﻿//*********************** Carousel Control Constants  ***************************
var UniversalMediaPlayerCarouselAttribute = {
    'DIRECTION': 'carousel-direction'
}

var UniversalMediaPlayerCarouselDirection = {
    'FORWARD': 'forward',
    'REVERSE': 'reverse'
}

var UniversalMediaPlayerCarouselJavaScriptEvent = {
    'CLICK': 'click',
    'MOUSE_OVER': 'mouseover',
    'MOUSE_OUT': 'mouseout'
}

var UniversalMediaPlayerCarouselEvent = {
    'CLICK': 'click'
}

var UniversalMediaPlayerCarouselNavigationEvent = {
    'NAVIGATE_FORWARD': 'forward',
    'NAVIGATE_REVERSE': 'reverse'
}

var UniversalMediaPlayerCarouselItemState = {
    "INACTIVE": false,
    "ACTIVE": true
}

var UniversalMediaPlayerCarouselItemStyle = {
    "INACTIVE": "mod-ump-carousel-item-inactive",
    "ACTIVE": "mod-ump-carousel-item-active",
    "HIGHLIGHT": "mod-ump-carousel-item-highlight"
}

var UniversalMediaPlayerCarouselItemCaptionStyle = "mod-ump-carousel-item-caption";

var UniversalMediaPlayerCarouselAssetType = {
    "AUDIO": "audio",
    "VIDEO": "video",
    "IMAGE": "image",
    "DOCUMENT": "document"
}

var UniversalMediaPlayerCarouselPlayerType = {
    "Embedded": 0,
    "Modal": 1
}

var UmpHtmlCarouselItemCount = new Array();
UmpHtmlCarouselItemCount["Small"] = 2;
UmpHtmlCarouselItemCount["Medium"] = 3;
UmpHtmlCarouselItemCount["Large"] = 4;

var UmpHtmlCarouselPreviewPaneSizeDimensions = new Array();
UmpHtmlCarouselPreviewPaneSizeDimensions["Small"] = { "Width": 320, "Height": 180 };
UmpHtmlCarouselPreviewPaneSizeDimensions["Medium"] = { "Width": 480, "Height": 270 };
UmpHtmlCarouselPreviewPaneSizeDimensions["Large"] = { "Width": 640, "Height": 360 };

var UmpHtmlCarouselInfoDisplayTop = new Array();
UmpHtmlCarouselInfoDisplayTop["Small"] = 190; //
UmpHtmlCarouselInfoDisplayTop["Medium"] = 280; //
UmpHtmlCarouselInfoDisplayTop["Large"] = 370;

var UmpHtmlCarouselHeaderContainerTop = new Array();
UmpHtmlCarouselHeaderContainerTop["Small"] = 280; //
UmpHtmlCarouselHeaderContainerTop["Medium"] = 370; //
UmpHtmlCarouselHeaderContainerTop["Large"] = 460;

var UmpHtmlCarouselContainerPosition = new Array();
UmpHtmlCarouselContainerPosition["Small"] = { "Top": 310, "Left": 0 }; //
UmpHtmlCarouselContainerPosition["Medium"] = { "Top": 400, "Left": 5 }; //
UmpHtmlCarouselContainerPosition["Large"] = { "Top": 490, "Left": 9 };

var UniversalMediaPlayerWindowName = 'IntelUniversalMediaDocumentWindow';

