/*jslint strict: true, browser: true, plusplus: true, devel: true, jquery: true, bitwise: true, maxerr: 50 */
/*global vQuery: true */
(function( global, jQuery ){
	"use strict";

	var vlbGlobals = {
		insts: {}
	};

	global.vlb = function( element ){
		element = jQuery( element );
		var groupName = element.attr( 'data-vlb-group' ) || undefined;
		var parentNode = element.attr( 'data-vlb-parent' ) || document;

		if ( groupName === undefined ) {
			return false;
		}

		var inst = null;

		var instName;
		for( instName in vlbGlobals.insts ) {
			if ( vlbGlobals.insts.hasOwnProperty( instName ) ) {
				if ( vlbGlobals.insts[ instName ].groupName === groupName && vlbGlobals.insts[ instName ].parentNode === parentNode ) {
					inst = vlbGlobals.insts[ instName ];
					break;
				}
			}
		}

		if ( inst === null ) {
			inst = new vlbInst( element );
			vlbGlobals.insts[ inst.name ] = inst;
		}

		inst.expand();

		return inst;
	};

	global.vlbGet = function( name ) {
		if ( name in vlbGlobals.insts ) {
			return vlbGlobals.insts[ name ];
		}
	};

	global.vlbFind = function( element ) {
		var parent = jQuery( element ).parents( 'data-vlb-id' );
		
		if ( parent.length === 0 ) {
			return false;
		}
		
		var name = parent.attr( 'data-vlb-id' );
		
		if ( name in vlbGlobals.insts ) {
			return vlbGlobals.insts[ name ];
		}
	};

	var vlbInst = function( element ){
		this.init( element );
		this.container_init();
		return this;
	};

	vlbInst.prototype = {
		name: undefined,
		container: undefined,
		containerWrapper: undefined,
		items: [],
		itemsInfo: [],
		index: 0,
		destroyTimeout: 250,

		init: function( element ){
			this.name = Math.random().toString( 36 ).substr( 2, 9 );
			this.element = jQuery( element );
			this.groupName = this.element.attr( 'data-vlb-group' ) || undefined;
			this.parentNode = this.element.attr( 'data-vlb-parent' ) || document;

			var self = this;

			var items = [];
			var itemsInfo = [];

			jQuery( '[data-vlb-group="' + this.groupName + '"]', this.parentNode ).each(function(){
				var link = jQuery( this );
				var linkHref = link.attr( 'href' );
				var linkTitle = link.attr( 'title' );

				if ( !linkHref ) {
					return;
				}

				for( var i = 0; i < itemsInfo.length; i++ ) {
					if( itemsInfo[i].src == linkHref ) {
						return;
					}
				}

				var item = jQuery( '<img />' ).attr( 'src', linkHref );

				if ( linkTitle ) {
					item.attr( 'title', linkTitle );
				}

				if ( self.element.attr( 'href') !== linkHref ) {
					item.css({ display: 'none' });
				}

				itemsInfo.push({
					'src': linkHref,
					'title': linkTitle
				});

				items.push( item );
			});

			this.items = items;
			this.itemsInfo = itemsInfo;
		},

		expand: function( element ){
			this.container
				.find( '.vlb-container-items' )
				.html( this.items );

			this.refresh();

			var self = this;

			setTimeout(function(){
				self.containerWrapper.removeClass( 'vlb-container-hidden' );
			}, 10 );

			jQuery( window ).off( 'resize.vlb' ).on( 'resize.vlb', function(){
				self.close();
			} );

			jQuery( window ).off( 'keydown.vlb' ).on( 'keydown.vlb', function( event ){
				switch( event.keyCode ) {
					case 13:// enter
					case 27:// esc
						self.close();
						event.preventDefault();
						break;

					case 32:// space
					case 37:// arrow left
					case 40:// arrow done
						self.next();
						event.preventDefault();
						break;

					case 39:// arrow right
					case 38:// arrow up
						self.prev();
						event.preventDefault();
						break;
				}
			} );
		},

		container_init: function(){
			this.containerWrapper = jQuery( '[data-vlb-id="' + this.name + '"]' );

			if ( this.containerWrapper.length === 0 ) {
				this.containerWrapper = jQuery( '<div />' )
					.attr( 'data-vlb-id', this.name )
					.addClass( 'vlb-container-wrapper vlb-container-hidden' )
					.attr( 'onclick', 'vlbGet(\'' + this.name + '\').close();return false' )
					.html( '' +
					'<div class="vlb-container-holder">' +
					'<div class="vlb-container">' +
					'<div class="vlb-container-content">' +
					'<div class="vlb-container-items"/>' +
						'<div class="vlb-container-info">' +
							'<div class="vlb-container-info-title" />' +
							'<div class="vlb-container-info-position" />' +
						'</div>' +
						'<div class="vlb-container-close" onclick="vlbGet(\'' + this.name + '\').close();return false"/>' +
						'</div>' +
					'</div>' +
					'</div>' +
					'' )
					.prependTo( 'body' );
			}

			this.container = this.containerWrapper.find( '.vlb-container-content' );
			this.containerItems = this.container.find( '.vlb-container-items' );
			this.containerPosition = this.container.find( '.vlb-container-info-position' );
			this.containerTitle = this.container.find( '.vlb-container-info-title' );

			if ( this.items.length > 1 ) {
				var self = this;

				this.container.append(
					jQuery( '<div class="vlb-navigate-left"/>' )
						.on( 'click', function( event ){
							self.prev();
							event.stopPropagation();
						})
				);
				this.container.append(
					jQuery( '<div class="vlb-navigate-right"/>' )
						.on( 'click', function( event ){
							self.next();
							event.stopPropagation();
						})
				);
			}
		},

		next: function(){
			this.containerItems
				.children( ':eq(' + this.index + ')' )
				.css({ display: 'none' })
				.next()
				.removeAttr( 'style');

			if ( this.containerItems.children(':not([style])' ).length === 0 ) {
				this.containerItems
					.children( ':eq(0)' )
					.removeAttr( 'style');
			}

			this.refresh();
		},

		prev: function(){
			this.containerItems
				.children( ':eq(' + this.index + ')' )
				.css({ display: 'none' })
				.prev()
				.removeAttr( 'style');

			if ( this.containerItems.children( ':not([style])' ).length === 0 ) {
				this.containerItems
					.children( ':eq(-1)' )
					.removeAttr( 'style');
			}

			this.refresh();
		},

		refresh: function(){
			var currentChild = this.containerItems.children( ':not([style])' );

			this.index = this.containerItems.children().index( currentChild );
			this.refreshTitle();
			this.refreshPosition();
		},

		refreshTitle: function(){
			var title = this.itemsInfo[ this.index ].title || '';

			this.containerTitle.html( title );

			if ( title.length === 0 ) {
				this.containerTitle.css({ display: 'none' });
			}
			else {
				this.containerTitle.removeAttr( 'style' );
			}
		},

		refreshPosition: function(){
			this.containerPosition.html( ( this.index + 1 ) + '/' + this.items.length );
		},

		close: function(){
			this.containerWrapper.addClass( 'vlb-container-hidden' );

			var self = this;

			jQuery( window ).off( 'resize.vlb' );
			jQuery( window ).off( 'keydown.vlb' );

			setTimeout( function(){
				self.containerWrapper.remove();
				delete vlbGlobals.insts[ self.name ];
			}, this.destroyTimeout );
		}
	};

	global.vlbGlobals = vlbGlobals;
	global.vlbStart = function( element ){
		var inst = new global.vlb();
		inst.expand( element );
		return inst;
	};

}( window, typeof vQuery !== 'undefined' ? vQuery : jQuery ));
