﻿// object: wrapper
var GlossaryPopups = {};

// object: global parameters
GlossaryPopups.Params = {        //null values set in Init
    PopupID: "GlossaryPopup",
    TermClassName: "GlossaryTerm",
    PopupOffsetX: 0,
    PopupOffsetY: -274,
    WebServiceUrl: null,
    GlossaryUrl: null,
    VideoPlayerUrl: null,
    VideoPlayerWidth: "190",
    VideoPlayerHeight: "165",
    AudioPlayerUrl: null,
    AudioPlayerWidth: "190",
    AudioPlayerHeight: "40",
    CloseButtonUrls: { Default: "", MouseOver: "", MouseDown: "" },
    PrevButtonUrls: { Default: "", MouseOver: "", MouseDown: "", Disabled:"" },
    NextButtonUrls: { Default: "", MouseOver: "", MouseDown:"", Disabled:"" }
};

// object: The interior template of the popup. Note that changing classnames will affect HTML injection in 
//           GlossaryPopups.RetrieveTermDescription_Success.
GlossaryPopups.PopupTemplate =   "<div class='PopupTemplate'>" +
                                    "<div class='CloseButton'></div>" +
                                    "<div class='Description'>" +
                                        "<h2 class='Term'></h2>" +
                                        "<div class='Definition'></div>" +
                                        "<ul class='LinkList'></ul>" +
                                    "</div>" +
                                    "<div class='Gallery'></div>" +
                                    "<div class='Clear'></div>" +
                                    "<div class='Footer'>" +
                                        "<div class='KeywordsContainer'>" +
                                            "Keywords: <span class='Keywords'></span>" +
                                        "</div>" +
                                        "<div class='GlossaryLinkContainer'>" +
                                            "<a class='GlossaryLink'>View the full Glossary</a>" +
                                        "</div>" +
                                        "<div class='Clear'></div>" +
                                    "</div>" +
                                "</div>";

//object: caches glossary data
GlossaryPopups.PopupHtmlCache = {};

//object: track states
GlossaryPopups.States = {
    IsOpening: false,
    IsOpen: false
};

// function: intialize glossary display on all spans with given classname
GlossaryPopups.Init = function (options) {
    var GP = GlossaryPopups,
        params = GP.Params;
        
    // save params if provided
    if (options)
    {
        $.extend(params, options);
    }
    // bind all links
    $("." + params.TermClassName).each( function (i) {
        $(this).unbind('click').bind('click', GP.ShowTerm);
    });
};

// function: Open glossary details window
GlossaryPopups.ShowTerm = function () {
    if (!GlossaryPopups.States.IsOpening)
    {
        var GP = GlossaryPopups,
            term = $(this).text();
        if (GP.States.IsOpen)
        {
            GP.CloseTermPopup();
        }
        GP.States.IsOpening = true;
        GP.InitializePopup($(this).offset(), $(this).width(), $(this).height());
        GP.RetrieveTermDescription(term);
    }
    return false;
};

// function: Initializes the display/location of the popup
GlossaryPopups.InitializePopup = function (offsetObj, targetWidth, targetHeight) {
    // declare vars
    var GP = GlossaryPopups,
        params = GP.Params,
        popupID = params.PopupID,
        popupOffsetX = params.PopupOffsetX,
        popupOffsetY = params.PopupOffsetY,
        popup = $("#" + popupID),
        cssObj = {
            top: offsetObj.top + 0 + popupOffsetY,
            left: offsetObj.left + targetWidth + popupOffsetX
        },
        outOfFrame = {
            top: cssObj.top < 0,
            right: cssObj.left + 485 > $(document).width()
        };
        
    // if the popup div does not yet exist, create it
    if (popup.length == 0)
    {
        $("body").append("<div id=\"" + popupID + "\" class='GlossaryPopup'></div>");
        popup = $("#" + popupID);
    }
    
    //write base template
    popup.html(GP.PopupTemplate);
    
    // if popup is out of frame, change offsets and class
    // Disabled until fully implemented
    $.extend(cssObj, GP.GetRotatedOffset(cssObj, outOfFrame));
    GP.SetRotatedClass(popup, outOfFrame);
    
    // set the position
    popup.css(cssObj);
};

GlossaryPopups.GetRotatedOffset = function (origCss, outOfFrame)
{
    var newCss = {};
    if (outOfFrame.top)
    {
        newCss.top = origCss.top + 324;
    }
    if (outOfFrame.right)
    {
        newCss.left = origCss.left - 335;
    }
    return newCss;
}

