// File: global.js
// Requires: prototype.js

// *************************************** Class: MessagePanelController ***************************************
/*
* Note: Global instance name of MessagePanelController is 'controllerMessagePanel'
*/
// #### Class Declaration & Static Defn ####
var MessagePanelController = Object.extend(
    Class.create(),
    // Static Properties and Members
    {
        // Type Consts
        MSSG_TYPE_ERROR : "error",
        MSSG_TYPE_MESSAGE : "message"
    }
);
// #### Instance Defn ####
var controllerMessagePanel;
MessagePanelController.prototype = {
    panelIDPrefix : "album", // default

    initialize : function(panelIDPrefix, noScript)
    {
        this.panelIDPrefix = panelIDPrefix;

        var errorPanel = $(panelIDPrefix + "ErrorPanel");
        var elt, closers;
        closers = errorPanel.select("a","linkErrorPanelClose");

        if(closers.length > 1){
            elt = closers[0];
        }else{
            elt = closers.pop();
        }

        // handle error message panel close
        if(elt != null){
            Event.observe(elt, "click", this.handleCloseErrorClick.bindAsEventListener(this), false);
        }
        if(noScript){
            this.clearMessage();
        }
        controllerMessagePanel = this;
    },
    handleCloseErrorClick : function(evnt)
    {
        var errorPanel = $(this.panelIDPrefix + "ErrorPanel");
        var elt;
        if(errorPanel != null){
            errorPanel.className = ""; // Clear Class (state)

            var emc = errorPanel.select("span","panelErrorMessageContent");
            if(emc != null){
                emc.innerHTML = "";
            }

            var ed = errorPanel.select("div","panelErrorDetails");
            if(ed != null){
                ed.innerHTML = "";
                //Element.hide(ed); //cnguyen says: Not sure if we still need this now?!!
            }
            Element.hide(errorPanel);
        }
    },
    /* Method to manually set error/status messages via JS. Lightbox error panels may include identical ID divs as main page,
     * so we get the proper element using the errorPanel.select("tag#tagId) which returns an array.
     * If no type is defined, default is MessagePanelController.MSSG_TYPE_ERROR.
     * @params cfg JSON object with three possible string values:
     *               cfg.message=>the message appearing in the <h1> tags
     *               cfg.details=>additional details to display
     *               cfg.type=>message type (MessagePanelController.MSSG_TYPE_ERROR, MessagePanelController.MSSG_TYPE_MESSAGE)
     */
    printMessage: function(cfg){
        var errorPanel, messagePanel, detailsPanel;
        var message, details;
        var type = MessagePanelController.MSSG_TYPE_ERROR;//default
        if(typeof(cfg)=="object"){
            if(typeof(cfg.message)=="string") message = cfg.message;
            if(typeof(cfg.details)=="string") details = cfg.details;
            if(typeof(cfg.type)=="string") type = cfg.type;
        }

        errorPanel = $(this.panelIDPrefix + "ErrorPanel");
        if(typeof(errorPanel)!="undefined"){
            errorPanel.className = "";
            Element.addClassName(errorPanel, "panel" + type.capitalize());

            // Set Main Message
            if(message){
                if((messagePanel = errorPanel.select("span","panelErrorMessageContent").pop()) != null){
                    messagePanel.innerHTML = message;
                }
            }
            // Set Details Message
            if(details){
                if((detailsPanel = errorPanel.select("div","panelErrorDetails").pop()) != null){
                    detailsPanel.innerHTML = details;
                    Element.show(detailsPanel);
                }
            }
            Element.show(errorPanel);
            if((elt = $("userMessagePanel")) != null){
                elt.toggle();
            }
        }
    },
    clearMessage : function()
    {
        var errorPanel, messagePanel, detailsPanel;
        if((errorPanel = $(this.panelIDPrefix + "ErrorPanel")) != null){
            errorPanel.className = "";

            // Clear Main Message
            if((messagePanel = errorPanel.select("span","panelErrorMessageContent").pop()) != null){
                messagePanel.innerHTML = "";
            }
            // Clear Details Message
            if((detailsPanel = errorPanel.select("div","panelErrorDetails").pop()) != null){
                detailsPanel.innerHTML = "";
                Element.hide(detailsPanel);
            }

            if((elt = $("userMessagePanel")) != null){
                elt.toggle();
            }
        }

        Element.hide(this.panelIDPrefix + "ErrorPanel");
    },
    setPaneIDPrefix: function(idPrefix){
        this.panelIDPrefix = idPrefix;
    }
};
// ************************************* END - Class: MessagePanelController ************************************


