/**
 * responsible for handling popup overlays for photo, video, etc.
 * @param {Cobalt.Core.Sandbox} sandbox
 */

Cobalt.Website.Common.PhotoPopupModule = function(sandbox)
{
	var _imgLoader;
    var _photoData;
    var _photoItems;
    var _panelElement;
    var _activeCarousel;
	var _pixelData;

    function getImgLoader()
    {
        if (!_imgLoader) { _imgLoader = new Cobalt.Core.LazyImageLoader(sandbox); }
        return _imgLoader;
    }

    function getPhotoData() { return _photoData; }
    function setPhotoData(data) { _photoData = data; }

    function getPhotoItems() { return _photoItems; }
    function setPhotoItems(data) { _photoItems = data; }
    function getPhotoItemsLength() { return parseInt(getPhotoItems().length,10); }

    function getPanelElement() { return _panelElement; }
    function setPanelElement(ele) { _panelElement = ele; }

    function getActiveCarousel() { return _activeCarousel; }
    function setActiveCarousel(obj) { _activeCarousel = obj; }
	
	function setPixelData(data) {_pixelData = data;}
	function getPixelData() {return _pixelData;}
	
	function renderMediaPopup(e)
	{
        var customData = e.customData;

        setPhotoData(customData.data);
        setPhotoItems(customData.items);
		setPixelData(customData.pixelData);
		setPanelElement(customData.tabData.panel);
        
        if(customData.initialLoad) firePixelTagForPhoto();

		if(getPhotoItemsLength() === 1){
			handleSinglePhoto();
			return;
		}

		constructPhotoGallery(getPanelElement());
	}

    function getNumberOfThumbsToDisplay()
    {
        var visible = parseInt(getPhotoData().itemsToBeDisplayedInCarousel);
		var total = getPhotoItemsLength();
		if (total <= visible)  visible = total;
        return visible;
    }
	
	function constructPhotoGallery(pnlElement){
		/*Construct DOM*/
        var caroselUi = constructMainImage(null);		
		var slider = sandbox.dom("<div class='photoCarousel'></div>").getDomElements();		
		var clear = sandbox.dom("<div style='clear:both'></div>").getDomElements();		
		var list = sandbox.dom("<ul class='photo_thumb'></ul>").getDomElements();
		
		sandbox.dom(slider).append(list);		
		sandbox.dom(caroselUi).append(slider);
		sandbox.dom(caroselUi).append(clear);		
		sandbox.dom(pnlElement).empty();
		sandbox.dom(pnlElement).append(caroselUi);
		
		/*Construct Carousel*/
		var carouselSelector = "div[id='" + sandbox.dom(pnlElement).attr("id") + "'] div.photoCarousel";
        var visible = getNumberOfThumbsToDisplay();
        
		sandbox.dom(carouselSelector).carousel({
			start: 1,
            auto:6,
            scroll:1,
			animation:"slow",
            visible: visible,
			buttonNextHTML:"<div class='next'></div>",
			buttonPrevHTML:"<div class='prev'></div>",
			initCallback: initCarouselCallback,
			itemVisibleInCallback: {onBeforeAnimation: loadThumbs},
			itemVisibleOutCallback: {onAfterAnimation: removeThumbs},
			itemFirstInCallback: {onBeforeAnimation: loadFirstPhoto}
		});
	}
	
	function initCarouselCallback(carousel)
	{
        setActiveCarousel(carousel);
        var visible = getNumberOfThumbsToDisplay();

		carousel.buttonNext.click(function() 
		{
			carousel.startAuto(0);
			carousel.options.scroll = visible;
		});
		carousel.buttonPrev.click(function() 
		{
			carousel.startAuto(0);
			carousel.options.scroll = visible;			
		});		
	}

    function createThumbElement(thumbUrl, carousel, i, item)
    {
        return sandbox.dom("<img src='" + thumbUrl + "'/>").click(function()
                    {
                        carousel.startAuto(0);
                        carousel.options.scroll = 0;
                        updateImageAndStatus(i, item);
                    });
    }

    function loadThumbs(carousel, item, i, state)
	{
        //carousel index is 1 based
        var photoElementIndex = getPhotoElementIndex(carousel, i); 
		
        if (! getPhotoItems()[photoElementIndex] ) { return; }
        
        var thumbUrl = getPhotoItems()[photoElementIndex].thumb;

        getImgLoader().load(null, thumbUrl, function()
        {
            if (!carousel.has(i)) {
                carousel.add(i, createThumbElement(thumbUrl, carousel, photoElementIndex, item));
            }
        });
	}
	
	function removeThumbs(carousel, item, i, state){
		carousel.remove(i);
	}

	function loadFirstPhoto(carousel, item, i)
	{
        updateImageAndStatus(getPhotoElementIndex(carousel, i), item);
	}
	
	function getPhotoElementIndex(carousel, i){
		return carousel.index(i, getPhotoItemsLength()) - 1;
	}

    function handleSinglePhoto()
    {	
		var url = getPhotoItems()[0].full;
		var container = sandbox.dom(getPanelElement()).getDomElements();
		loadImage(container, url);
		updateTabStatus(0);
    }
	
    function constructMainImage(url)
    {	
        var caroselUi = sandbox.dom("<div class='carousel widget'></div>").getDomElements();
		var caroselDisplayUi = url ? sandbox.dom("<div class='mid'><img src='" + url + "'/></div>").getDomElements() : sandbox.dom("<div class='mid'></div>").getDomElements();
        sandbox.dom(caroselUi).append(caroselDisplayUi);
        return caroselUi;
    }
	
	function updateImageAndStatus(carouselItemIndex, item)
	{
		var photoItemIndex = parseInt(carouselItemIndex);
		var url = getPhotoItems()[photoItemIndex].full;
		var container = sandbox.dom("div[class='mid']").getDomElements();
		loadImage(container, url);
		var selectedItems = sandbox.dom(getPanelElement()).find('li[class~="jcarousel-item-selected"]');
		sandbox.dom(selectedItems).removeClass('jcarousel-item-selected');
		sandbox.dom(item).addClass('jcarousel-item-selected');
		updateTabStatus(photoItemIndex);
	}
	
	function loadImage(container, url)
	{
		sandbox.raise(null, Cobalt.Website.Common.Events.LoadingIndicatorStart, {parentModule:container});
		getImgLoader().load(container, url, function(){
			sandbox.raise(null, Cobalt.Website.Common.Events.LoadingIndicatorStop, null);
		});
	}
	
	function updateTabStatus(index)
	{
		var current = sandbox.dom('<span class="current">' + (index+1) + ' of </span>').getDomElements();
		sandbox.dom('span.current').remove();
		sandbox.dom('span.count').before(current);
	}

	function firePixelTagForPhoto()
	{	
		var eventName = 'com.cobaltgroup.ws.view.media.photo';
		var vin = getPixelData().vin;
		var pageLabel = 'PhotoPopup';
		var pageLayout = getPixelData().pageLayout;
		var pageName = getPixelData().pageName;
		sandbox.firePixelTag({
			eventName: eventName,
			vin: vin,
			pageLabel: pageLabel,
			pageLayout: pageLayout,
			pageName: pageName,
			requestUri: null
		});
	}
	
	function destroyCarousel(e)
	{
        var element = getPanelElement();

        if(getActiveCarousel()){
            getActiveCarousel().startAuto(0);
            sandbox.dom(element).empty();
        }
	}

    return {
        init:function()
        {
			sandbox.listen(null, Cobalt.Website.Common.Events.PhotoTabClicked, renderMediaPopup, null);
			sandbox.listen(null, Cobalt.Website.Common.Events.DestroyPopup, destroyCarousel, null);
        },

        destroy:function()
        {
            destroyCarousel(null);
        }
    };
};