GlossaryPopups.SetRotatedClass = function (target, outOfFrame) {
    target.removeClass("TL").removeClass("BR").removeClass("BL");
    if (outOfFrame.top && outOfFrame.right)
    {
        target.addClass("BL");
    }
    else if (outOfFrame.top)
    {
        target.addClass("BR");
    }
    else if (outOfFrame.right)
    {
        target.addClass("TL");
    }
}

// function (AJAX): Asynchronously retrieve term description
GlossaryPopups.RetrieveTermDescription = function (term) {
    var GP = GlossaryPopups,
        cachedHtml = GP.PopupHtmlCache[term.toLowerCase()]
        popup = $("#" + GP.Params.PopupID);
    if (cachedHtml)
    {
        popup.html(cachedHtml);
        GP.OpenTermPopup();
    }
    else
    {
        $.ajax({
            type: "POST",
            url: GP.Params.WebServiceUrl + "/GetGlossaryTermDescription",
            contentType: "application/json; charset=utf-8",
            data: "{Term:\"" + escape(term) + "\"}",
            dataType: "json",
            success: GP.RetrieveTermDescription_Success
        });
    }
};                              

// function: RetrieveTermDescription successful -> inject html
GlossaryPopups.RetrieveTermDescription_Success = function (results) {
    if (results.d != null)
    {
        var GP = GlossaryPopups,
            popup = $("#" + GP.Params.PopupID),
            data = results.d;

        GP.FillTemplate(data);
        GP.PopupHtmlCache[data.Term.toLowerCase()] = popup.html();
        
        GP.OpenTermPopup();
    }
};

// function: Fill the template with the retrieved data
GlossaryPopups.FillTemplate = function(data) {
    if (data != null)
    {
        var GP = GlossaryPopups,
            params = GP.Params,
            popup = $("#" + params.PopupID),
            linkList = popup.find(".LinkList"),
            keywordsContainer = popup.find(".KeywordsContainer"),
            keywords = keywordsContainer.find(".Keywords"),
            glossaryLink = popup.find(".GlossaryLink"),
            gallery = popup.find(".Gallery"),
            glossaryUrl = params.GlossaryUrl,
            listenLI;
        
        // Write html to popup
        popup.find(".Term").text(data.Term);
        popup.find(".Definition").html(data.Definition);
        
        // Add links to list
        if (data.ListenText && data.ListenUrl)
        {
            //linkList.append("<li><a class='ListenLink' href='" + data.ListenUrl + "'>" + data.ListenText + "</a></li>");
            linkList.append("<li><span class='Bullet'>&gt;</span></li>");
            listenLI = linkList.find("li:last");
            listenLI.append("<a class='ListenLink' href='" + data.ListenUrl + "'>" + data.ListenText + "</a>");
            listenLI.append("<div class='AudioPlayerContainer'><div id='AudioPlayer'></div></div>");
        }
        if (data.BuyText && data.BuyUrl)
        {
            linkList.append("<li><a href='" + data.BuyUrl + "'>" + data.BuyText + "</a></li>");
        }
        if (data.MoreInfoText && data.MoreInfoUrl)
        {
            linkList.append("<li><a href='" + data.MoreInfoUrl + "'>" + data.MoreInfoText + "</a></li>");
        }
        
        //Write tags
        if (!data.Tags || data.Tags.length == 0)
        {
            keywordsContainer.hide();
        }
        else
        {
            for (var i = 0; i < data.Tags.length; i++)
            {
                if (data.Tags[i].indexOf("Type_") != 0)
                {
                    keywords.append("<a href=\"" + glossaryUrl + "?Keyword=" + encodeURIComponent(data.Tags[i]) + "\">" + data.Tags[i] + "</a>");
                    if (i < data.Tags.length - 1)
                    {
                        keywords.append(", ");
                    }
                }
            }
            //fix case where last tag is a type, leaving an extra comma
            var keywordsHtml = keywords.html();
            if (keywordsHtml.lastIndexOf(", ") == keywordsHtml.length - 2)
            {
                keywords.html(keywordsHtml.substring(0, keywordsHtml.length - 2));
            }
        }
        
        //Write glossary link location
        glossaryLink.attr("href", glossaryUrl);
        
        GP.WriteGalleryHtml(gallery, data.GalleryItems);
    }
};