//*********************************************************************************
//*********************** Carousel Control Constructor  ***************************
function Carousel(container, contentDiv, maskDiv, navigationControl, duration, interval, itemWidth, displayCount, infoDisplay, previewPane, header) {
    this.m_Container = container;
    this.m_ContentDiv = contentDiv;
    this.m_MaskDiv = maskDiv;
    this.m_NavigationControl = navigationControl;
    this.m_InfoDisplay = infoDisplay;
    this.m_PreviewPane = previewPane;
    this.m_Header = header;
    
    

    this.m_Duration = duration;
    this.m_Interval = interval;
    this.m_ElapsedTime = 0;
    this.m_MoveX = itemWidth;
    this.m_DisplayCount = displayCount;
    this.m_Direction = null;
    this.m_Count = 0;
    this.m_Cursor = 0;
    this.m_Increment = displayCount;

    this.m_RequestManager = new RequestManager();
    this.m_ContentDiv.OffsetStartX = this.m_ContentDiv.offsetLeft;
    this.m_Items = [];

    this.m_DataResponseDelegate = CreateDelegate(this, this.AddItems);
    this.m_NavigateForwardDelegate = CreateDelegate(this, this.NavigateForwardHandler);
    this.m_NavigateReverseDelegate = CreateDelegate(this, this.NavigateReverseHandler);
    this.m_ItemClickDelegate = CreateDelegate(this, this.ItemClickHandler);
    this.m_PreviewClickDelegate = CreateDelegate(this, this.PreviewClickHandler);

    this.m_MaskDiv.style.width = this.m_MoveX * this.m_DisplayCount + 'px';
    this.m_Container.style.width = this.m_MoveX * this.m_DisplayCount
                                    + this.m_NavigationControl.m_ForwardButton.m_ButtonElement.clientWidth
                                    + this.m_NavigationControl.m_ReverseButton.m_ButtonElement.clientWidth 
                                    + 7 + 'px';

    this.PlayerParent = null;
    this.PlayerType = null;

    this.StartListeningToNavigation();

    this.OnCarouselPopulated = null;
}

//*********************** Carousel Control Event Handlers  ***************************
Carousel.prototype.NavigateForwardHandler = function() {
    this.StopListeningToNavigation();
    this.NavigateForward();
}

Carousel.prototype.NavigateReverseHandler = function() {
    this.StopListeningToNavigation();
    this.NavigateReverse();
}

Carousel.prototype.ItemClickHandler = function(itemInfo) {
    if (itemInfo.Type == UniversalMediaPlayerCarouselAssetType.DOCUMENT) {
        this.LaunchAssetInNewPage(itemInfo.URL);
    }
    else {
        this.LaunchAssetInUMP(itemInfo);
    }

    for (var index = 0; index < this.m_Items.length; index++) {
        var currentItem = this.m_Items[index];
        if (currentItem.m_CarouselItemInfo.IndexInList == itemInfo.IndexInList) {
            currentItem.ToggleActiveState(UniversalMediaPlayerCarouselItemState.ACTIVE);
        }
        else {
            currentItem.ToggleActiveState(UniversalMediaPlayerCarouselItemState.INACTIVE);
        }
    }
}

Carousel.prototype.PreviewClickHandler = function() {
    this.m_PreviewPane.Container.style.display = 'none';
    this.PlayerParent.Play();
}


//*********************** Carousel Control Methods  ***************************
Carousel.prototype.PopulateCarousel = function(feedUrl) {
    this.Clear();
    this.m_RequestManager.LoadJSON(feedUrl, this.m_DataResponseDelegate);
}

Carousel.prototype.AddItems = function(feed) {
    var count = feed.UmpCarouselItems.length;
    for (var index = 0; index < count; index++) {

        var itemData = feed.UmpCarouselItems[index];
        this.AddItem(itemData.title, itemData.description,
                    itemData.asset, itemData.type,
                    itemData.thumbnail, itemData.preview,
                    itemData.pageUrl, itemData.shareUrl,
                    itemData.link, itemData.linkDescription)
    }
    
    if (this.OnCarouselPopulated != null) {
        this.OnCarouselPopulated();
    }
}

Carousel.prototype.AddItem = function(title, description, url, type, thumbnail, preview, pageUrl, shareUrl, link, linkDescription) {
    var carouselItem = new CarouselItem(this.m_Count, title, description, url, type, thumbnail, preview, pageUrl, shareUrl, link, linkDescription);
    carouselItem.OnItemClick = this.m_ItemClickDelegate;
    this.m_Items.push(carouselItem);

    this.m_Count++;
    this.m_ContentDiv.appendChild(carouselItem.m_Markup);
    this.m_ContentDiv.style.width = this.m_Count * this.m_MoveX + 'px';
}

Carousel.prototype.Clear = function() {
    this.m_Count = 0;
    this.m_ContentDiv.innerHTML = '';
}

Carousel.prototype.StartListeningToNavigation = function() {
    this.m_NavigationControl.OnNavigateForward = this.m_NavigateForwardDelegate;
    this.m_NavigationControl.OnNavigateReverse = this.m_NavigateReverseDelegate;
}

