﻿/* Caution ! 
    This is NOT the original version.
    This file was modified by sanjus & yvevan
*/

/*
 * 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 $vpw = Math.round($vp[0].offsetWidth); 
            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");
            
            // Don't bother letting users move stuff if you can see everything
            if(getCarouselWidth() <= $vpw) return;  
            
            // less processing to store a fixed width
            // var childWidth = $c.find(sel.childSelector + ":eq(0)").width();
            var childWidth = $c.find(sel.childSelector + ":eq(0)")[0].offsetWidth;
            var kidsPerView = Math.floor($vpw / childWidth);                          
    
            // 
            // Moves content to center of mouse cursor (where it entered hover)
            //
            $c
            .find(sel.childSelector)    
            .hover(
                function(e) {            
                    if(!settings.enableMouse) return;            
            
                    // my abs pos to carousel
                    var myAbs;

                    if(settings.childSizeFixed) {
                        myAbs = $c.children().index(this) * childWidth;
                    } else {
                        myAbs = Math.round($(this).position().left);
                    }

                    // my rel pos to viewport
                    var myRel = myAbs + getCarouselPos();
            
                    // my abs pos to carousel - centered
                    // var myAbsC = myAbs + Math.round($(this).width() / 2);
                    var myAbsC = myAbs + Math.round($(this)[0].offsetWidth / 2);

                    // mouse rel to viewport
                    var mouseRelV = Math.round(e.pageX) - $vp.offset().left;

                    // mouse rel to my center
                    var mouseRelC = mouseRelV - myAbsC;

                    // new position to move to
                    var newPos = myAbsC - mouseRelV;
            
                    // new rel position, left
                    var newRelPosL = myAbs - newPos;
                    // var newRelPosR = $(this).width() + myAbs - newPos;
                    var newRelPosR = $(this)[0].offsetWidth + myAbs - newPos;
            
                    // compensate for $'s -1 off
                    if(!settings.childFixedSize) newRelPosR += 1;
            
                    // Keep from going outside the viewport
                    if (newRelPosL <= 0) newPos = newPos + newRelPosL;
                    if (newRelPosR >= $vpw) newPos = newPos + (newRelPosR - $vpw);
            
                    // Stop all animations (smoothly)
                    $c.stop().animate({
                        "left": -newPos
                    }, settings.childSlideSpeed, settings.easingStyle, onMoveFinished);
                },
                function(e) {            
                    if(!settings.enableMouse) return;
            
                    $c.stop();
                });            
    
            // 
            // Handle navigation
            //
            if(getCarouselWidth() > $vpw) {                                                        
                
                $vp.append("<span class='"+settings.leftArrowSelector+"'></span>");
                $vp.append("<span class='"+settings.rightArrowSelector+"'></span>");
        
                // left arrow    
                $vp.find(sel.leftArrowSelector)
                .html('<a href="javascript:void(0)">'+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(!settings.enableMouse && settings.childSizeFixed) {
                        // move so we show equal amounts of kids at once
                        // if the mouse is enabled, this wouldn't make sense
                        movePos = kidsPerView * childWidth;
                    } else {
                        // children are variable, so move viewport width
                        movePos = $vpw;
                    }                    
                
                    if (newPos > 0) {                
                        movePos = -getCarouselPos();
                    }

                    movePos = movePos + getCarouselPos();

                    $c.stop();
                    $c.animate({
                        "left": movePos
                    }, settings.parentSlideSpeed, settings.easingStyle, onMoveFinished);
                }); // left
        
                // right arrow
                $vp.find(sel.rightArrowSelector)
                .html('<a href="javascript:void(0)">'+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() + $vpw;

                    if(!settings.enableMouse && settings.childSizeFixed) {
                        movePos = kidsPerView * childWidth;
                    } else {
                        movePos = $vpw;
                    }

            
                    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
        
            // 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)[0].offsetWidth;
                    });

                }
                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).addClass('arrow-previous-disabled');
                } else {
                    $vp.find(sel.leftArrowSelector).removeClass('arrow-previous-disabled');
                }
        
                if(checkReachedEdge("right")) {
                    $vp.find(sel.rightArrowSelector).addClass('arrow-next-disabled');
                } else {
                    $vp.find(sel.rightArrowSelector).removeClass('arrow-next-disabled');
                }
            }
    
            // 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",
        easingStyle: "swing",
           rightText: "Next",
        leftText: "Previous",
           childSizeFixed: true,
        childSlideSpeed: 300,        
        parentSlideSpeed: 600,
        fadeSpeed: 300,
        enableMouse: false
    }; // defaults
    
//
// end of closure
//
})(jQuery);
