﻿/*
 * Just Another Carousel v1.0
 * http://intrepidstudios.com/projects/jquery-just-another-carousel/
 *
 * Copyright (c) 2009 Kamran Ayub
 * Licensed under the GPL license.
 * http://intrepidstudios.com/projects/jquery-just-another-carousel/#license
 *
 * Last Modified: Feb 2, 2009
 * This file is part of Just Another Carousel.

    Just Another Carousel is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Just Another Carousel is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Just Another Carousel.  If not, see <http://www.gnu.org/licenses/>.
*/
(function($) {
	$.fn.jac = function (options) {          
    
		//
		// build main options before element iteration
		//
		var opts = $.extend({}, $.fn.jac.defaults, options);
		
		//
		// iterate and construct the carousel
		//
	  return this.each(function() {
    	
			// the viwport
			var $vp = $(this);
			var $vpw = Math.round($vp.width()); 
			var $c = $vp.children("ul:only-child");
			
			// Only support one carousel per viewport
			if($c.length > 1) return;
			
			// element specific options
			var settings = $.meta ? $.extend({}, opts, $vp.data()) : opts;
			// selectors
    	var sel = {
	        carouselSelector: "." + settings.carouselSelector,
	        childSelector: "." + settings.childSelector,
	        leftArrowSelector: "#" + settings.leftArrowSelector,
	        rightArrowSelector: "#" + settings.rightArrowSelector
	    };	 
		
			//
			// Setup CSS
			//
			
		  $vp
				.addClass("jac")
				.children("ul")
	      .addClass(settings.carouselSelector)
	      .children("li")
	      .addClass(settings.childSelector);
			// carousel wrapper
   		$c.wrapAll(
        $("<div class='carousel-wrapper'></div>")
        .css({
          "overflow":"hidden",
          "width" : $vpw,
          "height" : $vp.height(),
          "position" : "relative"
        })
    	);
			$c.css("width", getCarouselWidth() + "px");							                   						
			
      var children_length = [];
      
      $c.find(sel.childSelector).each(function (i) {
        children_length.push($(this).width());
      });
      
      var current_pos = 0;

      
      
			// Don't bother letting users move stuff if you can see everything, not needed BUZZWOO!
			//if(getCarouselWidth() <= $vpw) return;  
			
			// less processing to store a fixed width
	    var childWidth = $c.find(sel.childSelector + ":eq(0)").width();
	    var kidsPerView = Math.floor($vpw / childWidth); 		   		      
    
  		if(getCarouselWidth() > $vpw) { 
				// 
				// Moves content to center of mouse cursor (where it entered hover)
				//
			   
					// 
					// Handle navigation
					//                                                		
					
					$vp.append("<span id='"+settings.leftArrowSelector+"' class='"+settings.leftArrowClass+"'></span>");
			        $vp.append("<span id='"+settings.rightArrowSelector+"' class='"+settings.rightArrowClass+"'></span>");
			
			        // left arrow    
			        $vp.find(sel.leftArrowSelector)
			        .html("<a href='javascript:void(0)' title='"+settings.leftText+"'>"+settings.leftText+"</a>")
			        .css("opacity", 0.7)
			        .find("a")
			        .hover(function() {
												$(this).parent().fadeTo(settings.fadeSpeed,1); 
										 }, 
										 function(){ $(this).parent().fadeTo(settings.fadeSpeed,0.7); })                    
			        .click(function() {
			            var movePos, newPos;
			            newPos = getCarouselPos() + $vpw;
	            
			            if(checkReachedEdge("left")) {onMoveFinished(); return;}
                  
                  if(current_pos < 0) {
                    movePos = 0;
                    current_pos = 0;
                  } else {
                    var right_correction = 0;
                    if(checkReachedEdge("right")) {
                      rest_length = 0;
                      for(var i = current_pos; i < children_length.length; i++) {
                        rest_length += children_length[i];
                      }
                      right_correction = $vpw - rest_length;
                    }
                  
                    current_pos-=1;     
                    movePos = getCarouselPos() + (children_length[current_pos] - right_correction);
                  }
                  
                  //console.log('carpos:' + getCarouselPos() + ';cur:' + current_pos + ';pos:' + (getCarouselPos() + (children_length[current_pos] - right_correction)) + ';right_correction:'+right_correction);  
                    
                  
			            $c.stop();
			            $c.animate({
			                "left": movePos
			            }, settings.parentSlideSpeed, settings.easingStyle, onMoveFinished);
			        }); // left
	        
			        // right arrow
			        $vp.find(sel.rightArrowSelector)
			        .html("<a href='javascript:void(0)' title='"+settings.rightText+"'>"+settings.rightText+"</a>")
			        .css("opacity", 0.7)
			        .find("a")       
			        .hover(function() { $(this).parent().fadeTo(settings.fadeSpeed,1); }, function(){ $(this).parent().fadeTo(settings.fadeSpeed,0.7); })             
			        .click(function() {
			            var movePos, newPos;
			            newPos = -getCarouselPos() + children_length[current_pos];
                  
           			  movePos = children_length[current_pos];
                  //console.log('carpos:' + getCarouselPos() + ';cur:' + current_pos + ';pos:' + movePos + ';lg:'+children_length.length);
                  
                  current_pos+=1; 
	
			            if (newPos >= getCarouselWidth() - $vpw) {
                      movePos = (getCarouselWidth() - $vpw) + getCarouselPos();
			            }			
				
						      movePos = movePos - getCarouselPos();
				
			            $c.stop();
			            $c.animate({
			                "left": -movePos
			            }, settings.parentSlideSpeed, settings.easingStyle, onMoveFinished);                
			        }); // next
	
					// In case its decided that the carousel has a different
					// initial pos
					if(checkReachedEdge("left")) {
						$vp.find(sel.leftArrowSelector).hide();
					}
			
					if(checkReachedEdge("right")) {
						$vp.find(sel.rightArrowSelector).hide();
					}
        
		    } // navigation
		    
		    $('.pr_jac li > div').css('height','360px');
				
			// Get the carousel width
			function getCarouselWidth() {
				var w = 0;

				// Get carousel width
				if(settings.childFixedSize) {
					w = $c.find(sel.childSelector).length * childWidth;
				} else {

					$c.find(sel.childSelector).each(function() {
						w += $(this).width();
					});

				}
				return w;
			}
	
			// When animation finishes, checks to see if carousel reached edge,
			// and hides/shows arrows
			function onMoveFinished() {
		
				if(checkReachedEdge("left")) {
					$vp.find(sel.leftArrowSelector).hide("normal");
				} else {
					$vp.find(sel.leftArrowSelector).show("normal");
				}
		
				if(checkReachedEdge("right")) {
					$vp.find(sel.rightArrowSelector).hide("normal");
				} else {
					$vp.find(sel.rightArrowSelector).show("normal");
				}
			}
	
			// Checks to see if the carousel
			// has reached an edge
			function checkReachedEdge(side) {
				switch(side) {
					case "left":
						if(Math.round(getCarouselPos()) >= 0) return true;				
						break;
					case "right":
						var rightEdge = Math.round((getCarouselWidth() - $vpw) + getCarouselPos());

						if(rightEdge <= 0) return true;	
							
						break;			
				}
		
				return false;
			}			
	
			// For some reason, $'s position().left
			// is off by 1 pixel. So we get it from the CSS instead since that's
			// what we're manipulating.
			function getCarouselPos() {
				return getCssPos($c);
			}
    	
    	
    	
	    }); // return this.each
			
	}; // jac
	
	//
	// Returns a number for the CSS left position
	//
	function getCssPos(el) {
		var cssPos = $(el).css("left");

		return Math.round(parseInt(cssPos.replace("px","")));
	}
	
	//
	// plugin defaults
	//
	$.fn.jac.defaults = {
        carouselSelector: "carousel",
        childSelector: "jac-content",
        leftArrowSelector: "arrow-left",
        rightArrowSelector: "arrow-right",
        leftArrowClass: "arrow-left pngfix",
        rightArrowClass: "arrow-right pngfix",
        easingStyle: "swing",
   		rightText: "Next",
		leftText: "Previous",
   		childSizeFixed: false,
        childSlideSpeed: 300,        
        parentSlideSpeed: 600,
        fadeSpeed: 300,
        enableMouse: false
    }; // defaults
	
//
// end of closure
//
})(jQuery);