Carousel.prototype.StopListeningToNavigation = function() {
    this.m_NavigationControl.OnNavigateForward = null;
    this.m_NavigationControl.OnNavigateReverse = null;
}

Carousel.prototype.NavigateForward = function() {
    var boundary = this.m_MoveX * this.m_Count;

    if (this.m_Count - this.m_Cursor > this.m_DisplayCount) {
        if (this.m_Count - (this.m_Cursor + this.m_DisplayCount) < this.m_DisplayCount) {
            this.m_Increment = -(this.m_Count - (this.m_Cursor + this.m_DisplayCount));
        }
        else {
            this.m_Increment = -(this.m_DisplayCount);
        }

        this.m_Cursor -= this.m_Increment;
    }
    else {
        this.AnimateComplete();
        return;
    }

    this.m_ContentDiv.StartX = this.m_ContentDiv.offsetLeft;
    this.Animate();
}

Carousel.prototype.NavigateReverse = function() {
    if (this.m_Cursor > 0) {
        if (this.m_Cursor - this.m_DisplayCount > 0) {
            this.m_Increment = this.m_DisplayCount;
        }
        else {
            this.m_Increment = this.m_Cursor;
        }

        this.m_Cursor -= this.m_Increment;
    }
    else {
        this.AnimateComplete();
        return;
    }

    this.m_ContentDiv.StartX = this.m_ContentDiv.offsetLeft;
    this.Animate();
}

Carousel.prototype.Animate = function() {
    this.m_ElapsedTime += this.m_Interval;

    var percentDuration = (Math.abs(this.m_Increment) / this.m_DisplayCount) * this.m_Duration;
    //var percentChange = Math.pow(((1 / percentDuration) * this.m_ElapsedTime), .25);
    var percentChange = this.m_ElapsedTime / percentDuration;

    var moveX = this.m_MoveX * this.m_Increment;
    this.m_ContentDiv.style.left = this.m_ContentDiv.StartX + (percentChange * moveX) + "px";

    if (this.m_ElapsedTime <= percentDuration) {
        setTimeout(CreateDelegate(this, this.Animate), this.m_Interval);
    }
    else {
        this.m_ContentDiv.style.left = this.m_ContentDiv.StartX + moveX + "px";
        this.AnimateComplete();
    }
}

Carousel.prototype.AnimateComplete = function() {
    this.m_ElapsedTime = 0;
    this.StartListeningToNavigation();
}

Carousel.prototype.LaunchAssetInUMP = function(info) {
    this.m_PreviewPane.Container.style.display = 'none';

    info.PlayState = UmpPlayState.ON;
    if (this.PlayerType == UniversalMediaPlayerCarouselPlayerType.Embedded &&
        (info.Type == UniversalMediaPlayerCarouselAssetType.VIDEO || info.Type == UniversalMediaPlayerCarouselAssetType.AUDIO)
        ) {
        info.PlayState = UmpPlayState.OFF
        RemoveHandler(this.m_PreviewPane.Anchor, 'click', this.m_PreviewClickDelegate);
    }

    this.PlayerParent.DisplayAsset(info);
    this.PlayerParent.DisplayContentInfo(UmpComponentDisplayState.OFF);
    this.PlayerParent.DisplayCarousel(UmpComponentDisplayState.OFF);

    this.m_InfoDisplay.Title.innerHTML = (info.Title != '' && info.Title != undefined) ? info.Title : '';
    this.m_InfoDisplay.Description.innerHTML = (info.Description != '' && info.Description != undefined) ? info.Description : '';
    this.m_InfoDisplay.Link.href = (info.Link != '' && info.Link != undefined) ? info.Link : '';
    this.m_InfoDisplay.Link.innerHTML = (info.LinkDescription != '' && info.LinkDescription != undefined) ? info.LinkDescription : '';
    this.m_InfoDisplay.Link.href = (info.Link != '' && info.Link != undefined) ? info.Link : '';

    if (this.PlayerType == UniversalMediaPlayerCarouselPlayerType.Embedded && info.PlayState == UmpPlayState.OFF) {
        this.m_PreviewPane.Container.style.backgroundImage = 'url(' + info.Preview + ')';
        this.m_PreviewPane.Container.style.display = 'block';
        AddHandler(this.m_PreviewPane.Anchor, 'click', this.m_PreviewClickDelegate);
    }
}

