/*! jquery.Carousel360.js */
/* 
* Carousel360 jQuery Plugin
* by Paul Vlasenko (c)2009
* 
* Version: 0.5.5[beta] - 02/03/2009
* Known Issues/TODO:
* - (Pri:1) not fully independent when multiple intances per page 
* - (Pri:2) support for theme switching
* - (Pri:3) easing plugin tests needed 
* - (Pri:3) expects all slides to be fixed width
* - (Pri:3) add/improve debugging function(s)
*/

//
// create closure
//
(function($) {
    //
    // plugin definition
    //
    $.fn.Carousel360 = function($$options) {
        //; ; ; _debug(this); 

        //
        // plugin defaults
        //
        var defaults = {
            speed: 800, 				// ms, smaller number = faster speed
            easing: "swing", 	// swing|linear|(or use easing plugin w/ its options)
            autoAdvance: false, // true|false
            autoAdvancePause: 5000, // autoadvance pause ms.
            navType: 'none', // none|basic|precise|full
            slidesVisible: 1, 					// number of slides per animation	(dynamically determined based on mask width)

            ////// #### don't modify bellow... the rest are tracking vars #### //////
            curIx: 0,
            adSlides: null,
            activeSlide: null,
            slideBuffer: null,
            preciseNav: null,
            basicNav: null,
            isBothSlider: false
        };

        // build main options before element iteration
        var $settings = $.extend({}, defaults, $$options);

        // iterate and reformat each matched element
        return this.each(function() {
            $this = $(this);
            // build element specific options
            var o = $.meta ? $.extend({}, $settings, $this.data()) : $settings;

            //
            // define and expose our init function
            //
            init = function(el, o) {

                adSlides = el.find('ul > li'); 									// inialize slideshow objects
                activeSlide = el.find('ul > li:first');
                slideBuffer = el.find('ul > li:first');

                // for now asume slides have a fixed width
                slidesVisible = Math.round($(el).innerWidth() / $(el).find('ul.c360 > li').eq(0).outerWidth());
                slidesVisible = (slidesVisible < 1) ? 1 : slidesVisible;
                // hide navigation if all slides fit in the mask
                if (adSlides.length <= slidesVisible) {
                    o.navType = 'none';
                }

                if (o.navType == 'precise' || o.navType == 'full') {
                    preciseNav = $('<div class="c360_nav-precise"></div>');

                    adSlides.each(function(i) {														// dynamically create slideshow navigation
                        //var link = $('<a href="#" onclick="carouselGetSlide('+ i +',\''+ el.id +'\'); return false;">'+ (i+1) +'</a>');
                        var link = $('<a href="#" title="' + (i + 1) + '">&nbsp;</a>');
                        link.click(function(event) { event.preventDefault(); getSlide(el, i); });
                        preciseNav.append(link);
                    });
                    preciseNav.find('a:first').addClass('active'); 	// assign active state
                    preciseNav.insertAfter(el);
                }
                if (o.navType == 'basic' || o.navType == 'full') {
                    basicNav = $('<div class="c360_nav-basic"></div>');
                    var prevLink = $('<a href="#" class="c360_prevBtn">Previous</a>');
                    prevLink.click(function(event) { event.preventDefault(); prevSlide(el); });
                    basicNav.append(prevLink);
                    var nextLink = $('<a href="#" class="c360_nextBtn">Next</a>');
                    nextLink.click(function(event) { event.preventDefault(); nextSlide(el); });
                    basicNav.append(nextLink);

                    basicNav.insertAfter(el);
                }

                if (o.autoAdvance === true) {
                    setTimeout(function() { autoPlay(el); }, o.autoAdvancePause);
                }

            };

            //
            // define and expose our getSlide function
            //
            getSlide = function(el, ix, dir) {
                if (!dir) {
                    dir = (ix < o.curIx) ? '<' : '>'; 										// determine animation direction
                    // if dir=null and autoAdvance=true, then this is a manual click, delay next autoAdvance          
                    if (o.autoAdvance) {
                        if (apTime) {
                            clearTimeout(apTime);
                        }
                        apTime = setTimeout(function() {
                            if (apTime) {
                                clearTimeout(apTime);
                                autoPlay(el);
                            }
                        }, o.autoAdvancePause * 2);
                    }
                }

                slideBuffer = el.find('ul.c360 > li').eq(ix); 				// get next slide to be loaded
                // cr 54971
                try {
                       CoreMetrics.ManualImpressionTagFrmLinkAttribute(slideBuffer);
                }
                catch (e) {
                }

                animate(el, dir);
                if (o.navType == 'precise' || o.navType == 'full') {
                    preciseNav.find('a').removeClass('active'); 			// remove active state
                    preciseNav.find('a').eq(ix).addClass('active'); 	// assign active state
                }
                o.curIx = ix;
                // re-assign active slide index
            }

            //
            // define and expose our nextSlide function
            //
            nextSlide = function(el) {
                o.curIx++;
                if ((o.curIx + slidesVisible) >= adSlides.length) {
                    adSlides.clone().appendTo(el.find('ul.c360')); 		// clone + add temp slide set									
                }
                getSlide(el, o.curIx, '>'); 												// load slide
        if (o.isBothSlider) {
            $("div.c360_nav-basic").addClass("billingfull");
            if ((o.curIx + 1 + slidesVisible) >= adSlides.length) {
                $("a.c360_nextBtn").hide();
            }        
        }
            }

            //
            // define and expose our prevSlide function
            //
            prevSlide = function(el) {
                o.curIx--;
                if (o.curIx < 0) {
                    el.find('ul.c360').prepend(adSlides.clone()); 	// clone + add temp slide set
                    el.find('ul.c360').css('left', -activeSlide.position().left + 'px'); 	// shift position
                    getSlide(el, adSlides.length - 1, '<'); 					// load slide with reset index				
                } else {
                    getSlide(el, o.curIx, '<'); 											// load slide normally
        if (o.isBothSlider) {
            if (o.curIx - 1 < 0) {
                $("div.c360_nav-basic").removeClass("billingfull");
            }
            $("a.c360_nextBtn").show();
        }
                }
            }

            var apTime = null;
            autoPlay = function(el) {
                apTime = setTimeout(function() {
                    nextSlide(el);
                    if (apTime) {
                        clearTimeout(apTime);
                        autoPlay(el);
                    }
                }, o.autoAdvancePause);
            }

            //
            // define and expose our animate function
            //
            animate = function(el, dir) {
                posPX = slideBuffer.position().left * (-1); 						// get destination px

                el.find('ul.c360').stop().animate(
					{ 'left': posPX + "px" },
					 o.speed, o.easing,
					 function() { 																				// after animation is finished...					
					     if (dir == '>') {																		// if moving forward... 
					         if (o.curIx >= adSlides.length)										// if at the end of the show...
					         {																								//	dump temp slide set (cloned earlier)
					             el.find('ul.c360 > li:lt(' + (adSlides.length) + ')').remove();
					             el.find('ul.c360').css('left', '0px'); 				// shift position
					             o.curIx = 0; 																		// reset index
					             if (o.navType == 'precise' || o.navType == 'full') {
					                 preciseNav.find('a').removeClass('active'); 					// remove active state (TODO: refactor to change state in one place?)
					                 preciseNav.find('a').eq(o.curIx).addClass('active'); 	// assign active state (TODO: refactor to change state in one place?)								
					             }
					         }
					     }
					     else if (dir == '<')																	// if moving backwards...
					     {																									// if past the beginning of the show...
					         if (o.curIx >= adSlides.length + slidesVisible) {																								//	dump temp slide set (cloned earlier)
					             el.find('ul.c360 > li:gt(' + (adSlides.length - 1) + ')').remove();
					         }
					     }

					     activeSlide = slideBuffer; 											// assign temp slide as active
					 }
				);
            }


            // run it
            init($this, o);

        });
    };

    //
    // private function for debugging
    //
    function _debug($obj) {
        if (window.console && window.console.log)
            window.console.log('Carousel360 selection count: ' + $obj.size());
    };


    //
    // end of closure
    //
})(jQuery);