/**
 * @interface Cobalt.Core.ImageLoader
 */
Cobalt.Core.ImageLoader = function() {};
Cobalt.Core.ImageLoader.prototype.load = function(imageContainer, newImageUrl)
{ throw new Error("interface method must be implemented"); };

/**
 * @implements {Cobalt.Core.ImageLoader}
 */
Cobalt.Core.LazyImageLoader = function(sandbox)
{
    Cobalt.Core.ImageLoader.call(this);
    this.Sandbox = sandbox;
};
Cobalt.Core.LazyImageLoader.prototype = new Cobalt.Core.ImageLoader();

Cobalt.Core.LazyImageLoader.prototype.load = function(imageContainer, newImageUrl, callback)
{	
	var sandbox = this.Sandbox;
	var newImg = new Image();
	sandbox.dom(newImg).attr("src", newImageUrl);
	
	sandbox.dom(newImg).load(function(e)
	{
		if (imageContainer)
		{
            sandbox.dom(imageContainer).empty();
			sandbox.dom(imageContainer).append(this);
		}
		
		if (typeof callback ===  "function"){ callback(); }
	});
	
	sandbox.dom(newImg).each(function()    //ie doesn't fire load if img is loaded from cahce
	{
		if(this.complete) sandbox.raise(this,"load",null,null);
	});
	
	sandbox.dom(newImg).error(function (e) {
		var error = e;
	});	
};