//function: Construct the html for the gallery from a given array of URLs
GlossaryPopups.WriteGalleryHtml = function (targetDiv, galleryItems) {
    var params = GlossaryPopups.Params,
        url, altText, galleryItem, videoPlayerContainer;
    
    for (var i = 0; i < galleryItems.length; i++)
    {
        url = galleryItems[i].Url;
        altText = galleryItems[i].AltText;
        
        if (url.toLowerCase().lastIndexOf(".flv") == url.length - 4)
        {
            //File is an FLV -> add video player info
            targetDiv.append("<div class='GalleryItem Video'></div>");
            galleryItem = targetDiv.find(".GalleryItem:last");
            galleryItem.append(url);
        }
        else
        {
            //File is not an FLV -> assume it is an image
            targetDiv.append("<div class='GalleryItem'></div>");
            galleryItem = targetDiv.find(".GalleryItem:last");
            galleryItem.append("<img src='" + url + "' alt=\"" + altText + "\" />");
        }
    }
    if (targetDiv.find(".Video").length > 0)
    {
        targetDiv.append("<div class='VideoPlayerContainer'></div>");
        videoPlayerContainer = targetDiv.find(".VideoPlayerContainer");
        videoPlayerContainer.append("<div id='VideoPlayer'><a href='http://www.adobe.com/go/getflashplayer'><img src='http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /></a></div>");
    }
    if (galleryItems.length > 1)
    {
        targetDiv.append("<div class='PrevButton disabled'></div><div class='PrevLink disabled'>PREV</div>");
        targetDiv.append("<div class='NextButton'></div><div class='NextLink'>NEXT</div>");
    }
}

// function: Bind events and open the popup
GlossaryPopups.OpenTermPopup = function () {
    var GP = GlossaryPopups,
        params = GP.Params,
        popup = $("#" + params.PopupID),
        closeButton = popup.find(".CloseButton"),
        prevButton = popup.find(".PrevButton"),
        prevLink = popup.find(".PrevLink"),
        nextButton = popup.find(".NextButton"),
        nextLink = popup.find(".NextLink"),
        gallery = popup.find(".Gallery"),
        listenLink = popup.find(".ListenLink"),
        closeButtonUrls = params.CloseButtonUrls,
        prevButtonUrls = params.PrevButtonUrls,
        nextButtonUrls = params.NextButtonUrls;
    
    // Bind close events:
    //close if anywhere on document is clicked
    $(document).one('click', GP.CloseTermPopup);
    //prevent click from bubbling to document if click was inside popup
    popup.unbind('click').bind('click', function () { 
        return false;
    });
    //...make links work despite the above cancellation of bubbling
    popup.find("a:not(.ListenLink)").unbind('click').bind('click', function () {
        location.href = $(this).attr("href"); 
        return false; 
    });
    closeButton.unbind("click").bind("click", GlossaryPopups.CloseTermPopup);
    // Bind image mouseovers
    closeButton.unbind("mouseover").bind("mouseover", function (e) {
        $(this).css("background-image", "url(" + closeButtonUrls.MouseOver + ")");
    }).unbind("mouseout").bind("mouseout", function (e) {
        $(this).css("background-image", "url(" + closeButtonUrls.Default + ")");
    }).unbind("mousedown").bind("mousedown", function (e) {
        $(this).css("background-image", "url(" + closeButtonUrls.MouseDown + ")");
    }).unbind("mouseup").bind("mouseup", function (e) {
        $(this).css("background-image", "url(" + closeButtonUrls.Default + ")");
    });
    prevButton.unbind("mouseover").bind("mouseover", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + prevButtonUrls.MouseOver + ")");
        }
    }).unbind("mouseout").bind("mouseout", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + prevButtonUrls.Default + ")");
        }
    }).unbind("mousedown").bind("mousedown", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + prevButtonUrls.MouseDown + ")");
        }
    }).unbind("mouseup").bind("mouseup", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + prevButtonUrls.Default + ")");
        }
    });
    
    nextButton.unbind("mouseover").bind("mouseover", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + nextButtonUrls.MouseOver + ")");
        }
    }).unbind("mouseout").bind("mouseout", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + nextButtonUrls.Default + ")");
        }
    }).unbind("mousedown").bind("mousedown", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + nextButtonUrls.MouseDown + ")");
        }
    }).unbind("mouseup").bind("mouseup", function (e) {
        if (!$(this).hasClass("disabled")) {
            $(this).css("background-image", "url(" + nextButtonUrls.Default + ")");
        }
    });
    
    //bind gallery events
    prevButton.bind('click', GP.PrevButton_Click);
    prevLink.bind('click', GP.PrevButton_Click);
    nextButton.bind('click', GP.NextButton_Click);
    nextLink.bind('click', GP.NextButton_Click);
    gallery.find(".GalleryItem:first").addClass("Active").show();
    
    //bind audio player events
    listenLink.bind('click', GP.ListenLink_Click)
    popup.show();
    
    GP.States.IsOpening = false;
    GP.States.IsOpen = true;
};

// function: Close the popup
GlossaryPopups.CloseTermPopup = function () {
    var popup = $("#" + GlossaryPopups.Params.PopupID);
    popup.hide();
    popup.html("");
    $(document).unbind('click');
    GlossaryPopups.States.IsOpen = false;
};