// ****************************************** Global Proceedures *********************************************
// For tracking code clicks

function trackCopyCodeClick(track, isSponsored) {
    APIRequest.track(track);
    if ((isSponsored === true)||(isSponsored === "true")) {
        APIRequest.track('sponsored_slideshow_click');
    }
}

// For tracking click events on image codes in ALBUMS
function trackCodeClick(evnt,mType,isSponsored) {
    var elt = Event.element(evnt);
    if(mType == "adobeexpress") {
        mType = "remix";
    }
    if(elt) {
        var code = elt.value;

        if(code.match(/^http:/)) {
            if(code.match(/albumview=grid$/)) {
                // Track Album Share
                APIRequest.track('image_code_click_SHARE_ALBUM_GRID');
            } else if(code.indexOf("?") > -1) {
                // Track Share url
                APIRequest.track('image_code_click_ALBUM_SHARE_URL');
            } else {
                // Track Direct url
                APIRequest.track('image_code_click_ALBUM_URL_LINK');
            }
        } else if(code.match(/^<img src=/) || code.match(/^<embed/) || code.match(/^<a href=/)) {
            // Track HTML Url
            APIRequest.track('image_code_click_ALBUM_HTML');
        } else if(code.match(/^\[URL=http:/) || code.match(/^\[IMG\]http:/)) {
            // Track IMG url
            APIRequest.track('image_code_click_ALBUM_IMG');
        }
    }
    if(isSponsored == 1) {
            APIRequest.track('sponsored_slideshow_click');
    }
    return true;
}

// For tracking click events on image codes in FULLVIEW
function trackCodeClickFullview(evnt,mType,isSponsored) {
    var elt = Event.element(evnt);
    if(mType == "adobeexpress") {
        mType = "remix";
    }
    if(elt) {
        var code = elt.value;

        if(code.match(/^http:/)) {
            if(code.indexOf("?") > -1) {
                // Track Share url
                APIRequest.track('image_code_click_FULLVIEW_SHARE_URL');
            } else {
                // Track Direct url
                APIRequest.track('image_code_click_FULLVIEW_URL_LINK');
            }
        } else if(code.match(/^<img src=/) || code.match(/^<embed/) || code.match(/^<a href=/)) {
            // Track HTML Url
            APIRequest.track('image_code_click_FULLVIEW_HTML');
        } else if(code.match(/^\[URL=http:/) || code.match(/^\[IMG\]http:/)) {
            // Track IMG url
            APIRequest.track('image_code_click_FULLVIEW_IMG');
        } else if(code.match(/^<table border=/)) {
            // Track FLASH url
            APIRequest.track('image_code_click_FULLVIEW_FLASH');
        }
    }
    if(isSponsored == 1) {
            APIRequest.track('sponsored_slideshow_click');
    }
    return true;
}



// For tracking click events on image codes in MEDIADETAIL
function trackCodeClickMediaDetail(evnt,mType,isSponsored) {
    var elt = Event.element(evnt);
    if(mType == "adobeexpress") {
        mType = "remix";
    }
    if(elt) {
        var code = elt.value;
/*
Share and Direct Url Forms from media detail:
    Album:
        Share: http://media.photobucket.com/image/jessica%20alba/rocketshoe22/jessica-alba-.jpg
        Link: http://i518.photobucket.com/albums/u346/rocketshoe22/jessica-alba-.jpg
    Group:
        Share: http://photobucket.com/group/image/jessica%20alba/6J7N36CXP6/jessica-alba.jpg
        Link: http://gi75.photobucket.com/groups/i309/6J7N36CXP6/jessica-alba.jpg
*/
        if(code.match(/^http:/)) {
            var path = code.split("/");

            if(path[3] == "groups" || path[3] == "albums") {
                // Track Direct url
                APIRequest.track('image_code_click_MEDIADETAIL_URL_LINK');
            } else {
                // Track Share url
                APIRequest.track('image_code_click_MEDIADETAIL_SHARE_URL');
            }
        } else if(code.match(/^<img src=/) || code.match(/^<embed/) || code.match(/^<a href=/)) {
            // Track HTML Url
            APIRequest.track('image_code_click_MEDIADETAIL_HTML');
        } else if(code.match(/^\[URL=http:/) || code.match(/^\[IMG\]http:/)) {
            // Track IMG url
            APIRequest.track('image_code_click_MEDIADETAIL_IMG');
        } else if(code.match(/^<table border=/)) {
            // Track FLASH url
            APIRequest.track('image_code_click_MEDIADETAIL_FLASH');
        }
    }
    if(isSponsored == 1) {
            APIRequest.track('sponsored_slideshow_click');
    }
    return true;
}

//Start new tracking handler//
var trClicksOnPage = new Hash();
/*
 * Note: Now using implicit arguments array, so we can set multiple tracking keys in one call (ndemos, R18.4).
 * Ex: tr('key0'[, 'key1'][, ...]);
 */
function tr(/*arguments*/) {
    for(var i = 0; i < arguments.length; i++){
        var name = arguments[i];
        if(typeof(name) == "string" && name){
    name = name.toLowerCase().substring(0,128).replace(/[ -]/g,'_');
    name = name.replace(/['"\/|\\!\?\.]/g,'');
    name = name.replace(/[&]/g,'and');
        var v = trClicksOnPage.get(name);
    v = (typeof(v) == 'number') ? v+1 : 1;
    trClicksOnPage.set(name, v);
    createCookie('pbtr',trClicksOnPage.toJSON(),365);
    }
    }
}//end tr()
//End new tracking handler//

// Requires: prototype.js, scriptaculous.js?load=effects
function copyToClipboard(elt) {
    var flashVersionGTNine = false;
    var cacheBuster = Math.floor(Math.random()*10001);
    try {
        var fo = new SWFObject("/include/swf/_clipboard.swf?cb="+cacheBuster,"detectFlashObj",1,1,"9.0.0");
        if (fo.installedVer.major > 9) flashVersionGTNine = true;
    } catch(e) {}

    if(!flashVersionGTNine) {
    var urlSwf = "/include/swf/_clipboard.swf";
    var strMssgBoxId = "notifyTextCopied";

    // Copy the text inside the text box to the user's clipboard
    var flashcopier = 'flashcopier';
    if(!$(flashcopier)){
        var divholder = document.createElement('div');
        divholder.id = flashcopier;
        document.body.appendChild(divholder);
    }

    $(flashcopier).innerHTML = '';
    var divinfo = '<embed src="' + urlSwf + '" FlashVars="clipboard='+escape(elt.value)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
    $(flashcopier).innerHTML = divinfo;
    copyToClipboardEffect(elt);
    }

    elt.select();
    return true;
}

function copyToClipboardExternal(name, track, isSponsored) {
   var elt = $(name);
   copyToClipboardEffect(elt);
   trackCopyCodeClick(track, isSponsored);
}

function copyToClipboardEffect(elt) {
    var strMssgBoxId = "notifyTextCopied";
    var parent = Element.up(elt);
    var eltNotify = document.createElement('div');
        eltNotify.setAttribute('id', strMssgBoxId);
    eltNotify.appendChild(document.createTextNode("Copied"));
    parent.appendChild(eltNotify);

    elt.onblur =
        function(e){
            Element.hide(eltNotify);
            return true;
        }

    var cumOffset = Element.cumulativeOffset(elt);
    var offset = Element.positionedOffset(elt);

    Element.show(eltNotify);

    if (cumOffset.left < (eltNotify.offsetWidth + 2)) {
        // display 'copied' on right
        eltNotify.style.left = (offset.left + (elt.offsetWidth + 3)) + 'px';
    } else {
        // display 'copied' on left
        eltNotify.style.left = (offset.left - (eltNotify.offsetWidth + 2)) + 'px';
        }

    eltNotify.style.top = offset.top + 'px';

    var xEffect = Effect.Fade(eltNotify,
        {
            fps: 75,
            from: 1.9,
            to: 0.0,
            duration: 1.0,
            queue: 'front',
            afterFinish: function() {
                Element.remove(eltNotify);
            }
        }
    );
    window.status = 'Copied text to clipboard';
    return true;
}


// fireMouseEvent synthesises a mouse event on an element
// usage: fireMouseEvent($('someid'), 'click');

function fireMouseEvent(elt, strEvent, bubbles, cancelable)
{

    var bBubbles = false, bCancelable = true;
    if(typeof(bubbles) == "boolean"){
        bBubbles = bubbles;
    }
    if(typeof(cancelable) == "boolean"){
        bCancelable = cancelable;
    }

    // Note: strEvent = Event name w/o "on" prefix (Ex: "click")
    if(typeof(elt) != "undefined" && elt && typeof(strEvent) == "string" && strEvent.length > 0){
        var objEvnt; // Synthetic Event Obj
        // Sythesize Click event
        if(document.createEvent){    // W3C
            objEvnt = document.createEvent('MouseEvents');
            objEvnt.initEvent(strEvent, bBubbles, bCancelable);
            elt.dispatchEvent(objEvnt);
        }
        else if(document.createEventObject){ // MSIE
            objEvnt = document.createEventObject();    // copy the original event to the new event object
            elt.fireEvent('on' + strEvent, objEvnt);
        }
    }
}

function magickAdRender(divName, aambTag) {
    var eltAdTarget;
    var invObj = 'INV' + divName;

    if((eltAdTarget = document.getElementById(divName)) != null){
        try{
            var code = aambTag;
        }
        catch(aamErr){
        }

        if(typeof(code) != 'undefined'){
            var msieIdx = navigator.userAgent.indexOf('MSIE');
            if(msieIdx > -1){
                var ifrString = '<iframe name="' + invObj + '" width="0" height="0" frameborder="0" AAM_EVENT="javascript:try { document.getElementById(\'' + divName + '\').insertAdjacentElement(\'beforeEnd\', window.frames[\'' + invObj + '\'].document.getElementById(\'adDiv\')) } catch(aamErr) { }"></iframe>';
                eltAdTarget.innerHTML += '<div id="TMP' + divName + '" style="display:none">' + escape('<body><div id="adDiv">' + code + '</div>') + '</div>' + ifrString.replace(/AAM_EVENT/, 'onload');
                window.frames[invObj].document.location = 'javascript:unescape(parent.document.getElementById(\'TMP' + divName + '\').innerHTML)';
            }
            else{
                document.writeln('<div id="' + invObj + '" style="display:none">' + code + '<script type="text/javascript" defer="true">document.getElementById(\'' + divName + '\').innerHTML = document.getElementById(\'' + invObj + '\').innerHTML;document.getElementById(\'' + invObj + '\').innerHTML = \'\';</scr' + 'ipt></div>');
            }
        }
    }
}

function showToRightOfElement(baseElemId, posElemId, extraX, extraY) {

    if (!extraX) extraX = 0;
    if (!extraY) extraY = 0;

    var baseElem = $(baseElemId);
    var posElem = $(posElemId);

    var offsetTrail = baseElem;
    var offsetLeft = 0;
    var offsetTop = 0;

    // account for IE6 CSS compatibility mode
    while (offsetTrail) {
        offsetLeft += offsetTrail.offsetLeft;
        offsetTop += offsetTrail.offsetTop;
        offsetTrail = offsetTrail.offsetParent;
    }

    if (navigator.userAgent.indexOf("Mac") != -1 &&
        typeof document.body.leftMargin != "undefined") {
        offsetLeft += document.body.leftMargin;
        offsetTop += document.body.topMargin;
    }

    posElem.style.left = offsetLeft + parseInt(baseElem.offsetWidth) + extraX + "px";
    posElem.style.top = offsetTop + extraY + "px";

    Element.show(posElem);
}


// Class Definition
ShowHideRegistry = Class.create();
ShowHideRegistry.prototype = {

    eltHash : null,

    initialize: function() {
        this.eltHash = new Hash();
    },

    add: function(id) {
        var elt;
        if (!this.eltHash[id] && (elt = $(id)) != null) this.eltHash.set(id, elt);
    },

    remove: function(id) {
        if (this.eltHash[id]) this.eltHash.remove(id);
    },

    hideAllVisibility: function() {
        this.eltHash.each(function(pair) { pair.value.style.visibility = 'hidden'; });
    },

    hideAllDisplay: function() {
        this.eltHash.each(function(pair) { Element.hide(pair.value); });
    },

    hideAllVisibleUnder: function(elt) {
        var eltOver = $(elt);
        var overPos = Position.cumulativeOffset(eltOver);
        var overDimensions = eltOver.getDimensions();

        this.eltHash.each(this.checkVisibility_Closure(overPos, overDimensions).bind(this));
    },

    checkVisibility_Closure: function(overPos, overDim) {
        return function(pair) {
            var underPos = Position.cumulativeOffset(pair.value);
            var underDim = pair.value.getDimensions();

            if (!(overPos[0] > (underPos[0] + underDim.width) ||
                  (overPos[0] + overDim.width) < underPos[0] ||
                  overPos[1] > (underPos[1] + underDim.height) ||
                  (overPos[1] + overDim.height) < underPos[1]))
                pair.value.style.visibility = 'hidden';
        };
    },

    showAllVisibility: function() {
        this.eltHash.each(function(pair) { pair.value.style.visibility = 'visible'; });
    },

    showAllDisplay: function() {
        this.eltHash.each(function(pair) { Element.show(pair.value); });
    },

    toggleAllVisibility: function() {
        this.eltHash.each(function(pair) { Element.toggle(pair.value); });
    }
};

var flashRegistry = new ShowHideRegistry();


function translateAjaxResponse(response)
{
    var jsonResp = null;

    if(response && typeof(response.responseText) != "undefined" && response.responseText){
        var json = eval('(' + response.responseText + ')');
        jsonResp = (json && typeof(json.response) == "object" ? json.response : null);
    }
    return jsonResp;
}

function getEltOffsetPos(elt, eltAncestor)
{
    var offLeft = elt.offsetLeft, offTop = elt.offsetTop;

    if(eltAncestor){
        var eltCurr = elt;

        while((eltCurr = eltCurr.offsetParent) != null && eltCurr != eltAncestor){// && eltCurr != document
            offLeft += eltCurr.offsetLeft;
            offTop += eltCurr.offsetTop;
        }
    }

    return {left : offLeft, top: offTop};
}

function viewContactsWindow(url, bReturnChildWindow)
{
    var height = 550;
    var width = 750;
    var LeftPosition = (screen.width) ? (screen.width - width) / 2 : 0;
    var TopPosition = (screen.height) ? (screen.height - height) / 2 : 0;
    var settings = 'height=450, width=620, top=' + TopPosition + ', left=' + LeftPosition + ', menubar=no, location=no, resizable=yes, scrollbars=yes, status=no, titlebar=no';
    var win = window.open(url, "ModifyContacts", settings)
    if(win.window.focus){
        win.window.focus();
    }
    if(typeof(bReturnChildWindow) == "boolean" && bReturnChildWindow){
        return win;
    }
}

function detectJavaScriptSupportChange()
{
    var change = false;
    // safely check for the nojs cookie.  remove if it's found.
    // depends on cookie.js
    if (typeof readCookie == "function" && typeof createCookie == "function")
    {
        var nojscookiename = "nojs";
        if (readCookie(nojscookiename) != null)
        {
            createCookie(nojscookiename, "", -1);
            change = true;
        }
    }
    // save the state in the photobucket obj
    if (photobucket) {
        photobucket.jsSupportChanged = change;
    }
}
// delay call so cookie.js can load
Event.observe(window, "load", detectJavaScriptSupportChange);

/* Static object for global definitions */
var photobucket = {
    browser: {
        isIE : (navigator.userAgent.indexOf("MSIE") != -1),
        isIE6 : (navigator.userAgent.indexOf("MSIE 6") != -1),
        isIE7 : (navigator.userAgent.indexOf("MSIE 7") != -1),
        isSafari : (navigator.userAgent.indexOf("AppleWebKit") != -1),
        isFirefox : (navigator.userAgent.indexOf("Firefox") != -1),
        isOpera : (navigator.userAgent.indexOf("Opera") != -1)
    },

    ui : {

        // -----------------------------------------------------------------------------------
        //
        // getPageScroll()
        // Returns object with x,y page scroll values.
        // Core code from - quirksmode.org
        //
        getPageScroll: function(){

            var yScroll;

            if (self.pageYOffset) {
                yScroll = self.pageYOffset;
            } else if (document.documentElement && document.documentElement.scrollTop){     // Explorer 6 Strict
                yScroll = document.documentElement.scrollTop;
            } else if (document.body) {// all other Explorers
                yScroll = document.body.scrollTop;
            }

            pageScrollObj = {
                'xScroll': null,
                'yScroll': yScroll
            };
            return pageScrollObj;
        },

        // -----------------------------------------------------------------------------------
        //
        // getPageSize()
        // Returns object with page width, height and window width, height
        // Core code from - quirksmode.org
        // Edit for Firefox by pHaez
        //
        getPageSize: function(){

            var xScroll, yScroll;

            if (window.innerHeight && window.scrollMaxY) {
                xScroll = document.body.scrollWidth;
                yScroll = window.innerHeight + window.scrollMaxY;
            } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
                xScroll = document.body.scrollWidth;
                yScroll = document.body.scrollHeight;
            } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
                xScroll = document.body.offsetWidth;
                yScroll = document.body.offsetHeight;
            }

            var windowWidth, windowHeight;
            if (self.innerHeight) {    // all except Explorer
                windowWidth = self.innerWidth;
                windowHeight = self.innerHeight;
            } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
                windowWidth = document.documentElement.clientWidth;
                windowHeight = document.documentElement.clientHeight;
            } else if (document.body) { // other Explorers
                windowWidth = document.body.clientWidth;
                windowHeight = document.body.clientHeight;
            }

            // for small pages with total height less then height of the viewport
            if(yScroll < windowHeight){
                pageHeight = windowHeight;
            } else {
                pageHeight = yScroll;
            }

            // for small pages with total width less then width of the viewport
            if(xScroll < windowWidth){
                pageWidth = windowWidth;
            } else {
                pageWidth = xScroll;
            }

            pageSizeObj = {
                'pageWidth': pageWidth,
                'pageHeight': pageHeight,
                'windowWidth': windowWidth,
                'windowHeight': windowHeight

            };
            return pageSizeObj;
        },

        setButtonDisabled: function(eltBttn, bDisabled) {
            if(eltBttn){
                eltBttn.disabled = bDisabled;
                if(bDisabled){
                    Element.addClassName(eltBttn, "button_disabled")
                }
                else{
                    Element.removeClassName(eltBttn, "button_disabled")
                }
            }
        },

        loadScript: function(url) {
            var e = document.createElement("script");
            e.src = url;
            e.type="text/javascript";
            document.getElementsByTagName("head")[0].appendChild(e);
        }

    }
}

function getDocumentUrl() {
    var url = document.location.href;
    url = url.split("?")[0];
    url = url.split("#")[0];
    return url;
}

function cookieReader(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return '';
}

function createCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        expires = "; expires="+date.toGMTString();
    }

    document.cookie = name+"="+escape(value)+expires+"; path=/; domain= .photobucket.com";
}
/*
 *
 */
