﻿/*
 * markup example for new lib.shared.components.carousel({ selectors : [
 *                                                   { carouselSelector: 'div#CarouselContainer' },
 *                                                   { carouselWrapper: 'div.CarouselWrapper' },
 *                                                   { carouselGroup: 'div.CarouselGroup'}],
 *                                                autoStart : 2000
 *           });
 *
 * <div id="CarouselContainer">
 * <div class="CarouselWrapper">
 *  <div class="CarouselGroup">
 *   <div><img src="01.jpg" alt="" /></div>
 *   <div><img src="02.jpg" alt="" /></div>
 *   <div><img src="03.jpg" alt="" /></div>
 *  </div>
 *  <div class="CarouselGroup">
 *   <div><img src="01.jpg" alt="" /></div>
 *   <div><img src="02.jpg" alt="" /></div>
 *   <div><img src="03.jpg" alt="" /></div>
 * </div>
* </div>
* </div> 
*
*/ 
registerNS('lib.shared.components');

(function ($) {
	var ns = lib.shared.components;

    var defaultSettings = {
        selectors : [{ "carouselContainer": null, required : true}, {"carouselWrapper" : null, required : true }, {"carouselGroup" : null, requird : true}],
        autoStart : 0,
        slideSpeed : 300,
        displayToolbar : true,
        nextBtn : null,
        previousBtn : null 
    };

    var settings = {};
	
	// constructor
    var intializeAndValidateSettings = function(options) {
        $.extend(settings, defaultSettings, options);

        $.each(settings.selectors, function(index, itemData) {
            if (itemData.required) {
                var selectorName = '';
                var selectorValue = null;
               
			    for (prop in itemData) {
                   selectorName = prop;
                   selectorValue = itemData[prop];
                   break;
                }
                
				if ((selectorValue === null) || (selectorValue == ""))
                    throw "The following selector has not been set " + selectorName;
            }
        });
    };

    var cssSpriteImages = {
        "nextBtn" : { inActiveState : "0 24px", hoverState: "0 48px", href : "url('/Lib/Shared/Assets/Images/Carousel/Next.png')" },
        "previousBtn" : {inActiveState : "0 24px", hoverState: "0 48px", href : "url('/Lib/Shared/Assets/Images/Carousel/Prev.png')" },
        "playBtn" : {inActiveState : "0 24px", hoverState: "0 0", href : "url('/Lib/Shared/Assets/Images/Carousel/PlayPause.png')"},
        "pauseBtn" : { inActiveState : "24px 24px", hoverState: "24px 0", href : "url('/Lib/Shared/Assets/Images/Carousel/PlayPause.png')" }
    };

	ns.carousel = function (options) {
        intializeAndValidateSettings(options);

        this._carousel = $(settings.selectors[0]["carouselSelector"]);
        this._carouselWrapper = $(settings.selectors[1]["carouselWrapper"]);
        this._carouselGroup = $(settings.selectors[2]["carouselGroup"]);
        this._noSlides = this._carouselGroup.length;
        this._totalSizeOfSlides = this._carouselGroup.width() * this._noSlides;
        this._slideWidth = this._carouselGroup.width();
        this._currentSlide = 0;
        this._timerId = null;
        this._playing = false;

        var scope = this;

        setupCarouselContainer(this._carousel);
        setupCarouselWrapper(this._carouselWrapper, this._totalSizeOfSlides);
        setupCarouselGroups(this._carouselGroup, this._slideWidth);

        if (settings.displayToolbar)
            scope.createToolBar();

		scope.bindEvents();

        if (settings.autoStart > 0) {
            if (settings.displayToolbar)
                $('.carousel-playPause').trigger('click');
            else
                playOrPauseSlides(scope);
        }
	};

    var setupCarouselContainer = function(container) {
        container.css({overflow : 'hidden', position : 'relative'});
    };

    var setupCarouselWrapper = function(wrapper, totalSize) {
        wrapper.css({ position : 'absolute', left : 0, width : totalSize + 'px' });
    };

    var setupCarouselGroups = function(groups, individualWidth) {
        $.each(groups, function(i, item) {
			$(item).css({position:'absolute', left : (individualWidth * i), display : 'block'});
        });
    };

    var p = lib.shared.components.carousel.prototype;

    p.createToolBar = function() {
        var $divToolBar = $('<div></div>').addClass('toolbar').css({ 
            backgroundColor : '#000000', 
            left : '0',
            height: "0px",
            opacity: '0.6', 
            position: 'absolute',
            display:'block',
            zIndex: 1,
            width: '100%',
            top : "-29px"
        });

        addButtonsToToolbar($divToolBar);
        this._carousel.prepend($divToolBar);
    };

    var addButtonsToToolbar = function($toolBar) {
        var $nextButton = $('<a class="carousel-movenext"></a>');
	    var $playPauseButton = $('<a class="carousel-playPause"></a>');
	    var $previousButton = $('<a class="carousel-moveprevious"></a>');

        $.data($nextButton.get(0), "button-name", "nextBtn");
        $.data($playPauseButton.get(0), "button-name", "playBtn");
        $.data($previousButton.get(0), "button-name", "previousBtn");

        var sharedCss = {backgroundPosition : "0 24px", display: "block", float:"right", height: "24px", margin:"2px 0"};
        var nextCss = $.extend({}, sharedCss, { backgroundImage : cssSpriteImages["nextBtn"].href, marginRight : "2px", width : "30px" });
        var playPauseCss = $.extend({}, sharedCss, { backgroundImage : cssSpriteImages["playBtn"].href, width : "24px" });
        var previousCss = $.extend({}, sharedCss, { backgroundImage : cssSpriteImages["previousBtn"].href, width : "31px" });

        $nextButton.css(nextCss);
        $playPauseButton.css(playPauseCss);
        $previousButton.css(previousCss);
        $toolBar.append($nextButton);
        $toolBar.append($playPauseButton);
        $toolBar.append($previousButton);
    };

    var slideDownToolBar = function() {
        var $toolbar = $(this).find('div.toolbar');
        $toolbar.css({"top" : "0px"});
        $toolbar.animate({ "opacity" : 0.6, "height" : "29px" }, 500);
    };

    var slideUpToolBar = function() {
        var $toolbar = $(this).find('div.toolbar');
        $toolbar.animate({ "opacity" : 0, "height" : "0px" }, 500);
    };

    var playOrPauseSlides = function(scope) {
        var $anchor = $('.carousel-playPause');
        var buttonName = '';
        if (scope._playing) {
            stopAutoPlay(scope);
            buttonName = "playBtn";
        } else {
            startAutoPlay(scope);
            buttonName = 'pauseBtn';
        }

        if ($anchor.length > 0) {
            //check needed as toolbar may not be used
            $.data($anchor.get(0), "button-name", buttonName);
        }
        switchPlayPauseState(scope);
    };

    var previousSlide = function(scope) {
        stopAutoPlay(scope);
        animateSlides('prev', scope);
    };

    var nextSlide = function(scope) {
        stopAutoPlay(scope);
        animateSlides('next', scope);
    };

    var autoPlay = function(scope) {
        animateSlides('next', scope);
        if (scope._currentSlide == (scope._noSlides - 1)) { 
            scope._currentSlide = -1;
        }
    };

    var startAutoPlay = function(scope) {
        scope._timerId = setInterval(function() { autoPlay(scope); }, settings.autoStart);
        scope._playing = true;
    };

    var stopAutoPlay = function(scope) {
        if (scope._timerId == null) return;
        clearInterval(scope._timerId);
        scope._playing = false;
        switchPlayPauseState(scope);
    };

    var switchPlayPauseState = function(scope) {
        if (settings.displayToolbar) {
            var $button = $('.carousel-playPause');
            var state = (scope._playing) ? 'pauseBtn' : 'playBtn';
            var inActivePos = cssSpriteImages[state].inActiveState;
            $.data($button.get(0), 'button-name', state);
            $button.css({backgroundPosition : inActivePos});
        }
    };

    var animateSlides = function(direction, scope) {	
        var $carouselWrapper = $(settings.selectors[1]["carouselWrapper"]);
	
		switch(direction){
			case 'next':
			    scope._currentSlide += 1;
                if (slideIsInValidRange(scope)) {
                    var $currentSlide = scope._carouselGroup.eq(scope._currentSlide);
                    var newLeftPos = (-(parseInt($currentSlide.css('left')))) + 'px';
                    $carouselWrapper.animate({ 'left' : newLeftPos }, settings.slideSpeed, null); 
                }
				break; 
		
			case 'prev':
                scope._currentSlide -= 1;
                if (slideIsInValidRange(scope)) {
                    var $currentSlide = scope._carouselGroup.eq(scope._currentSlide);
                    var currentLeftPos = parseInt($carouselWrapper.css('left'));
                    var newLeftPos = (currentLeftPos + parseInt($currentSlide.css('left')));
                    if (scope._currentSlide == 0) {
                        newLeftPos += scope._slideWidth;
                    }
                    $carouselWrapper.animate({ 'left' : newLeftPos }, settings.slideSpeed, null); 
                }
			default:
				break;
		}					
	};
    
    var slideIsInValidRange = function(scope) {
        if (scope._currentSlide > (scope._noSlides - 1)) {
            scope._currentSlide = scope._noSlides - 1;
            return false;
        }

        if (scope._currentSlide < 0) {
            scope._currentSlide = 0;
            return false;
        }

        return true;
    };

    var displayActiveImage = function() {
        var $anchor = $(this);
        var buttonName = $.data(this, 'button-name');
        $anchor.css({backgroundPosition : cssSpriteImages[buttonName].hoverState});
    };

    var displayInActiveImage = function() {
        var $anchor = $(this);
        var buttonName = $.data(this, 'button-name');
        $anchor.css({backgroundPosition : cssSpriteImages[buttonName].inActiveState});
    };

    p.bindEvents = function(){ 
        var scope = this;
  
        if (settings.displayToolbar) {
            this._carousel.mouseenter(slideDownToolBar).mouseleave(slideUpToolBar);
            this._carousel.find('.carousel-movenext').click(function() { nextSlide(scope); });
            this._carousel.find('.carousel-moveprevious').click(function() { previousSlide(scope); });
            this._carousel.find('.carousel-playPause').click(function() { playOrPauseSlides(scope); });
            this._carousel.find('.carousel-movenext,.carousel-moveprevious,.carousel-playPause').hover(displayActiveImage, displayInActiveImage);
        }

        if (settings.nextBtn != null)
            $(settings.nextBtn).click(function() { nextSlide(scope); });

        if (settings.previousBtn != null)
            $(settings.previousBtn).click(function() { previousSlide(scope); });
    };
})($);