Carousel.prototype.LaunchAssetInNewPage = function(url) {
    this.PlayerParent.Pause();
    window.open(url, UniversalMediaPlayerWindowName);
}





//*********************************************************************************
//*********************** Carousel Navigation Control  ***************************
function CarouselNavigationControl(forwardButton, reverseButton) {
    this.m_ForwardButton = forwardButton;
    this.m_ReverseButton = reverseButton;

    this.m_ForwardButton.OnButtonClick = CreateDelegate(this, this.NavButtonClickHandler);
    this.m_ReverseButton.OnButtonClick = CreateDelegate(this, this.NavButtonClickHandler);

    this.OnNavigateForward = null;
    this.OnNavigateReverse = null;
}

//*********************** Carousel Control Nav Button Event Handlers  ***************************
CarouselNavigationControl.prototype.NavButtonClickHandler = function(direction) {
    switch (direction) {
        case UniversalMediaPlayerCarouselDirection.FORWARD:
            this.FireEvent(UniversalMediaPlayerCarouselNavigationEvent.NAVIGATE_FORWARD);
            break;
        case UniversalMediaPlayerCarouselDirection.REVERSE:
            this.FireEvent(UniversalMediaPlayerCarouselNavigationEvent.NAVIGATE_REVERSE);
            break;
    }
}

//*********************** Carousel Nav Control Methods  ***************************
CarouselNavigationControl.prototype.FireEvent = function(type) {
    switch (type) {
        case UniversalMediaPlayerCarouselNavigationEvent.NAVIGATE_FORWARD:
            if (this.OnNavigateForward != null) {
                this.OnNavigateForward();
            }
            break;
        case UniversalMediaPlayerCarouselNavigationEvent.NAVIGATE_REVERSE:
            if (this.OnNavigateReverse != null) {
                this.OnNavigateReverse();
            }
            break;
    }
}




//*********************************************************************************
//*********************** Carousel Nav Control Button  ***************************
function CarouselNavButton(element, direction) {
    this.m_ButtonElement = element;
    this.m_Direction = direction;

    this.m_ClickDelegate = CreateDelegate(this, this.ClickHandler);
    AddHandler(this.m_ButtonElement, UniversalMediaPlayerCarouselJavaScriptEvent.CLICK, this.m_ClickDelegate);

    this.OnButtonClick = null;
}

//*********************** Carousel Nav Control Button Event Handlers  ***************************
CarouselNavButton.prototype.ClickHandler = function(e) {
    this.FireEvent(UniversalMediaPlayerCarouselEvent.CLICK);
}

//*********************** Carousel Nav Control Button Methods  ***************************
CarouselNavButton.prototype.FireEvent = function(type) {
    switch (type) {
        case UniversalMediaPlayerCarouselEvent.CLICK:
            if (this.OnButtonClick != null) {
                this.OnButtonClick(this.m_Direction);
            }
            break;
    }
}




//*********************************************************************************
//*********************** Carousel Item  ***************************
function CarouselItem(index, title, description, url, type, thumbnail, preview, pageUrl, shareUrl, link, linkDescription) {
    this.m_CarouselItemInfo = new CarouselItemInfo(index, title, description, url, type, thumbnail, preview, pageUrl, shareUrl, link, linkDescription);
    this.m_Markup = null;

    this.CreateMarkup();

    this.m_ClickDelegate = CreateDelegate(this, this.ClickHandler);
    this.m_MouseOverDelegate = CreateDelegate(this, this.MouseOverHandler);
    this.m_MouseOutDelegate = CreateDelegate(this, this.MouseOutHandler);

    AddHandler(this.m_Markup, UniversalMediaPlayerCarouselJavaScriptEvent.CLICK, this.m_ClickDelegate);
    AddHandler(this.m_Markup, UniversalMediaPlayerCarouselJavaScriptEvent.MOUSE_OVER, this.m_MouseOverDelegate);
    AddHandler(this.m_Markup, UniversalMediaPlayerCarouselJavaScriptEvent.MOUSE_OUT, this.m_MouseOutDelegate);

    this.OnItemClick = null;
    this.IsActive = false;
}

//*********************** Carousel Item Event Handlers  ***************************
CarouselItem.prototype.ClickHandler = function(e) {
    this.FireEvent(UniversalMediaPlayerCarouselEvent.CLICK);
}