// function: Show the previous gallery item
GlossaryPopups.PrevButton_Click = function (e) {
    if (!$(this).hasClass("disabled"))
    {
        var GP = GlossaryPopups,
            popup = $("#" + GP.Params.PopupID),
            gallery = popup.find(".Gallery"),
            galleryItems = gallery.find(".GalleryItem"),
            activeItem = galleryItems.filter(".Active"),
            videoPlayerContainer = popup.find(".VideoPlayerContainer"),
            prevButton = popup.find(".PrevButton"),
            prevLink = popup.find(".PrevLink"),
            nextButton = popup.find(".NextButton"),
            nextLink = popup.find(".NextLink"),
            prevItem;
        
        activeItem.removeClass("Active").hide();
        videoPlayerContainer.hide();
        
//        prevItem = (galleryItems.index(activeItem) == 0) ? 
//                        galleryItems.filter(":last") : activeItem.prev();
        prevItem = activeItem.prev();
        prevItem.addClass("Active");
        if (galleryItems.index(prevItem) == 0)
        {
            prevButton.addClass("disabled");
            prevLink.addClass("disabled");
        }
        nextButton.removeClass("disabled");
        nextLink.removeClass("disabled");
        GP.ShowOrPlay(prevItem);
    }
};

// function: Show the next gallery item
GlossaryPopups.NextButton_Click = function (e) {
    if (!$(this).hasClass("disabled"))
    {
        var GP = GlossaryPopups,
            popup = $("#" + GP.Params.PopupID),
            gallery = popup.find(".Gallery"),
            galleryItems = gallery.find(".GalleryItem"),
            activeItem = galleryItems.filter(".Active"),
            videoPlayerContainer = popup.find(".VideoPlayerContainer"),
            prevButton = popup.find(".PrevButton"),
            prevLink = popup.find(".PrevLink"),
            nextButton = popup.find(".NextButton"),
            nextLink = popup.find(".NextLink"),
            nextItem;
        
        activeItem.removeClass("Active").hide();
        videoPlayerContainer.hide().empty().append("<div id='VideoPlayer'></div>");
        
//        nextItem = (galleryItems.index(activeItem) == galleryItems.length - 1) ? 
//                        galleryItems.eq(0) : activeItem.next();
        nextItem = activeItem.next();
        nextItem.addClass("Active");
        if (galleryItems.index(nextItem) == galleryItems.length - 1)
        {
            nextButton.addClass("disabled");
            nextLink.addClass("disabled");
        }
        prevButton.removeClass("disabled");
        prevLink.removeClass("disabled");
        GP.ShowOrPlay(nextItem);
    }
};

// function: Show this picture or play this video
GlossaryPopups.ShowOrPlay = function (jObj) {
    if (jObj.hasClass("Video"))
    {
        //this is a video -> show video player and load
        var popup = $("#" + GlossaryPopups.Params.PopupID),
            videoPlayerContainer = popup.find(".VideoPlayerContainer"),
            params = GlossaryPopups.Params;
            
        GlossaryPopups.EmbedSwf("VideoPlayer", "video_url", jObj.text(), params.VideoPlayerUrl, params.VideoPlayerWidth, params.VideoPlayerHeight);
        videoPlayerContainer.show();
    }
    else
    {
        //this is a photo -> show this
        jObj.show();
    }
};

// function (event): ListenLink has been clicked -> toggle audio player
GlossaryPopups.ListenLink_Click = function (e) {
    var GP = GlossaryPopups,
        params = GP.Params,
        audioPlayerContainer = $(".AudioPlayerContainer");
    if (audioPlayerContainer.is(":visible"))
    {
        audioPlayerContainer.empty().append("<div id='AudioPlayer'></div>").hide();    
    }
    else
    {
        GP.EmbedSwf("AudioPlayer", "audio_url", $(this).attr("href"), params.AudioPlayerUrl, params.AudioPlayerWidth, params.AudioPlayerHeight);
        audioPlayerContainer.show();
    }
    return false;
};

// function: Embed the SWF. Used to start playing a new file.
GlossaryPopups.EmbedSwf = function (targetID, urlParam, url, playerUrl, width, height) {
    var params = GlossaryPopups.Params,
        flashvars = {}, 
        flashParams, attributes;
    flashvars[urlParam] = url;
    flashParams = {
        allowfullscreen: true,
        wmode: "transparent",
        allowScriptAccess: "always"
    };
    attributes = {
        id: targetID,
        name: targetID
    };
    swfobject.embedSWF(playerUrl, targetID, width, height, "9.0.0", "", flashvars, flashParams, attributes);
}