function createCookieByUnixTimestamp(name,value,unixTime) {
    var expires = "";
    if(unixTime){
        var objdate = new Date();
        objdate.setTime(unixTime*1000);// Convert PHP Unix Epoch (secs) to UTC time (milliseconds)
        expires = "; expires="+objdate.toGMTString();
    }
    document.cookie = name+"="+escape(value)+expires+"; path=/; domain= .photobucket.com";
}

function disableTextHighlight(elem){
    if (typeof(elem.onselectstart)!="undefined")
        elem.onselectstart=function(){return false}
    else if (typeof(elem.style.MozUserSelect)!="undefined")
        elem.style.MozUserSelect="none"
    else
        elem.onmousedown=function(){return false}
    elem.style.cursor = "default"
}

//-----------------------------------------------------------------------------
// String Utility Functions ---------------------------------------------------
//-----------------------------------------------------------------------------

// hack gotten from the internet ...
// returns the width of a string in pixels
// modified slightly to support setting of the css class name to measure width
// in the correct font and allow for selection of element in which the temporary
// span used to measure width is created
function getStringWidth(text, stylename, elementId)
{
    //------------------------------------------------------------
    // create a span element and put the string to measure into it
    //------------------------------------------------------------
    var spanElement = document.createElement("span");
    if (stylename)
        spanElement.className=stylename;
    spanElement.style.whiteSpace = "nowrap";
    spanElement.innerHTML = text;

    //-----------------------------------------------------------------------
    // if parent element in which to place the span element wasn't specified,
    // fall back on the element expected to be placed in the document by
    // headermeata.tpl
    //-----------------------------------------------------------------------
    if (elementId == null)
        elementId = 'stringWidthMeasure';

    var spanParent = $(elementId);
    spanParent.appendChild(spanElement);
    var width = spanElement.offsetWidth;
    spanParent.removeChild(spanElement);
    return width;
}