CarouselItem.prototype.MouseOverHandler = function(e) {
    if (!this.IsActive) {
        this.m_Markup.className = UniversalMediaPlayerCarouselItemStyle.HIGHLIGHT;
    }
}

CarouselItem.prototype.MouseOutHandler = function(e) {
    if (!this.IsActive) {
        this.m_Markup.className = UniversalMediaPlayerCarouselItemStyle.INACTIVE;
    }
}

//*********************** Carousel Item Methods  ***************************
CarouselItem.prototype.ToggleActiveState = function(state) {
    switch (state) {
        case UniversalMediaPlayerCarouselItemState.ACTIVE:
            this.m_Markup.className = UniversalMediaPlayerCarouselItemStyle.ACTIVE;
            break;
        case UniversalMediaPlayerCarouselItemState.INACTIVE:
            this.m_Markup.className = UniversalMediaPlayerCarouselItemStyle.INACTIVE;
            break;
    }

    this.IsActive = state;
}

CarouselItem.prototype.CreateMarkup = function() {
    this.m_Markup = document.createElement('div');
    this.m_Markup.className = UniversalMediaPlayerCarouselItemStyle.INACTIVE;
    this.m_Markup.style.backgroundImage = 'url(' + this.m_CarouselItemInfo.Thumbnail + ')';

    var title = document.createElement('div');
    title.innerHTML = this.m_CarouselItemInfo.Title;
    title.className = UniversalMediaPlayerCarouselItemCaptionStyle;
    this.m_Markup.appendChild(title);
}

CarouselItem.prototype.FireEvent = function(type) {
    switch (type) {
        case UniversalMediaPlayerCarouselEvent.CLICK:
            if (this.OnItemClick != null) {
                this.OnItemClick(this.m_CarouselItemInfo);
            }
            break;
    }
}




//*********************************************************************************
//*********************** Carousel Item Info  ***************************
function CarouselItemInfo(index, title, description, url, type, thumbnail, preview, pageURL, shareURL, link, linkDescription) {
    this.Type = type;
    this.URL = url;
    this.Thumbnail = thumbnail;
    this.Preview = preview;
    this.ShareURL = shareURL;
    this.PageURL = pageURL;
    this.Title = title;
    this.Description = description;
    this.IndexInList = index;
    this.Link = link;
    this.LinkDescription = linkDescription;
}

CarouselItemInfo.prototype = new UniversalMediaPlayerAsset();





//*********************************************************************************
//*********************** Carousel Info Display  ***************************
function CarouselInfoDisplay(container, title, description, link) {
    this.Container = container;
    this.Title = title;
    this.Description = description;
    this.Link = link;
}





//*********************************************************************************
//*********************** Carousel Header  ***************************
function CarouselHeader(title, container) {
    this.Container = container;
    this.Title = title;
}

function CarouselPreviewPane(container, anchor) {
    this.Container = container;
    this.Anchor = anchor;
}




//*********************************************************************************
//*********************** Data Request Manager  ***************************
function RequestManager() {
}

RequestManager.prototype.CreateXMLHttpRequest = function() {
    if (typeof XMLHttpRequest != "undefined") {
        return new XMLHttpRequest();
    }
    else if (typeof ActiveXObject != "undefined") {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {
        throw new Error("XMLHttpRequest not supported");
    }
};

RequestManager.prototype.LoadXML = function(file, delegate) {
    var request = this.CreateXMLHttpRequest();
    request.open("GET", file, true);
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            if (request.status != 404) {
                delegate(request.responseXML);
            }
        }
    }
    request.send(null);
};

RequestManager.prototype.LoadJSON = function(url, delegate) {
    var request = this.CreateXMLHttpRequest();
    request.open("GET", url, true);
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            if (request.status != 404) {
                var response = new Function("return " + request.responseText + ";")();
                delegate(response);
            }
        };
    }
    request.send(null);
};

RequestManager.prototype.LoadJSONScriptBlock = function(url, delegate) {
    var pageHead = document.getElementsByTagName('head')[0];

    var jsonScriptBlock = document.createElement('script');
    jsonScriptBlock.type = 'text/javascript';
    jsonScriptBlock.src = url;

    pageHead.appendChild(jsonScriptBlock);

    delegate();
};
