/**
 * Gallery.js - A simple gallery with thumbnails
 * 
 * @author Webstores <info at webstores dot nl>
 *         Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
function Gallery(el, options) {
	this.el = $(el);
	this.options = options;
	this.index = 0;
	this.totalImages = 0;
	this.images = [];
	this.overlay = null;
	this.construct();
};

Gallery.prototype = {
	/**
	 * @constructor
	 */
	construct: function() {
		if(this.el.length) {
			this.options = $.extend({
				imageWrapperSelector: '.gallery-image-wrapper',
				imageSelector: '.gallery-image',
				thumbsSelector: '.gallery-thumbs',
				thumbSelector: '.thumb',
				controlsSelector: '.gallery-controls',
				galleryJsClass: 'js-gallery',
				scrollerClass: 'gallery-scroller',
				itemActiveClass: 'selected',
				controlClass: 'gallery-control',
				controlPrevClass: 'prev',
				controlNextClass: 'next',
				onReady: null,
				onBeforeItemChange: null,
				onAfterItemChange: null
			}, this.options || {});
			
			this.el.addClass(this.options.galleryJsClass);
			this.setActiveItem(0);
			
			this.addEventHandlers();
			this.createThumbScroller();
			this.createControls();
			this.appendOverlay();
			
			if(typeof this.options.onReady === 'function') {
				this.options.onReady();
			}
		}
	},
	
	/**
	 * Add event handlers
	 */
	addEventHandlers: function() {
		var self = this;
		
		$(this.options.thumbSelector, this.el).click(function(e) {
			e.preventDefault();
			self.thumbClickHandler(this);
		});
	},
	
	/**
	 * When a thumb link fires onclick
	 * 
	 * @param {Object} el The HTMLAnchorElement (thumb)
	 */
	thumbClickHandler: function(el) {
		this.index = $(this.options.thumbSelector, this.el).index(el);
		
		if(typeof this.options.onBeforeItemChange === 'function') {
			this.options.onBeforeItemChange(el, this.index);
		}
		
		if(typeof this.images[this.index] === 'undefined') {
			this.images[this.index] = this.loadImage(el.href);
		}
		else {
			this.setImage(this.images[this.index].attr('src'));
		}
		
		this.setActiveItem(this.index);
		
		if(typeof this.options.onAfterItemChange === 'function') {
			this.options.onAfterItemChange(el, this.index);
		}
	},
	
	/**
	 * Creates the needed DOM elements and sets the right properties
	 */
	createThumbScroller: function() {
		var self = this;
		var totalWidth = 0;

		$(this.options.thumbsSelector).children().each(function() {
			totalWidth += $(this).outerWidth(true);
			self.totalImages++;
		});
		
		$(this.options.thumbsSelector).css({
			position: 'relative',
			width: totalWidth
		});
		
		var galleryScroller = $('<div>', {
			'class': this.options.scrollerClass
		}).css({
			position: 'relative',
			overflow: 'hidden'
		});
		
		$(this.options.thumbsSelector).wrap(galleryScroller);
	},
	
	/**
	 * Creates the previous and next controls
	 */
	createControls: function() {
		var self = this;
		
		var prevControl = $('<span>', {
			'class': this.options.controlClass + ' ' + this.options.controlPrevClass
		}).attr('unselectable', 'on').css('-moz-user-select', 'none').bind('selectstart', function() {
			return false;
		}).click(function() {
			self.prev();
		});
		
		var nextControl = $('<span>', {
			'class': this.options.controlClass + ' ' + this.options.controlNextClass
		}).attr('unselectable', 'on').css('-moz-user-select', 'none').bind('selectstart', function() {
			return false;
		}).click(function() {
			self.next();
		});
		
		/*@cc_on
		prevControl.dblclick(function() {
			self.prev();
		});
		
		nextControl.dblclick(function() {
			self.next();
		});
		@*/
		
		$(this.options.controlsSelector).append(prevControl).append(nextControl);
	},
	
	/**
	 * Create, hide and append the loading overlay to the gallery image wrapper
	 */
	appendOverlay: function() {
		this.overlay = $('<div class="overlay">').hide();
		$(this.options.imageWrapperSelector, this.el).append(this.overlay);
	},
	
	/**
	 * Load an image and add it to the images cache
	 * 
	 * @param {String} src The image's relative path
	 */
	loadImage: function(src) {
		this.overlay.show();
		
		var self = this;
		var img = $('<img>');
		
		img.load(function() {
			self.setImage(this.src);
			self.overlay.hide();
		});
		
		img.attr('src', src);
		
		return img;
	},
	
	/**
	 * When the prev button fires onclick
	 */
	prev: function() {
		if(this.index > 0) {
			var el = $(this.options.thumbSelector + ':eq(' + (this.index - 1) + ')', this.el).get(0);
			this.thumbClickHandler(el);
		}
	},
	
	/**
	 * When the next button fires onclick
	 */
	next: function() {
		if(this.index + 1 < this.totalImages) {
			var el = $(this.options.thumbSelector + ':eq(' + (this.index + 1) + ')', this.el).get(0);
			this.thumbClickHandler(el);
		}
	},
	
	/**
	 * Set the gallery image's source
	 * 
	 * @param {String} src The image's relative path
	 */
	setImage: function(src) {
		$(this.options.imageSelector, this.el).attr('src', src);
	},
	
	/**
	 * Sets the active thumb, deactivating the previous
	 * 
	 * @param {Number} index The index of the item to set active
	 */
	setActiveItem: function(index) {
		$(this.options.thumbsSelector + ' .' + this.options.itemActiveClass, this.el).removeClass(this.options.itemActiveClass);
		$(this.options.thumbsSelector, this.el).children(':eq(' + index + ')').addClass(this.options.itemActiveClass);
		this.setCenter(index);
	},
	
	/**
	 * Center the item at a given index
	 * 
	 * @param {Number} index The index of the item to set active
	 */
	setCenter: function(index) {
		var left = $(this.options.thumbSelector, this.el).children(':eq(' + index + ')').position().left;
		left -= ($('.' + this.options.scrollerClass, this.el).width() - $(this.options.thumbSelector + ':eq(' + index + ')', this.el).width()) / 2;
		
		$('.' + this.options.scrollerClass).animate({
			scrollLeft: left + 'px'
		}, 'fast');
	}
};