// truncates a string at the specified number of pixels of by measuring the string's width
// in pixels (given the specified css style class name) and
//
// - returning it immediately if it already fits within maxwidth pixels
// - performing a binary search for the truncation spot repeatedly measuring the
//   string each iteration
// - adding '...' to the truncated string (the dots' width is accounted for)
//
// parameters:
//
// - caption: the string to be truncated to fit within maxwidth pixels
// - maxwidth: maximum number of pixels caption may occupy
// - stylename: the css class name(s) with which the string will be output (to measure
//              it using the correct font)
function truncateToPixels(caption, maxwidth, stylename, elementId)
{
    //-------------------------------------------------------------------------------
    // measure initial string, and return it if it's short enough after it's rendered
    // (this should be the norm)
    //-------------------------------------------------------------------------------
    if (getStringWidth(caption, stylename, elementId) <= maxwidth)
        return caption;

    //--------------------------------------------------------------------------
    // if it didn't fit to begin with, it will truncated and '...' will be added
    // determine how wide the dots will be and remove that from maximum width
    // (intentionally remove an extra dot's worth of space to be conservative)
    //--------------------------------------------------------------------------
    maxwidth -= getStringWidth('....', stylename, elementId);

    //-----------------------------------
    // search for the truncation location
    //-----------------------------------
    var lo = 1;
    var hi = caption.length;
    var middle = (lo + hi) / 2;
    while (hi - lo > 1) {
        if (getStringWidth(caption.substring(0, middle), stylename, elementId) <= maxwidth)
            lo = middle;
        else
            hi = middle;
        middle = (lo + hi) / 2;
    }

    //---------------------------------------------------------------
    // start with truncation at the high end, stripping (at most two,
    // none if it already fits) characters until the string fits
    //---------------------------------------------------------------
    caption = caption.substring(0, hi);
    while (getStringWidth(caption, stylename, elementId) > maxwidth && caption.length > 0)
        caption = caption.substring(0, caption.length - 1);
    return caption + '...';
}

