/*
* File: jquery.flexisel.js
* Version: 1.0.0
* Description: Responsive carousel jQuery plugin
* Author: 9bit Studios
* Copyright 2012, 9bit Studios
* http://www.9bitstudios.com
* Free to use and abuse under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/

(function ($) {

    $.fn.flexisel = function (options) {

        var defaults = $.extend({
    		visibleItems: 4,
    		animationSpeed: 200,
    		autoPlay: false,
    		autoPlaySpeed: 3000,    		
    		pauseOnHover: true,
			setMaxWidthAndHeight: false,
    		enableResponsiveBreakpoints: false,
    		responsiveBreakpoints: { 
	    		portrait: { 
	    			changePoint:480,
	    			visibleItems: 1
	    		}, 
	    		landscape: { 
	    			changePoint:640,
	    			visibleItems: 2
	    		},
	    		tablet: { 
	    			changePoint:768,
	    			visibleItems: 3
	    		}
        	}
        }, options);
        
		/******************************
		Private Variables
		*******************************/         
        
        var object = $(this);
		var settings = $.extend(defaults, options);        
		var itemsWidth; // Declare the global width of each item in carousel
		var canNavigate = true; 
        var itemsVisible = settings.visibleItems; 
        
		/******************************
		Public Methods
		*******************************/        
        
        var methods = {
        		
			init: function() {
				
        		return this.each(function () {
        			methods.appendHTML();
        			methods.setEventHandlers();      			
        			methods.initializeItems();
				});
			},

			/******************************
			Initialize Items
			*******************************/			
			
			initializeItems: function() {
				
				var listParent = object.parent();
				var innerHeight = listParent.height(); 
				var childSet = object.children();
				
    			var innerWidth = listParent.width(); // Set widths
    			itemsWidth = (innerWidth)/itemsVisible;
    			childSet.width(itemsWidth);
    			childSet.last().insertBefore(childSet.first());
    			childSet.last().insertBefore(childSet.first());
    			object.css({'left' : -itemsWidth}); 

    			object.fadeIn();
				$(window).trigger("resize"); // needed to position arrows correctly

			},
			
			
			/******************************
			Append HTML
			*******************************/			
			
			appendHTML: function() {
				
   			 	object.addClass("nbs-flexisel-ul");
   			 	object.wrap("<div class='nbs-flexisel-container'><div class='nbs-flexisel-inner'></div></div>");
   			 	object.find("li").addClass("nbs-flexisel-item");
 
   			 	if(settings.setMaxWidthAndHeight) {
	   			 	var baseWidth = $(".nbs-flexisel-item > img").width();
	   			 	var baseHeight = $(".nbs-flexisel-item > img").height();
	   			 	$(".nbs-flexisel-item > img").css("max-width", baseWidth);
	   			 	$(".nbs-flexisel-item > img").css("max-height", baseHeight);
   			 	}
 
   			 	$("<div class='nbs-flexisel-nav-left'></div><div class='nbs-flexisel-nav-right'></div>").insertAfter(object);
   			 	var cloneContent = object.children().clone();
   			 	object.append(cloneContent);
			},
					
			
			/******************************
			Set Event Handlers
			*******************************/
			setEventHandlers: function() {
				
				var listParent = object.parent();
				var childSet = object.children();
				var leftArrow = listParent.find($(".nbs-flexisel-nav-left"));
				var rightArrow = listParent.find($(".nbs-flexisel-nav-right"));
				
				$(window).on("resize", function(event){
					
					methods.setResponsiveEvents();
					
					var innerWidth = $(listParent).width();
					var innerHeight = $(listParent).height(); 
					
					itemsWidth = (innerWidth)/itemsVisible;
					
					childSet.width(itemsWidth);
					object.css({'left' : -itemsWidth});
					
					var halfArrowHeight = (leftArrow.height())/2;
					var arrowMargin = (innerHeight/2) - halfArrowHeight;
					leftArrow.css("top", arrowMargin + "px");
					rightArrow.css("top", arrowMargin + "px");
					
				});					
				
				$(leftArrow).on("click", function (event) {
					methods.scrollLeft();
				});
				
				$(rightArrow).on("click", function (event) {
					methods.scrollRight();
				});
				
				if(settings.pauseOnHover == true) {
					$(".nbs-flexisel-item").on({
						mouseenter: function () {
							canNavigate = false;
						}, 
						mouseleave: function () {
							canNavigate = true;
						}
					 });
				}

				if(settings.autoPlay == true) {
					
					setInterval(function () {
						if(canNavigate == true)
							methods.scrollRight();
					}, settings.autoPlaySpeed);
				}
				
			},
			
			/******************************
			Set Responsive Events
			*******************************/			
			
			setResponsiveEvents: function() {
				var contentWidth = $('html').width();
				
				if(settings.enableResponsiveBreakpoints == true) {
					if(contentWidth < settings.responsiveBreakpoints.portrait.changePoint) {
						itemsVisible = settings.responsiveBreakpoints.portrait.visibleItems;
					}
					else if(contentWidth > settings.responsiveBreakpoints.portrait.changePoint && contentWidth < settings.responsiveBreakpoints.landscape.changePoint) {
						itemsVisible = settings.responsiveBreakpoints.landscape.visibleItems;
					}
					else if(contentWidth > settings.responsiveBreakpoints.landscape.changePoint && contentWidth < settings.responsiveBreakpoints.tablet.changePoint) {
						itemsVisible = settings.responsiveBreakpoints.tablet.visibleItems;
					}
					else {
						itemsVisible = settings.visibleItems;
					}
				}
			},			
			
			/******************************
			Scroll Left
			*******************************/				
			
			scrollLeft:function() {

				if(canNavigate == true) {
					canNavigate = false;
					
					var listParent = object.parent();
					var innerWidth = listParent.width();
					
					itemsWidth = (innerWidth)/itemsVisible;
					
					var childSet = object.children();
					
					object.animate({
							'left' : "+=" + itemsWidth
						},
						{
							queue:false, 
							duration:settings.animationSpeed,
							easing: "linear",
							complete: function() {  
								childSet.last().insertBefore(childSet.first()); // Get the first list item and put it after the last list item (that's how the infinite effects is made)   								
								methods.adjustScroll();
								canNavigate = true; 
							}
						}
					);
				}
			},
			
			/******************************
			Scroll Right
			*******************************/				
			
			scrollRight:function() {
				
				if(canNavigate == true) {
					canNavigate = false;
					
					var listParent = object.parent();
					var innerWidth = listParent.width();
					
					itemsWidth = (innerWidth)/itemsVisible;
					
					var childSet = object.children();
					
					object.animate({
							'left' : "-=" + itemsWidth
						},
						{
							queue:false, 
							duration:settings.animationSpeed,
							easing: "linear",
							complete: function() {  
								childSet.first().insertAfter(childSet.last()); // Get the first list item and put it after the last list item (that's how the infinite effects is made)   
								methods.adjustScroll();
								canNavigate = true; 
							}
						}
					);
				}
			},
			
			/******************************
			Adjust Scroll 
			*******************************/
			
			adjustScroll: function() {
				
				var listParent = object.parent();
				var childSet = object.children();				
				
				var innerWidth = listParent.width(); 
				itemsWidth = (innerWidth)/itemsVisible;
				childSet.width(itemsWidth);
				object.css({'left' : -itemsWidth});		
			}			
        
        };
        
        if (methods[options]) { 	// $("#element").pluginName('methodName', 'arg1', 'arg2');
            return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof options === 'object' || !options) { 	// $("#element").pluginName({ option: 1, option:2 });
            return methods.init.apply(this);  
        } else {
            $.error( 'Method "' +  method + '" does not exist in flexisel plugin!');
        }        
};

})(jQuery);
