GY.megabig = (function(parent, $) {
	
	var self = parent.megabig = parent.megabig || {};
	
	self.init = function(target, slides, options) {
		
		this.options = $.extend({
			animationDurationSlide: 200, // time, in milliseconds, it takes for slideshow animation to complete
			animationDuration: 1000, // time in milliseconds it takes for the animation to complete
			containerID: 'slides', // ID of container that holds slides
			groupsOf: 5, // how many items should slide at once
			loader: true, // create loader element?
			holderSelector: document.body, // selector of the place you want insert slides
			initialIndex: 0, // where to start
			loop: false 
		}, options || {});
		
		this.slides = slides || []; // expects an array of objects
		
		// shortcuts and instance variables
		this.groupsOf = this.options.groupsOf;
		this.holder = $(this.options.holderSelector);
		this.target = $(target);
		this.slideWindow = this.target.find('ul');
		this.triggers = this.target.find('li');
		this.build();
		
		$(window).bind('resize', function(e) {
			self.resize();
		});
		
		$(window).bind('load', function(e) {
			self.container.fadeTo(self.options.animationDuration, 1);
			self.resize();
		});
		
		this.triggers.bind('mouseenter', function(e) {
			e.preventDefault();
			self.swap($(this).index());
		});
		
		this.currentIndex = (this.inBounds(this.options.initialIndex, this.triggers.length)) ? this.options.initialIndex : 0;
		this.groupIndex = (this.currentIndex % this.groupsOf === 0) ? this.currentIndex : (Math.floor(this.currentIndex / this.groupsOf) * this.groupsOf);
		this.updateNav();
	};
	
	self.inBounds = function(n, l) {
		// check if index is a) numeric and b) within the bounds of the slideshow
		return (!isNaN(parseFloat(n)) && isFinite(n) && n >= 0 && n <= (l - 1));
	};
	
	self.build = function() {
		var loader = $('<div/>').attr('id', this.options.containerID + '-loader');
		this.overlay = $('<div/>').attr('id', this.options.containerID + '-overlay');
		this.container = $('<div/>').attr('id', this.options.containerID);
		this.holder.append(this.overlay)
					.append(this.container)
					.append(loader);
		
		for(var i = 0, l = this.slides.length; i < l; i++) {
			if(this.slides[i].src) {
				var img = $('<img/>').attr('src', this.slides[i].src).attr('data-trigger', i).css({'z-index': '1', 'opacity': 0});
				this.container.append(img);
				this.container.fadeTo(0, 0);
			}
		}
		this.imgs = this.container.children();
		this.imgs.eq(0).css({'z-index': '10', 'opacity': 1});
		
		// create nav
		this.previousBtn = $('<a/>', {
			'href': '#',
			'class': 'previous'
		});
		this.nextBtn = $('<a/>', {
			'href': '#',
			'class': 'next'
		});
		
		this.previousBtn.bind('click', function(e) {
			e.preventDefault();
			self.previous();
		});

		this.nextBtn.bind('click', function(e) {
			e.preventDefault();
			self.next();
		});
		
		var wrapper = this.target.children();
		wrapper.before(this.previousBtn).after(this.nextBtn);
		
	};
	
	self.swap = function(index) {
		if($('img[data-trigger=' + index + ']').length) {
			$('img[data-trigger]:not(img[data-trigger=' + index + '])').stop().fadeTo(200, 0, function() {
				//self.imgs.css({'z-index': '1'});
			});
			$('img[data-trigger=' + index + ']').stop().fadeTo(200, 1);//.css({'z-index': 10});
		}
	};
	
	self.resize = function() {
		
		var img = $('img', this.container);
		
		var ratio = (img.height()/img.width()).toFixed(2);	// Define size ratio
		// Gather browser size
		var browserWidth = $(window).width();
		var browserHeight = $(window).height();
		
		img.width(browserWidth);
		img.height(browserHeight);
	};
	
	/**
	 * Advance to the next slide / section
	 */
	self.next = function() {
		var next = this.groupIndex + this.groupsOf;
		if(next >= this.triggers.length) {
			if(this.options.loop) {
				next = 0;
			} else {
				next = this.groupIndex;
			}
		}
		this.slideTo(next);
	};
	
	/**
	 * Retreat to the previous slide / section
	 * @param index {number}
	 */
	self.previous = function() {
		var prev = this.groupIndex - this.groupsOf;
		if(prev < 0) {
			if(this.options.loop) {
				prev = (this.totalGroups - 1) * this.groupsOf;
			} else {
				prev = 0;
			}
		}
		this.slideTo(prev);
	};
	
	
	/**
	 * Slide
	 * @param index {number}
	 */
	self.slideTo = function(index) {
		
		var self = this;
		
		// are we within bounds?
		if(!this.inBounds(index)) {
			this.currentIndex = index;
		}
		this.groupIndex = index = parseInt(index, 10); // make sure index is a number
		// find element
		var el = this.triggers.eq(index);
		if(el.length === 0) {
			el = this.sections.eq(0);
		}
		// find offset
		var top = '-' + el[0].offsetTop + 'px';
		this.slideWindow.stop().animate({top: top}, this.options.animationDurationSlide, function(e) {
		});
		
		this.updateNav();
	};
	
	self.updateNav = function() {

		if(this.groupIndex > 0) {
			this.previousBtn.removeClass('disabled');
		} else {
			this.previousBtn.addClass('disabled');
		}

		if(this.groupIndex + this.groupsOf < this.triggers.length) {
			this.nextBtn.removeClass('disabled');
		} else {
			this.nextBtn.addClass('disabled');
		}
	};
	
	return self;
	
})(GY || {}, jQuery);