// computes HTML for an anchor inclusive of a counter in a span tag (output only if
// it's a positive integer - prefixed with '+' if so).  Truncates the anchor's caption
// (if necessary) as to fit both the truncated caption and the counter within the
// specified maxwdith pixels
//
// - caption: string to use for anchor's caption
// - title: tool tip do display for the counter
// - href: anchor's href attribute
// - count: count to output in the span element
// - maxwdith: maximum width (in pixels) available to both anchor and counter
// - stylename: css class name(s) with which the anchor will be output (so string can
//              be measured in the correct font)
// - counterstylename: optional css class name(s) with which counter <span> tag is output
//                     (assigned to span's class attribute, and used to measure counter's
//                     width using the correct font) - defaults to 'xBox xBoxTheme'
// - onclickhandler: optional onclick code to include in the anchor
// - elementId: optional document element in which to measure strings - if not specified
//              a hidden div created by headermeta.tpl (stringWidthMeasure) will be used
//
// TODO: currently only used in album modules - Nick said he could see this function go
//       into either global.js or albummodule.js ... put here cuz I'm that lazy
function computeCountedAnchor(caption, title, href, count, maxwidth,
                              stylename, counterstylename, onclickhandler, elementId)
{
    //-----------------------------------------------------------------------
    // compute the counter's caption and its width (if it's a non-zero count)
    //-----------------------------------------------------------------------
    var counterstyle = counterstylename != null ? counterstylename : 'xBox xBoxTheme';
    var countercaption = "+" + count;
    var counterwidth = count > 0 ? getStringWidth(countercaption, counterstyle, elementId) : 0;

    //---------------------------------------------------------------------
    // truncate the caption if necessary (acommodating the counter's width)
    //---------------------------------------------------------------------
    caption = truncateToPixels(caption, maxwidth - counterwidth, stylename, elementId);

    //-------------------------------------------------------------------------------------------
    // append a trailing slash to urls that do not have querystrings or anchors (see trac#: 9181)
    //-------------------------------------------------------------------------------------------
    if(!href.include("?") && !href.include("#") && !href.endsWith("/")) href += "/";

    //------------------------------------------------------
    // compute the opening anchor tag and append the caption
    //------------------------------------------------------

    // adding ascending sort to all subscription links as per #9438
    var ascending = '?sort=ascending';

    var a = '<a href="' + href + ascending + '"';
    if (stylename != null)
        a = a + ' class="' + stylename + '"';
    if (title != null)
        a = a + ' title="' + title + '"';
    if (onclickhandler != null)
        a = a + ' onclick="' + onclickhandler + '"';
    a = a + '>' + caption;

    //-----------------------------------------
    // add the counter <span> tag (if positive)
    //-----------------------------------------
    if (count > 0)
        a = a + '<span class="' + counterstyle + '">' + countercaption + '</span>';

    //-----------------
    // close the anchor
    //-----------------
    a = a + '</a>';
    return a;
}

function promptRemix(url) {
    if(url == '') var url = window.location.href.split("?")[0];
    document.fire(PBLightbox.EVENT.ACTIVATE, {contentUrl: url+'?action=interstitial&secondary_action=remix'});
}
