/**
 * General script for Oliveo
 * Also has the jQuery functions for the Homepage News Slider
 * 
 * @author Koos van Egmond | Cream Internetbureau
 */
 
// Set own function scope to avode naming conflictions and stuff
(function(win, doc, $, undef) {

	
	// Set variables for the slider
	var
	    // Start with the width of each slide
	    slideWidth = 390,
	
	    // Set the speed to slide width
	    slideAnimSpeed = 500,
	    
	    // Set the animation style
	    slideAnimStyle = 'easeOutQuint',
	    
	    // Set the default timeout between slides (miliseconds)
	    slideDefTimeout = 4000,
	
		// Place holder for current Slider object controllers
		sliders = {};
	
	// Start functioning the following code when DOM is ready
	$(function() {
		
		// Loop through all the sliders and bind correct controllers
		// and events
		$('.slider-container').each(function() {
			
			// Get the current context
			var contextId = $(this).closest('.smallcontent').attr('id'),
				context   = $('#'+contextId);
			
			// Skip and remove if no items present
			if (! $('ul li', this).length) {
				
				// Remove both the slider and bullets
				// and go to the next slider
				$('.slider-container, .slider-bullet-list', context).remove();
				return;
			}
			
			// Check if the sliders exists
			if (sliders && sliders[contextId] === undef) {
				
				// Store the new slider
				sliders[contextId] = Slider(context);
			} 
			
			// Get the stored slider
			var slider = sliders[contextId];
		
			// Open slide on clicking a slide bullet
			$('.slider-bullet-list a', context).click(function(e) {
				
				// Do nothing if already active
				if ($(this).parent().hasClass('active')) return;
				
				// Get the requested slide
				var requestedSlideId = $(this).attr('id').replace(/^for/, '');
				slider.open(requestedSlideId);
				
				e.preventDefault();
			});
			
			// Start the current slideshow in 5 seconds
			slider.setSlideshow(slideDefTimeout);
		});
	});
	
	
	/**
	 * Slider class
	 * @return Slider
	 */
	var Slider = function(/*jQuery*/ context) {
		
		return new Slider.fn.init(context);
	};
	Slider.fn = Slider.prototype = {
			
		/**
		 * Holds the jQuery object of the context where the slider
		 * resides in
		 * @var jQuery
		 */
		_context: null,
		
		/**
		 * Holds the jQuery object of the current slider
		 * @var jQuery
		 */
		_slider: null,
		
		/**
		 * Holds the jQuery object of the current bullet list
		 * @var jQuery
		 */
		_bulletList: null,
		
		/**
		 * Holds the handler for the timeout
		 * @var mixed
		 */
		_timeoutHandler: null,
		
		/**
		 * Set contructor same main function
		 * @see Slider
		 * @return void
		 */
		constructor: Slider,
		
		/**
		 * Initialization method which also sets the current slider
		 * @param jQuery context
		 * @return void
		 */
		init: function(/*jQuery*/ context) {
			
			this._context = context;
			return this;
		},
	
		/**
		 * Opens the slide in the slider by index in the given context
		 * @param String id
		 * @param Function cb
		 * @param Boolean noReset
		 * @return Slider
		 */
		open: function(/*String*/ id, /*Function*/ cb, /*bool*/ noReset) {
			
			// Reset the current slideShow
			if (!noReset) this.resetSlideshow();
			
			// Set default callback function
			var thisSlider = this;
			if (typeof cb != 'function') cb = function() {
				
				thisSlider.setSlideshow(slideDefTimeout);
			};
			
			// Count how many slides has to be moved by checking
			// the new index and set the new style
			var slideCount = this._getSlideIndexById(id),
			    newStyle   = {marginLeft: (0 - (slideCount * slideWidth))};
			
			// Set the new slide active
			this._setActive(id);
			
			// Animate to the new slide
			$('ul', this._getSlider()).stop().animate(newStyle, slideAnimSpeed, slideAnimStyle, cb);
			
			return this;
		},
		
		/**
		 * Start the slideshow in the slider after a timeout.
		 * First argument is the timeout used to ignite
		 * the slideshow.
		 * @param Integer timeout
		 * @param jQuery context
		 * @return Slider
		 */
		setSlideshow: function(/*int*/ timeout) {
			
			// Reset if set
			if (this._timeoutHandler !== undef) clearTimeout(this._timeoutHandler);
			
			// Set tmp placeholder of this and rerun the timeout
			var thisSlider = this;
			this._timeoutHandler = setTimeout(function() {
				
				// Open the next slide
				thisSlider._nextSlide(function() {
					
					// Rerun current function
					thisSlider.setSlideshow(slideDefTimeout);
				});
			}, timeout);
			
			return this;
		},
		
		/**
		 * Clears the timeout on the handler of the current slider
		 * @return Slider
		 */
		resetSlideshow: function() {
			
			// Clear the timeout of the current slideshow
			// if possible
			if (this._timeoutHandler !== undef && this._timeoutHandler) {
				
				clearTimeout(this._timeoutHandler);
			}
			
			return this;
		},
		
		/**
		 * Sets correct slide and bullet active by id
		 */
		_setActive: function(/*String*/ id) {
			
			// Reset current actives
			$('.active', this._context).removeClass('active');
			
			// Set current active bullet
			$('#for'+id, this._getBulletList()).parent().addClass('active');
			
			// Set current active slide
			$('#'+id, this._getSlider()).addClass('active');
		},
		
		/**
		 * Opens the following slide in the slider
		 * @return Slider
		 */
		_nextSlide: function(/*Function*/ cb) {
			
			// Get the current active slide's index
			var activeSlideId = this._getActiveSlide().attr('id'),
			    activeSlideIndex = this._getSlideIndexById(activeSlideId);
			
			// Calc the next index
			var nextIndex = activeSlideIndex + 1;
			if (nextIndex > this._getHighestIndex()) {
				nextIndex = 0;
			}
			
			// Get the nextIndex's object and id
			var nextObject   = this._getSlideByIndex(nextIndex),
			    nextObjectId = nextObject.attr('id');
			
			// Open the new slide
			return this.open(nextObjectId, cb, true);
		},
		
		/**
		 * Returns the index of the requested slider
		 * @param String id
		 * @return Integer
		 */
		_getSlideIndexById: function(/*String*/ id) {
			
			// Get the object
			var obj = $('#'+id, this._getSlider());
			
			// Return the index
			return $('ul li', this._getSlider()).index(obj);
		},
		
		/**
		 * Returns the jQuery object of the active slide
		 * @return jQuery
		 */
		_getActiveSlide: function() {
			
			return $('.active', this._getSlider());
		},
		
		/**
		 * Returns a slide's jQuery object by index
		 * @param Integer index
		 * @return jQuery
		 */
		_getSlideByIndex: function(/*int*/ index) {
			
			return $('ul li:eq('+index+')', this._getSlider());
		},
		
		/**
		 * Returns the highest possible index
		 * @return Integer
		 */
		_getHighestIndex: function() {
			
			// Return index by counting the number of items and
			// recucing that by one
			return ($('ul li', this._getSlider()).length - 1);
		},
		
		/**
		 * Returns the slider's jQuery object
		 * @return jQuery
		 */
		_getSlider: function() {
			
			// Define the slider if not yet defined
			if (!this._slider) {
				
				this._slider = $('.slider-container', this._context);
			}
			
			return this._slider;
		},
		
		/**
		 * Returns the slider's bullet list jQuery object
		 * @return jQuery
		 */
		_getBulletList: function() {
			
			// Define the bullet list if not yet defined
			if (!this._bulletList) {
				
				this._bulletList = $('.slider-bullet-list', this._context);
			}
			
			return this._bulletList;
		}
	};
	
	// Link init's prototype to the functional scope
	// Slider for correct defining
	Slider.fn.init.prototype = Slider.fn;

// Close the function scope called at line 8
})(window, window.document, jQuery);
