if (typeof(jQuery) != 'function') {  $ = function() {return {'ready':function(){}}} }
//if (!window.console) {  console = {'log':function(){},'dir':function(){}};  }
(function(){
var debugok = 0;
;;;  debugok = window.console && window.console.log && typeof(window.console.log.apply) == 'function' ? 1:0;
if (debugok) { window.$log = function(){ console.log.apply( console, arguments ) }; }
else { window.$log = function(){}; }
})();

createNamespace('WF');

function addObjectEventListener(o, e, fn) { if (typeof fn == 'string') {fn = new Function('evt',fn)} $(o).bind(e,fn) }

function buildElement(elproto) {
    var el;
    if (elproto.t) {
        el = document.createTextNode(elproto.t);
    }
    else {
        el = document.createElement(elproto.e);
        if (elproto.h) {
            el.innerHTML = elproto.h;
        }
        else {
            for (var attribute in elproto.a) {
                el.setAttribute(attribute,elproto.a[attribute]);
            }
            if (elproto.cl) { el.className = elproto.cl; }
            for (var event in elproto.ev) {
                //addObjectEventListener(el,event,elproto.ev[event]);
                el[event] = elproto.ev[event];
            }
        }
    }
    return el;
}

function buildElementTree(elproto) {
    if (!document.getElementById) {return;}
    var el = buildElement(elproto);
    for (var childproto in elproto.c) {
        el.appendChild(buildElementTree(elproto.c[childproto]));
    }
    return el;
}

function removechildren(el) {  el.innerHTML = ''  }

function createNamespace(s, o) {
    var ns = s.split('.'),
        i,
        len;
    o = o || window;
    for (i=0, len=ns.length; i<len; i++) {
        o = o[ns[i]] = o[ns[i]] || {};
    }
    return o;
}

function parenthref(url) {
    if (opener !== null  &&  typeof(opener.location.href) == "string") {
        opener.location.href = url;
        opener.window.focus();
    } else {
        window.open(url,"newwefunkwindow");
    }
}

var timers = {
    showelement:{},
    hideelement:{}
};

function handleElementKeepVisible(event) {
    event.stopPropagation();
    var id = event.data.id;
    event.data.fadeInSpeed = event.data.fadeInSpeed || 200;
    window.clearTimeout(timers.hideelement[id]);
    timers.hideelement[id] = -1;
    var el = $('#'+id);
    var eldisplay = el.css('display');
    if (eldisplay == 'none' || parseFloat(el.css('opacity')) < 1) {
        if (eldisplay == 'none') { el.css({opacity:0,display:'block'}) }
        el.stop().animate({opacity:1},event.data.fadeInSpeed);
    }
}

function handleElementSetFade(event) {
    event.data = event.data || {};
    event.data.fadeDelay = event.data.fadeDelay || 800;
    event.data.fadeOutSpeed = event.data.fadeOutSpeed || 1000
    var thisid = event.data.id;
    thisid = thisid || 'learnown';
    if (timers.hideelement[thisid] < 0  ||  typeof(timers.hidelement[thisid]) == 'undefined') {
        timers.hideelement[thisid] = window.setTimeout(function(){$('#'+thisid).fadeOut(event.data.fadeOutSpeed);},event.data.fadeDelay);
        window.clearTimeout(timers.showelement[thisid]);
    }
}


/* **************************** WFHover ************************ */

(function($){
    // private functions
    var o_defaults = {
        timerShow: null,
        timerHide: null,
        fadeInDelay: 300,
        fadeInSpeed: 200,
        fadeOutDelay: 800,
        fadeOutSpeed: 1000,
        state:0
    };

    function handleSetFadeIn(event) {
        event.target.blur();
        var id = event.data.id;
        var eltarget = $('#'+id);
        if (eltarget.length < 1) { return false; }
        var targetdata = eltarget.data('WFHover');
        if (targetdata) {
            window.clearTimeout(targetdata.timerHide);  // clear any active hide timer
            targetdata.timerHide = null;
            var interaction = event.data.interaction || 'hover';

            if (targetdata.state == 0  && event.data.interaction == 'hover') {
                startFadeInDelay(eltarget,targetdata,event.data.eltrigger);
            } else {
                startFadeIn(eltarget,targetdata,event.data.eltrigger);
            }
        }
        return false;
    }

    function handleSetFadeOut(event) {
        //event.stopPropagation();
        var id = event.data.id;
        var eltarget = $('#'+id);
        if (eltarget.length < 1) { return false; }
        var targetdata = eltarget.data('WFHover');
        if (targetdata) {
            //console.log('handleSetFadeOut: ',targetdata.state, id,eltarget,targetdata);

            // if there is an active hide timer, clear it
            window.clearTimeout(targetdata.timerShow);
            targetdata.timerShow = null;
            if (targetdata.state == 4) { targetdata.state = 0; }

            switch (targetdata.state) {
                case 2:
                    startFadeOutDelay(eltarget,targetdata);
                    break;
                case 5:
                    startFadeOutDelay(eltarget,targetdata);
                    break;
                case 6:
                    startFadeOutDelay(eltarget,targetdata);
                    break;
                //default:
                //    console.log('omitting startFadeOutDelay() because state=',targetdata.state);
            }
            //return false;
        }
    }

    function handleKeepVisible(event) {
        // is this necessary?
        //event.stopPropagation();
        var id = event.data.id;
        var eltarget = $('#'+id);
        if (eltarget.length < 1) { return false; }
        var targetdata = eltarget.data('WFHover');
        if (targetdata) {
            if (targetdata.state == 0) { return false; }

            window.clearTimeout(targetdata.timerHide); // clear any active hide timer
            targetdata.timerHide = null;

            var doFade = (targetdata.state <= 1);

            if (doFade) {
                startFadeIn(eltarget,targetdata);
            }
        }
    }

    function handleFadeInComplete() {
        var targetdata = $(this).data('WFHover');
        if (targetdata) { targetdata.state = 6 }
    }

    function handleFadeOutComplete() {
        var targetdata = $(this).data('WFHover');
        if (targetdata) { targetdata.state = 0 }
    }

    function startFadeInDelay(eltarget,targetdata,eltrigger) {
        targetdata.state = 4;
        targetdata.timerShow = setTimeout(function(){startFadeIn(eltarget,targetdata,eltrigger)}, targetdata.fadeInDelay);
    }

    function startFadeIn(eltarget,targetdata,eltrigger) {
        if (eltrigger) {
            eltrigger.trigger('WFHoverStartFadeIn', [{'eltarget':eltarget, 'eltrigger':eltrigger, 'targetdata':targetdata}]);
            targetdata.lastTrigger = eltrigger;
        } else {
            targetdata.lastTrigger = null;
        }
        if (targetdata.state >= 5 && !targetdata.animate) { return; }
        if (targetdata.preventFadeIn) { targetdata.preventFadeIn = null; return; }
        var isVis = targetdata.state == 6 || targetdata.state == 2;
        //console.log('startFadeIn(5): ',targetdata.state, eltarget,targetdata);
        targetdata.state = 5;
        if (eltarget.css('display') == 'none') {
            eltarget.css({'opacity':0,'display':'block'});
        }
        var animCss = $.extend({opacity:1},targetdata.animate);
        targetdata.animate = null;
        var fadeInSpeed = (isVis && targetdata.fadeInSpeedWhenVisible != null)?
                targetdata.fadeInSpeedWhenVisible : targetdata.fadeInSpeed;
        //console.log('animCSS=',animCss);
        eltarget.stop(true).animate(animCss,fadeInSpeed,handleFadeInComplete);
    }

    // 0 hidden, 1 fading out, 2 fadeout delay, 4 fadein delay, 5 fading in, 6 visible
    function startFadeOutDelay(eltarget,targetdata) {
        targetdata.state = 2;
        targetdata.timerHide = setTimeout(function(){startFadeOut(eltarget,targetdata)}, targetdata.fadeOutDelay);
    }

    function startFadeOut(eltarget,targetdata) {
        if (targetdata.lastTrigger) { targetdata.lastTrigger.trigger('WFHoverStartFadeOut', [{'eltarget':eltarget, 'eltrigger':targetdata.lastTrigger, 'targetdata':targetdata}]); }
        targetdata.state = 1;
        targetdata.lastTrigger = null;
        eltarget.stop(true).fadeOut(targetdata.fadeOutSpeed,handleFadeOutComplete);
    }

    $.fn.extend({

        WFHoverTargetInit: function(o) {
            //Iterate over the current set of matched elements
            return this.each(function() {
                var eltarget = $(this);
                var targetid = eltarget.attr('id');
                var targetdata = $.extend({},o_defaults,o);
                eltarget.data('WFHover',targetdata);
                eltarget.bind('mouseover',{id:targetid},handleKeepVisible);
                eltarget.bind('mouseout',{id:targetid},handleSetFadeOut);
            });
        },

        WFHoverTriggerInit: function(o) {
            //Iterate over the current set of matched elements
            var eltarget = $('#'+o.target);
            var targetdata = eltarget.data('WFHover');
            var fadeInEvent = o.interaction || 'mouseover';
            return this.each(function() {
                var eltrigger = $(this);
                if (o.keepVisOnly) {
                    eltrigger.bind('mousemove',{id:o.target},handleKeepVisible);
                } else {
                    eltrigger.bind(fadeInEvent,{id:o.target, 'eltrigger':eltrigger, interaction:o.interaction}, handleSetFadeIn);
                    if (o.interaction != 'mouseover') {
                        eltrigger.bind('mouseover',{id:o.target},handleKeepVisible);
                    }
                }
                eltrigger.bind('mouseout',{id:o.target},handleSetFadeOut);
            });
        }
    });
})(jQuery);


/* **************************** METRICS / POSITION  ************************ */
(function(){
$.each({
    'cssOffsetFromElement':cssOffsetFromElement,
    'elementMetrics':elementMetrics
},function(n,v){ WF[n]=v; });

function windowMetrics($win) {
    $win = $win || $(window);
    var metrics = {
        top: $win.scrollTop(),
        left: 0,  // assume
        height: $win.height(),
        width: $win.width()
    };
    metrics.bottom = metrics.top + metrics.height;
    metrics.right = metrics.left + metrics.width;
    return metrics;
}

function elementMetrics($element) {
    var metrics;
    var unhideElement = $element.css('display') == 'none'  &&  $element.css('position') == 'absolute';

    if (unhideElement) { $element.css({display:'block', visibility:'hidden'}); }
    metrics = $element.offset();
    metrics.width = $element.outerWidth();
    metrics.height = $element.outerHeight();
    if (unhideElement) { $element.css({display:'none', visibility:'visible'}); }

    metrics.right = metrics.left + metrics.width;
    metrics.bottom = metrics.top + metrics.height;
    return metrics;
}

function cssOffsetFromElement(opt) {  // { offsets, reference, target, window, referenceMetrics, targetMetrics, windowMetrics, pageX, pageY
    if (!opt.reference || !opt.target) { return }

    // Available formulae:
    //    x=  r=  y=  b=    (left right top bottom)
    // Available parameters in formulae:
    //   (d is default, m is mouse pageX/pageY, w is width, h is height, x/r/y/b)
    //   empty formula is equivalent to simply 'd', e.g. for a formula string of "x;b" element is positioned on top and left aligned
    //   UPPERCASE W,H,X,Y,R,B values refer to target (rather than reference)
    //   If formula begins with [-+] or a bare positive number, is assumed relative to d (whatever the default param is)

    opt.targetMetrics = opt.targetMetrics || elementMetrics(opt.target);
    opt.referenceMetrics = opt.referenceMetrics || elementMetrics(opt.reference);
    opt.windowMetrics = opt.windowMetrics || windowMetrics(opt.window);  // opt.window is optional

    opt.pageX = opt.pageX || 0;
    opt.pageY = opt.pageY || 0;

    var metricsFormulae =  typeof(opt.offsets) == 'object'? opt.offsets : WF.keyValFromString(opt.offsets);
    //console.log('metricsFormulae=',metricsFormulae);
    var thisCSS = {};
    if (metricsFormulae.r) {
        thisCSS.left = calculateMetricsFormula(metricsFormulae.r, {
            d: opt.referenceMetrics.right,
            m: opt.pageX,
            w: opt.referenceMetrics.width,
            x: opt.referenceMetrics.left,
            r: opt.referenceMetrics.right,
            W: opt.targetMetrics.width,
            X: opt.targetMetrics.left,
            R: opt.targetMetrics.right
        });
        thisCSS.left -= opt.targetMetrics.width;
    } else {
        thisCSS.left = calculateMetricsFormula(metricsFormulae.x, {
            d: opt.referenceMetrics.left,
            m: opt.pageX,
            w: opt.referenceMetrics.width,
            x: opt.referenceMetrics.left,
            r: opt.referenceMetrics.right,
            W: opt.targetMetrics.width,
            X: opt.targetMetrics.left,
            R: opt.targetMetrics.right
        });
    }

    if (metricsFormulae.b) {
        thisCSS.top = calculateMetricsFormula(metricsFormulae.b, {
            d: opt.referenceMetrics.top,
            m: opt.pageY,
            h: opt.referenceMetrics.height,
            y: opt.referenceMetrics.top,
            b: opt.referenceMetrics.bottom,
            H: opt.targetMetrics.height,
            Y: opt.targetMetrics.top,
            B: opt.targetMetrics.bottom,
        });
        thisCSS.top -= opt.targetMetrics.height;
    } else {
        thisCSS.top = calculateMetricsFormula(metricsFormulae.y, {
            d: opt.referenceMetrics.top,
            m: opt.pageY,
            h: opt.referenceMetrics.height,
            y: opt.referenceMetrics.top,
            b: opt.referenceMetrics.bottom,
            H: opt.targetMetrics.height,
            Y: opt.targetMetrics.top,
            B: opt.targetMetrics.bottom,
        });
    }

    thisCSS.top = Math.min(opt.windowMetrics.bottom - opt.targetMetrics.height, Math.max(opt.windowMetrics.top, thisCSS.top));
    thisCSS.left = Math.min(opt.windowMetrics.right - opt.targetMetrics.width, Math.max(opt.windowMetrics.left, thisCSS.left));

    return thisCSS;
}

function calculateMetricsFormula(expression, replacements) {

    if (typeof(expression) == 'number') { expression = ''+expression }
    if (expression == '' || typeof(expression) != 'string') { expression = 'd' }

    //console.log('calculateMetricsFormula(',expression,',',replacements,')');

    if (/^[0-9]/.test(expression[0])) { expression = '+' + expression }
    if (/^[-+]/.test(expression[0])) { expression = 'd' + expression }

    for (var token in replacements) {
        expression = expression.replace(token, replacements[token]);
    }
    return Math.round(eval(expression));
}

})();
/* ***************************** metrics / position ************************** */


/* **************************** MISC ************************ */
(function(){
$.each({
    'gatherFormData':gatherFormData,
    'keyValFromString':keyValFromString,
    'initTooltips':initTooltips,
    'contextualShareAdd':contextualShareAdd,
    'buydropQueryUpdate':buydropQueryUpdate,
    'buydropInit':buydropInit,
    'bindClickoutHandlers':bindClickoutHandlers,
    'winScrollElement':winScrollElement,
    'playlistMakeTitleCase':playlistMakeTitleCase,
    'playerInstanceActivate':playerInstanceActivate,
    'playerInstanceBlocked':playerInstanceBlocked,
    'startSingleTimer':startSingleTimer,
    'stopSingleTimer':stopSingleTimer,
    'notifyCenter':notifyCenter,
    'logEvent':logEvent,
    'handleLogEvent':handleLogEvent
},function(n,v){ WF[n]=v; });

var contextualshare = [
    {
        name: 'twitter',
        context: ['http://twitter.com/','http://www.twitter.com/'],
        destination: 'http://twitter.com/home/?status={URL}+{TITLE}',
        tooltip: 'Click to share this page on Twitter',
        wrapDiv: true
    },
    {
        name: 'facebook_like',
        context: [],
        html: '<iframe src="https://www.facebook.com/plugins/like.php?href={URL}&amp;layout=button_count&amp;show_faces=false&amp;width=95&amp;action=like&amp;colorscheme=light&amp;height=21&amp;ref=wf_page_cx_share" scrolling="no" frameborder="0" style="float:left; clear:left; border:none; overflow:hidden;margin:6px 0; width:95px; height:21px;visibility:hidden" onload="\$(this).css({\'visibility\':\'visible\'}).hide().fadeIn(500)" allowTransparency="true" class="tooltip" title="Click to Like this page on Facebook"></iframe>',
        testFn:function(){return $('META[property=og\\:type]').length},
        forceActive: true
    },
    {
        name: 'facebook_share',
        context: [],
        html: '<a target="_blank" style="float:left;margin:6px 0 7px;font:11px &quot;lucida grande&quot;,tahoma,verdana,arial,sans-serif;display:block;background:#ECEEF5;border-radius:3px;-moz-border-radius:3px;padding:2px 4px;border:1px solid #CAD4E7" href="/clickout?https://www.facebook.com/share.php?ref=wf_page_cx_share&u={URL}" title="Click to share on your Facebook wall" class="tooltip"><span style="background:url(&quot;https://s-static.ak.facebook.com/rsrc.php/zh/r/Ch71Zv858xU.png&quot;) no-repeat left -47px transparent;line-height:14px; display:block;color:#3B5998; padding-left:17px">Love!</span></a>',
        testFn:function(){return $('META[property=og\\:type]').length},
        tooltip: 'Click to share this page on Facebook',
        forceActive: true
    },
    {
        name: 'facebook',
        context: ['http://www.facebook.com/','http://www.facebook.com/home.php?ref=home','http://www.facebook.com/home.php?ref=logo','http://www.facebook.com/home.php?'],
        destination: 'https://www.facebook.com/share.php?ref=wf_page_cx_share&u={URL}&t={TITLE}',
        tooltip: 'Click to share this page on Facebook',
        disabled: true
    },
    {
        name: 'myspace',
        context: ['http://www.myspace.com/','http://home.myspace.com/index.cfm?fuseaction=home'],
        destination: 'http://www.myspace.com/Modules/PostTo/Pages/?l=3&u={URL}&t={TITLE}&c={DESCRIPTION}',
        tooltip: 'Click to share this page on MySpace',
        disabled: true
    }
];

function contextualShareAdd(container) {
    var body = $('body');
    var u = window.location.href.toString().replace('//session.','//www.');
;;;   u = u.replace('proto','www').replace(':81','');
    var enc_url = encodeURIComponent(u);
    var enc_title = encodeURIComponent($('title').text());
    var enc_description = encodeURIComponent($('meta[name=description]').text());
    var el, eld, found;
    var popWin = function () { window.open(this.href); return false };

    for (var cx in contextualshare) {
        if (contextualshare[cx].disabled) { continue }
        if (contextualshare[cx].testFn && !contextualshare[cx].testFn()) { continue }
        var active = contextualshare[cx].forceActive;
        var eld = document.createElement('A');
        eld.className = 'cxshare probe';
        el = $(eld);
        if (0 && !active) {  // for now, not sniffing! only forced active sites
            found = false;
            for (var i=0, l=contextualshare[cx].context.length; i<l; i++) {
                eld.href = contextualshare[cx].context[i];
                if (el.css('display') == '') { // I'm looking at you, safari
                    body.append(el);
                }
                if (el.css('display') != 'none') {
                    found = true;
                    break;
                }
            }
            if (!found) { el.remove() }
            active = found;
        }
        if (active) {
            if (contextualshare[cx].destination) {
                var url = '/clickout?' + encodeURIComponent(contextualshare[cx].destination.replace('{URL}', enc_url).replace('{TITLE}', enc_title).replace('{DESCRIPTION}', enc_description));
                eld.href = url;
                var text = contextualshare[cx].text || 'Share';
                el.addClass('ok cxshare_'+contextualshare[cx].name).removeClass('probe').html(text);
                el.bind('click',popWin);
                if (contextualshare[cx].tooltip) {
                    el.addClass('tooltip').attr('title',contextualshare[cx].tooltip);
                }
                if (contextualshare[cx].wrapDiv) {
                    el = $('<div>').append(el).css({'padding':0,'height':'auto'});
                }
                container.append(el);
            }
            else if (contextualshare[cx].html) {
                var html = contextualshare[cx].html.replace('{URL}',enc_url).replace('{TITLE}', enc_title).replace('{DESCRIPTION}', enc_description);
                el.remove();
                container.append(html);
            }
        }
    }
    WF.initTooltips(container);
}

function playerInstanceActivate() {
    WF.playerInstance = WF.playerInstance || Math.random().toString().substr(2);
    WF.createCookie('playerInstance',WF.playerInstance);
}

function playerInstanceBlocked() {
    var activeInstance = WF.readCookie('playerInstance');
    var isBlocked =  (activeInstance && activeInstance !== WF.playerInstance);
    return isBlocked;
}

function startSingleTimer(id, delayms, callbackFn, timerStartFn) {
    if (typeof(timers[id]) !== 'number'  ||  timers[id] < 0) {
        timers[id] = timerStartFn(callbackFn, delayms);
    }
}

function stopSingleTimer(id, timerStopFn) {
    if (typeof(timers[id]) == 'number'  &&  timers[id] >= 0) {
        timerStopFn(timers[id]);
        timers[id] = -1;
    }
}

function gatherFormData(id) {
    var inputs = [];
    $('#'+id+' :input').each(function() {
        inputs.push(this.name + '=' + escape(this.value));
    });
    return inputs.join('&');
}

// e.g.: el.bind('click', {tg:'toplisten'}, WF.handleLogEvent)
function handleLogEvent(event, extradata) {
    var data = event.data || {};
    if (typeof(extradata) === 'object') { $.extend(data, extradata) }
    data.tg = data.tg || this.id;
    if (typeof(data.tg) === 'undefined') { delete data.tg; }
    data.ev = data.ev || event.type;
    var immediate = false;
    if (data.immediate) {
        immediate = true;
        delete data.immediate;
    }
    logEvent(data, immediate);
    return true;
}

function logEvent(data, immediate, noUri) {
    // ts: timestamp
    // uri
    // ev: event signature
    // tg: target
    data.ts = data.ts || Math.round((new Date()).getTime()/1000).toString(16);
    data.uri = data.uri || location.pathname + location.search + location.hash;
    if (noUri) { delete data.uri }
    if (immediate) {
        $.ajax({
            type: 'POST',
            url: '/api/pingback',
            dataType: 'text',
            'data':data
        });
    } else {
        var previousEvents = WF.readCookie('ev') || '';
        if (previousEvents.length < 2000) { // don't let cookie get >2kb
            var allEvents = [];
            if (previousEvents.length > 0) { allEvents.push(previousEvents); }
            var thisEvent = [];
            for (var p in data) {
                var encoded = escape(p) + '=' + escape(data[p]);
                thisEvent.push(encoded);
            }
            allEvents.push( thisEvent.join('&') );
            var cookieValue = allEvents.join(',');
            WF.createCookie('ev',cookieValue,365);
        }
    }
    gaTrackEvent(data);
}

function gaTrackEvent(data) {
    if (typeof(_gaq) == 'object'  && data.ev) {
        // _gaq.push(['_trackEvent', 'Videos', 'Play', 'Baby\'s First Birthday']);
        // _gaq.push(['_trackEvent', category(plural), action(past tense), label, optionalvalue(integer)]);
        var eventBits = data.ev.split('-');
        var category = eventBits.shift();
        var action = eventBits.join('-') || category;
        _gaq.push(['_trackEvent', category, action, data.tg]);
    }
}

/* Tooltip script - adapted from version by Alen Grakalic (http://cssglobe.com)
 * http://cssglobe.com/post/1695/easiest-tooltip-and-image-preview-using-jquery
 */

// x=m+12;y=b
function initTooltips(el,opt) {
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if (is_touch_device) { return true; }

    opt = $.extend({
        'xOffset': 'x',
        'y': 'b+5',
        'arrow':'a',
        'classname': '',
        'evts': 'mouseenter',
        'evth': 'mouseleave'
    }, opt);
    opt.x = opt.x || opt.xOffset;
    opt.y = opt.y || opt.yOffset;  // need to handle both, but from here on we use .x and .y

    el = el || $('body');
    var els = el.find(".tooltip");
    if (el.is('.tooltip')) { els = els.add(el); }
    els.data('tooltipDefaultOpt', opt);
    els.unbind(opt.evts, handleTooltipShow).bind(opt.evts, handleTooltipShow);
    els.unbind(opt.evth, handleTooltipHide).bind(opt.evth, handleTooltipHide);
}

function handleTooltipShow(e) {
    var $this = $(this);
    var opt = $this.data('tooltipDefaultOpt');
    $this.data('oldTitle', this.title);
    var tooltipContent = $this.attr('data-tooltip-html') || this.title;
    this.title = "";

    var oldTooltip = $("#tooltip").remove();
    $("#tooltip-arrow").remove();

    if (!tooltipContent) { return }
    $this.attr('data-tooltip-html', tooltipContent); // just to be sure

    var thisOptString = $this.attr('data-tooltip-opt');
    var thisOpt = keyValFromString(thisOptString);
    thisOpt = $.extend({}, opt, thisOpt);

    var eltip = $('<p>').attr('id', 'tooltip').addClass(thisOpt.classname).html(tooltipContent).css('display','none');
    $("body").append(eltip);

    var thisMetrics = WF.elementMetrics($this);
    var tipMetrics = WF.elementMetrics(eltip)
    var thisCSS = WF.cssOffsetFromElement({
        reference: $this,
        target: eltip,
        offsets: thisOpt,
        pageX: e.pageX,
        pageY: e.pageY,
        referenceMetrics: thisMetrics,
        targetMetrics: tipMetrics,
    });

    if (thisOpt.bg) {
        eltip.css({
            'background':'#'+thisOpt.bg,
            'border-color':'#'+thisOpt.bg
        });
    }
    if (thisOpt.fg) {
        eltip.css({'color':'#'+thisOpt.fg});
    }
    if (thisOpt.opacity) {
        eltip.css({'opacity':thisOpt.opacity});
    }

    var elAnim = $(eltip);
    if (thisOpt.arrow == 'a') {
        var elArrow = $('<div>').attr('id', 'tooltip-arrow').css('display','none');
        $("body").append(elArrow);

        var arrowLeft;
        if (thisMetrics.width < 40) {
            arrowLeft = thisMetrics.left + thisMetrics.width/2 - 5;
        }
        else if (thisCSS.left > thisMetrics.left) {
            arrowLeft = thisCSS.left + 15;
        }
        else {
            arrowLeft = thisMetrics.left + 15;
        }
        var arrowColor = thisOpt.bg || 'FFC';

        if (thisCSS.top > thisMetrics.top) {
            thisCSS.top = thisCSS.top + 5;
            elArrow.css({
                'border-bottom-color':'#'+arrowColor,
                'left': arrowLeft,
                'top': thisCSS.top-10
            });
        } else {
            thisCSS.top = thisCSS.top - 5;
            elArrow.css({
                'border-top-color':'#'+arrowColor,
                'left': arrowLeft,
                'top': thisCSS.top+tipMetrics.height
            });
        }
        elAnim = elAnim.add(elArrow);
    }

    if (oldTooltip.length > 0 || thisOpt.fast) {
        eltip.css(thisCSS);
        elAnim.show();
    } else {
        eltip.css(thisCSS);
        elAnim.fadeIn("fast");
    }
}

function handleTooltipHide() {
    this.title = this.title || $(this).attr('data-tooltip-html') || $(this).data('oldTitle');
    $('#tooltip-arrow').remove();
    $("#tooltip").remove();
}

function keyValFromString(string, pairSep, kvSep) {
    string = string || '';
    pairSep = pairSep || ';';
    kvSep = kvSep || '=';
    var thisOpt = {};

    var kvpairs = string.split(pairSep);
    for (var i=0; i<kvpairs.length; i++) {
        var kv = kvpairs[i].split(kvSep);
        thisOpt[kv[0]] = kv.length>1? kv[1] : true;
    }
    return thisOpt;
}

function winScrollElement() {
    if (WF._winScrollElement) { return WF._winScrollElement }

    var wse = $('html, body');
    wse.each(function () {
        var $this = $(this);
        var initScrollTop = $this.attr('scrollTop');
        $this.attr('scrollTop', initScrollTop + 1);
        if ($this.attr('scrollTop') == initScrollTop + 1) {
            wse = $this;
            $this.attr('scrollTop', initScrollTop);
            return false;
        }
    });
    WF._winScrollElement = wse;  // cache
    return wse;
}

function playlistMakeTitleCase() {
    var $plItems = $('.plitem').add($('.plitem').children());
    var $textNodes = $plItems.contents().filter(function(){ return this.nodeType==3 });

    $textNodes.each(function(){
        var el = this;
        el.replaceWholeText(el.wholeText.replace(/(^|[^0-9a-z'])[a-z]/gi, function($0) {
            return $0.toUpperCase();
        }));
    })
}

function notifyCenter(opt) {
    var old = $('#plOvStatus');

    if (!opt) { old.remove(); clearTimeout(timers.notifyCenter); return }
    if (opt.fade) { old.fadeOut(opt.fade,function(){old.remove();clearTimeout(timers.notifyCenter)}); return }
    if (!opt.html) { old.remove(); clearTimeout(timers.notifyCenter); return }
    opt.bg = opt.bg || '#333';

    old.remove();
    var el = $('<div>').attr('id','plOvStatus').html(opt.html).css({position:'absolute','zIndex':-1, padding:'6px 12px','MozBorderRadius':'6px','WebkitBorderRadius':'6px','borderRadius':'6px','background':opt.bg,'color':'#fff'}).addClass('mediumtext');
    $('body').append(el);
    var elw = el.outerWidth();
    var elh = el.outerHeight();
    var sw = $(window).width();
    var sh = $(window).height();
    el.hide();
    if (opt.spinner) {
        var w = 300;
        var elImg = $('<img>').attr({src:WF.staticwww+'/images-small/spinner-10-white.gif'}).css({width:w,height:w,opacity:0.4,position:'absolute',top:elh/2-w/2,left:elw/2-w/2});
        el.append(elImg);
    }
    el.css({'zIndex':1,'position':'fixed', left:(sw-elw)/2+'px', top:(sh-elh)/2+'px'}).fadeIn(300);
    clearTimeout(timers.notifyCenter);
    opt.time = opt.time || 8000;
    timers.notifyCenter = setTimeout(function(){el.fadeOut(600,function(){el.remove()})},opt.time);
}

function buydropQueryUpdate(query, queryInfo) {
    var $buydrop = $('#buy-drop');

    if ($buydrop.length > 0) {
        $buydrop.data('queryInfo',queryInfo);
        queryEncoded = encodeURIComponent(query);
        $buydrop.find('A.flag-link').each(function(){
            this.target = '_blank';
            this.href = '/gclickout.plx?' + $(this).attr('data-clickbase') + '/' + queryEncoded;
        });
    }
}

function buydropInit() {
    var $buydrop = $('#buy-drop');
    $buydrop.WFHoverTargetInit({fadeOutDelay:100, fadeOutSpeed:600});
    $buydrop.bind('click',function(event) {
        var target = event.target.tagName == 'IMG'? event.target.parentNode : event.target;
        if (target.tagName == 'A') {
            var clickbase = target.getAttribute('data-clickbase') || '';
            var clickbaseBits = clickbase.split('/');
            if (clickbaseBits.length == 3) {
                var service = clickbaseBits[2];
                var countryCode = clickbaseBits[1].substr(3);
                var queryInfo = $(this).data('queryInfo') || {};
                WF.logEvent({
                    ev: 'buy-clickout-query',
                    tg: queryInfo.plid + ' ' + queryInfo.firstArtist + ' ' + queryInfo.firstTitle
                });
                WF.logEvent({
                    ev: 'buy-clickout-cc',
                    tg: 'To ' + countryCode + ' In ' + $buydrop.attr('data-cc') + ' For ' + service
                });
            }
            // if event.target is a link
            // then get the link base data for link
            // then log the clickout
            //   ev: buy-clickout
            //   tg: plix artist title
            // but also want to log on what type of page? showpage-player or explore?
        }
        return true;
    });
}

function handleClickout(event) {
    event.preventDefault();
    var url = event.target.href;
    if (url) {
        var urlTarget = decodeURI(url.replace(/.*clickout\?/,''));
        WF.logEvent({
            ev: 'clickout',
            tg: urlTarget
        });
        window.open(urlTarget);
    }
    return false;
}

function bindClickoutHandlers() {
    $(document).delegate('A.clickout', 'click', handleClickout);
}

})();
/* ***************************** misc ************************** */


/* **************************** Cookies ************************ */
(function(){
$.each({
    'createCookie':createCookie,
    'readCookie':readCookie,
    'eraseCookie':eraseCookie
},function(n,v){ WF[n]=v; });

function createCookie(name, value, days, domain) {     // http://www.quirksmode.org/js/cookies.html
    var expires = '';
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		expires = "; expires="+date.toGMTString();
	}
	if (!domain) {domain = '.wefunkradio.com'; }
	document.cookie = name+"="+value+expires+"; path=/; domain="+domain;
}

function readCookie(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 null;
}

function eraseCookie(name, domain) {
	if (!domain) {domain = '.wefunkradio.com'; }
	createCookie(name,"",-1,domain);
}

})();

/* ***************************** cookies ************************* */


/* **************************** NavSearch ************************ */
(function(){
$.each({
    'initNavSearch':initNavSearch
},function(n,v){ WF[n]=v; });

function navsearch_focus() {
    var el = document.getElementById('navsearch');
    if (el.value == 'search') {
        el.value='';
    }
    el = document.getElementById('navsearchform');
    el.action = "/playlistsearch.plx";
    el.target = '_top'; // default
    $('#navsearchli').addClass('focused');
}

function navsearch_blur_real() {
    $('#navsearchli').removeClass('focused');
    var el = document.getElementById('navsearch');
    if (el.value.length == 0) {
        el.value = 'search';
    }
}

function navsearch_blur() {
    setTimeout(navsearch_blur_real,100);
}

function navsearch_submit_playlists() {
    document.getElementById('navsearchform').submit();
}

function navsearch_submit_learnown() {
    var el = document.getElementById('navsearch');
    var bits = el.value.split(/ - /,2);
    if (bits.length == 2) {
        document.getElementById('artist').value = bits[0];
        document.getElementById('title').value = bits[1];
    } else {
        document.getElementById('artist').value = bits[0];
        document.getElementById('title').value = '';
    }
    el.value = '';

    el = document.getElementById('navsearchform');
    el.action = "/learn-own.plx";
    el.submit();
}

function initNavSearch() {
    $('#navsearch').focus(navsearch_focus).blur(navsearch_blur).addClass('dyn').val('search');
    $('#navsearch_playlists').click(navsearch_submit_playlists);
    $('#navsearch_learnown').click(navsearch_submit_learnown);
}

})();
/* ************************* navsearch ******************* */


/* ************************* FAVORITES ******************* */
(function(){
$.each({
    'favoritesCreateStar':favoritesCreateStar,
    'togglefav':togglefav,
    'favoritesUpdateStar':favoritesUpdateStar,
    'favoritesUpdateAll':favoritesUpdateAll
},function(n,v){ WF[n]=v; });

var favorite_types = {
    'show'   : {'s':'show','p':'shows','ts':'Show','tp':'Shows'},
    'showtrack'   : {'s':'song','p':'songs','ts':'Song','tp':'Songs'},
    'extra'  : {'s':'extra','p':'extras','ts':'Extra','tp':'Extras'},
    'search' : {'s':'search','p':'searches','ts':'Search','tp':'Searches'}
};

function prefs_request(str,key) {
  	var d = new Date();
    //$('#'+key).trigger('update');
    $.ajax({
        url: '/prefs/gj/' + str + '/key/' + key + '/' + d.getTime(),
        dataType: "json",
        success:prefs_callback,
        error:undefined
    });
}

function prefs_callback(result) {
    if (result.success) {
        favoritesUpdateStar(result.key,parseInt(result.value));
    }
}

function favoritesUpdateAll(el, callbackFn) {
    el = el || $('BODY');
    var requestData = {};
    var elMapping = {};
    var numFound = 0;
    el.find('.favstar').each(function(){
        var elStarA = $(this).closest('A');
        if (elStarA.length > 0) {
            var key = elStarA.attr('id') || /\bfav_[^ ]+/.exec(elStarA[0].className);
            if (key) {
                var thisParam = 'favorite:'+key;
                requestData[thisParam] = 1;
                elMapping[thisParam] = elStarA;
                numFound++;
            }
        }
    });
    if (numFound) {
        $.ajax({
            url:'/prefs/?pj/get/favorite/_',
            type:'POST',
            cache:false,
            data:requestData,
            dataType:'json',
            success:function(d){
                if (d.item_results) {
                    for (var p in d.item_results) {
                        var thisParam = d.item_results[p].param + ':' + d.item_results[p].key;
                        var elStar = elMapping[thisParam];
                        favoritesUpdateStar(d.item_results[p].key, d.item_results[p].value, elStar);
                    }
                }
                if (typeof(callbackFn) == 'function') {
                    callbackFn();
                }
            }
        });
    } else {
        if (typeof(callbackFn) == 'function') {
            callbackFn();
        }
    }
}

function favoritesUpdateStar(key,value, el_a) {
    value = parseInt(value);
    var type = favtype(key);
    var typestring_s = favorite_types[type].ts;
    var typestring_p = favorite_types[type].tp;
    var el_a = el_a || $('#'+key).add('.'+key);
    var starData = el_a.data('starData') || {};
    el_a.attr('href','/prefs/?gr/set/favorite/' + (value>0? starData.flagOffValue||0 : starData.flagOnValue||1) + '/key/' + key + '/r/' + escape(document.location.href.substr(document.location.href.indexOf('/',8))));
    var el_img = el_a.children('IMG.favstar');

    if (value > 0) {
        el_img.removeClass('staroff staroffpend staronpend').addClass('staron');
        el_a.attr('title','Click to remove from your Favorite '+typestring_p+' list');
    } else {
        el_img.removeClass('staroffpend staronpend staron').addClass('staroff');
        el_a.attr('title','Click to add to your Favorite '+typestring_p+' list');
    }
    $('#'+key+'_text').add('.'+key+'_text').each(function(){
        var el = $(this);
        var favtext;
        if (value > 0) {
            favtext = '<b>Favorite ' + typestring_s + '</b>';
            if (el.hasClass('lnk0') || el.hasClass('lnk1')) {
                var url = '/profile#view_fav_'+type+'s';
                favtext = favtext + ' &nbsp;&nbsp;<a href="'+url+'" class="nu">View All</a>';
            }
        } else {
             favtext = $('<a>').attr({href:'#'}).addClass('nu').bind('click',{'key':key},togglefav_clickevent).text('Add to Favorite ' + typestring_p);
        }
        el.html(favtext);
        el.attr('title','Click to ' + (value>0? 'remove from':'add to') + ' your WEFUNK Favorites');
  	});
  	el_a.trigger('update',{'key':key, 'staron':value});
}

function favtype(item) {
    var bits = item.toString().split(/_/);
    return bits[1];
}

function togglefav(key) {
    var el_a = $('#'+key).add('.'+key);
    var el_a_label = $('#'+key+'_label').add('.'+key+'_label');
    el_a.trigger('blur');
    var starData = el_a.data('starData') || {};
    var el_img = el_a.children('IMG.favstar');
    var el = el_img.get(0);
  	var opacity = 1;
    var type = favtype(key);
  	var typestring = favorite_types[type].tp;
    if (el.className.indexOf('off') < 0) {
        WF.loginHook({fn:function(newlogin){
            // it's on; turn off
            el_img.removeClass('staron staronpend').addClass('staroffpend');
            el_a.attr('title','Click to add to your Favorite '+typestring+' list');
            prefs_request('set/favorite/'+(starData.flagOffValue||0),key);
            opacity = 0.4;
            el_a_label.fadeTo(150, opacity);
        },message:'Removing '+favorite_types[type].s+' from your favorites...'});
    } else {
        WF.loginHook({fn:function(newlogin){
            el_img.removeClass('staroff staroffpend').addClass('staronpend');
            el_a.attr('title','Click to remove from your Favorite '+typestring+' list');
            prefs_request('set/favorite/'+(starData.flagOnValue||1),key);
            el_a_label.fadeTo(150, opacity);
        },message:'Saving favorite '+favorite_types[type].s+' to your profile...'});
    }
}

function togglefav_clickevent(event) {
    togglefav(event.data.key);
    event.stopPropagation();
    return false;
}

function favoritesCreateStar(opt) {
    if (opt.returnto) {
        opt.returnto = opt.returnto.replace(/^http:\/\/[^\/]+/,'');
        opt.returnto = opt.returnto.replace(/^\//,'');
    } else {
        opt.returnto = '';
    }
    opt.isfav = parseInt(opt.isfav); // just in case
    var starData = {
        flagOnValue: opt.flagOnValue || 1,
        flagOffValue: opt.flagOffValue || 0,
        key: opt.key
    };
    var url = '/prefs/?gr/set/favorite/' + (opt.isfav? starData.flagOffValue : starData.flagOnValue) + '/key/' + opt.key + '/r/'+(opt.returnto?encodeURIComponent(opt.returnto):'');
    var el = $('<a>').attr({'href':url}).addClass('nohover starlink '+opt.key);
    var size = (opt.small? 17:22);
    el.append('<img src="'+WF.staticwww+'/images-small/pxl-clr.gif" height="'+size+'" width="'+size+'" class="favstar '+(opt.small?'smallstar ':'')+(opt.isfav?'staron':'staroff')+'"></a>');

    el.bind('click',{key:opt.key},togglefav_clickevent);
    el.data('starData',starData);
    return el;
}

function bind_startoggle(id) {
    $('#'+id).bind('click',{key:id},togglefav_clickevent);
}

})();
/* ***************************** favorites ************************ */


/* *******************  HEIGHT/WIDTH LAYOUT + SIDEIMAGE ***************** */
(function(){
$.each({
    'checkPageLayout':checkPageLayout,
    'initPageLayout':initPageLayout,
    'setSideimagePinnable':setSideimagePinnable,
    'sideimageSelect':sideimageSelect
},function(n,v){ WF[n]=v; });

var elDivImage;
var elWindow;

function setSideimagePinnable(enabled) {
    elDivImage = $('#divimage');
    elWindow = $(window);
    if (enabled && elDivImage.length>0) {
        elWindow.bind('scroll', handleSideimagePageScroll);
    } else {
        elWindow.unbind('scroll', handleSideimagePageScroll);
    }
}

function handleSideimagePageScroll(event) {
    var isfixed = elWindow.scrollTop()>124;
    elDivImage.toggleClass('fixed',isfixed);
    if ($.browser.msie && $.browser.version < 8) {
        elDivImage.css('position', (isfixed? 'fixed':'absolute'));
    }
}

function sideimageSelect(item) {
    var elItem = typeof(item) === 'string'? $(item) : item;
    var elNotItem = $('#divimage .divimage-item').not(elItem);

    elItem.stop(true).fadeIn(1000);
    elNotItem.stop(true).fadeOut(1000);
}

function initPageLayout() {
    WF.widthThresholds = {
        'narrowpage': 620,
        'tinypage': 450
    }

    var _body = document.getElementsByTagName('BODY')[0];
    var $body = $(_body);

    var thr = _body.className.match(/thr(\d+)/);
    if (thr) {
        WF.widthThresholds.narrowpage = thr[1];
    }

    thr = _body.className.match(/thr2-(\d+)/);
    if (thr) {
        window.widthThresholds.tinypage = thr[1];
    }

    $('#nav-more-show').bind('click', function(){
        $(this).hide();
        $('#nav-more').fadeIn();
        return false;
    });

}

function checkPageLayout() {
    var _body = document.getElementsByTagName('BODY')[0];
    var $body = $(_body);
    var $win = $(window);

    // WIDTH

    var winWidth = $win.width();

    if (winWidth < WF.widthThresholds.narrowpage) {
        $body.addClass('narrowpage');
        WF.createCookie('narrowpage',1,6/24);
    } else {
        $body.removeClass('narrowpage');
        WF.eraseCookie('narrowpage');
        var $pageWrap = $('#pagewrap');
        if ($pageWrap.length > 0) {
            var critWidth2 = parseInt($pageWrap.css('max-width'), 10);
            if (winWidth > critWidth2) {
                $body.addClass('widerpage');
            } else {
                $body.removeClass('widerpage');
            }
        }
    }

    var isTiny = (winWidth < WF.widthThresholds.tinypage)? true:false;
    $body.toggleClass('tinypage', isTiny);

    // HEIGHT

    var winHeight = $win.height();
    var $divcontent = $('#divcontent');
    if ($divcontent.length > 0) {
        // we want to ensure divcontent fills the window height, at minimum
        var dcHeight = $divcontent.height();
        var dcTop = $divcontent.offset().top;
        var dcOuterHeight = $divcontent.outerHeight();
        var dcMinHeight = winHeight - dcTop - (dcOuterHeight - dcHeight);
        $divcontent.css({'min-height': dcMinHeight});

        // we don't want divimage's contents to extend the page height
        var $limitHeight = $('.limit-height');
        if ($limitHeight.length > 0) {
            dcHeight = $divcontent.height();  // update values
            dcOuterHeight = $divcontent.outerHeight();
            $limitHeight.each(function(){
                var el = $(this);
                // note: we assume that any .limit-height has height=outerHeight
                var thisMaxHeight = dcOuterHeight + dcTop - el.offset().top;
                var thisOverflow = el.height() >= thisMaxHeight - 21? 'hidden':'visible';
                el.css({
                    'max-height': thisMaxHeight,
                    'overflow': thisOverflow
                });
            });
        }
    }
}

})();
/* ********************* height/width layout + sideimage ***************** */


/* **************************** MODALOVERLAY ************************ */
(function(){
$.each({
    'modalOverlayPop':overlayPop,
    'modalOverlayClose':overlayClose,
    'handleExploreOverlayPop':handleExploreOverlayPop,
    'closeSelfWindow':closeSelfWindow
},function(n,v){ WF[n]=v; });

function overlayLayoutUpdate(param) {
    var data = param.data? param.data : param; // handle event or direct call
    var w = $(window);
    var wH = w.height();
    var wW = w.width();
    var boxH = data.h;
    var boxW = data.w;
    if (typeof(boxH) === 'string' && boxH.indexOf('%') >= 0) { boxH = Math.floor(wH * parseFloat(boxH,10) / 100) }
    if (typeof(boxW) === 'string' && boxW.indexOf('%') >= 0) { boxW = Math.floor(wW * parseFloat(boxW,10) / 100) }
    if (boxH < 0) { boxH += wH }
    if (boxW < 0) { boxW += wW }
    if (data.maxW) {
        boxW = Math.min(boxW, data.maxW);
    }
    var boxTop = Math.round((w.height() - boxH)/2,0);
    var boxLeft = Math.round((w.width() - boxW)/2,0);
    data.elContent.css({
        height:boxH,
        width:boxW,
        top:boxTop,
        left:boxLeft
    });
}

function overlayPop(param) {
    var data = param.data? param.data : param; // handle event or direct call
    var scrolling = data.iframeScrolling? 'auto':'no';
    data.zindex = data.zindex || 998;
    $('#modalOverlay').remove();
    var elOverlay = $('<div>').attr('id', 'modalOverlay').css({position:'fixed',height:'100%', width:'100%', zIndex:data.zindex, left:0, top:0});
    data.elOverlay = elOverlay;
    var url = data.url || this.href;
    var background = data.background || '#FEBF42';
    var contentContainer;
    if (data.content) {
        contentContainer = $('<div>').css({
            position:'absolute',
            opacity:0,
            'background':background
        });
        contentContainer.append(data.content);
        contentContainer.fadeTo(500,1);
    } else {
        var elIframe = $('<iframe>').attr({
            src:url,
            frameBorder:0,
            'scrolling':scrolling
        }).css({
            position:'absolute',
            opacity:0,
            'background':background
        });
        if (data.iframeCss) { elIframe.css(data.iframeCss); }
        if (data.iframeClass) { elIframe.addClass(data.iframeClass); }
        if (data.bg) { elIframe.css('background',data.bg); }
        if (data.showImmediately) {
            contentFadeIn.apply(elIframe);
        } else {
            elIframe.bind('load', contentFadeIn);
        }
        contentContainer = elIframe;
    }
    var elMask = $('<div>').attr('id', 'modalOverlayMask').css({
        background:'#000',
        position:'absolute',
        height:'100%',
        width:'100%',
        opacity:0,
        left:0,
        top:0
    });
    elMask.bind('click',overlayClose);
    elOverlay.append(elMask);
    elOverlay.append(contentContainer);
    data.elContent = contentContainer;
    overlayLayoutUpdate(data);
    $(window).bind('resize', data, overlayLayoutUpdate);
    $('body').append(elOverlay);
    elMask.fadeTo(800,0.7);
    return false;
}

function handleExploreOverlayPop(param) {
    var data;
    if (typeof(param) === 'string') {
        data = {url: param};
    }
    else if (typeof(param) === 'object') {
        data = param.data || param;
    }
    else {
        return false; // invalid input
    }
    data.url = data.url || this.href;
    if (!data.url) { return false; }

    if ($.browser.msie && $.browser.version <= 8) {
        open(data.url);
    } else {
        WF.notifyCenter({html:'<b>Loading Track Info...</b>',time:4000,spinner:true});
        WF.modalOverlayPop({w:-40, h:-40, maxW:1050, 'url':data.url, zindex:1001, showImmediately:true, background:'#000'});
    }
    return false;
}

function contentFadeIn(el) {
    $(this).fadeTo(500,1);
}

function overlayClose() {
    var el = $('#modalOverlay');
    el.fadeOut(600,function(){el.remove()});
    return false;
}
function closeSelfWindow() {
    if (top !== self  &&  window.parent.WF.modalOverlayClose) {
        window.parent.WF.modalOverlayClose();
    } else {
        window.close();
    }
    return false;
}

})();
/* **************************** modaloverlay ************************ */

/* ****************************** LOGIN *************************** */
(function(){
$.each({
    'loginHook':loginHook,
    'loginInit':loginInit,
    'getshowdate':getshowdate
},function(n,v){ WF[n]=v; });

function loginInit() {
    if (document.location.href.indexOf('//store.') > 0) { return; }

    if (!WF.username) {
        var elL = $('#login');
        if (elL.length > 0) {
            var login = elL.find('b').text();
            if (login.length) {
                WF.username = login.substr(0,login.indexOf(' :'));
            }
        }
    }

    if (!WF.username) {
        elL.find('A').bind('click',function(){loginView(true,'Logging In...');return false});
    }

    if ($('#logingrp').length > 0) {
        var cancelFn = function(){loginView(false);return false}
        $('#logincancel').bind('click',cancelFn);
        $('#logincreate').click(function(){$('#loginchoose').fadeOut(200, function(){$('#loginpre').html('Creating New Account'); $('#loginformcreate').fadeIn(200).find('INPUT').eq(0).focus()}); return false});
        $('#logingo').click(function(){$('#loginchoose').fadeOut(200, function(){$('#loginform').fadeIn(200).find('INPUT').eq(0).focus()}); return false});
        $('#logingrp .logincancel').bind('click', function(){
            loginView(false);
            return false;
        });
        $('#loginmask').bind('click',cancelFn);
        $('#loginform_f').bind('submit',handleLoginFormSubmit);
        $('#loginformcreate_f').bind('submit',handleLoginCreateSubmit);
        $('#logingrp .loginsubmit').bind('click', function(){
            $(this).parents('FORM').submit()
        });
    }
}

function handleLoginSubmit(el) {
    $('#logingrp .loginformstatus').show();
    $('#'+el).fadeTo(300,0.2);

    jQuery.ajax({
        data: WF.gatherFormData(el),
        url: '/login?type=json',
        error: function() {
            $log("Failed to submit");
        },
        type: 'POST',
        dataType: 'json',
        success: loginCallback
    });

    return false;
}

function getshowdate() {
  	var docurl = document.location.toString();
  	var i = docurl.indexOf("show/");
    var showdate = '';
  	if (i >= 0) {
      	showdate = docurl.substr(i+5,10);
    }
    return showdate;
}

function loginCallback(r) {
    //$log('LOGIN SUBMIT RESPONSE', r);
    if (r.success) {
        WF.username = r.username;
        if (r.cookie) {
            document.cookie = r.cookie;
        }
        var el = $('#login');
        el.html('<b>'+WF.username+' : <a class="fglink nohover nu" href="/profile">view profile</a>');
        //el.get(0).onclick = false;

        $('#loginpre,.loginformstatus').fadeOut(100,function(){$('#loginpre').html('Login Complete').fadeIn(200)});
        setTimeout(function(){
            loginView(false);
            var loginfinish = function () {
                if (typeof(WF.onloginsuccess) == 'function') {
                    WF.onloginsuccess();
                    delete WF.onloginsuccess;
                }
            }
            // OKAY, SHALL WE HANDLE THIS PROPERLY WITH AN EVENT/HOOK??
            WF.favoritesUpdateAll();
            loginfinish();
            /*
            var showdate = getshowdate();
            if (showdate) {
                jQuery.ajax({
                    url: '/info/showsingle/json?vars=songfav,showfav&show='+showdate,
                    error: loginfinish,
                    dataType: 'json',
                    success: function(r){
                        if (r && r.datafound) {
                            window.trackisfav = r.songfav;
                            var i = 0;
                            $('#playlist .starlink').each(function(){  // this only applies to show pages!!
                                var key = $(this).attr('id') || /\bfav_[^ ]+/.exec(this.className);
                                if (key) {
                                    WF.favoritesUpdateStar(key,r.songfav[i]);
                                }
                                i++;
                            });
                            var el = $('#ibx .favstar').parent();
                            if (el.length > 0) {
                                WF.favoritesUpdateStar(el.attr('id'),r.showfav);
                            }
                        }
                        loginfinish();
                    }
                });
            } else {
                loginfinish();
            }
            */
        },1000);
    } else {
        if (r.message) { $('#loginpre').html(r.message); }
        $('#logingrp .loginformstatus').fadeOut(200);
        $('#loginform,#loginformcreate').filter(':visible').fadeTo(300,1);
    }
}

function handleLoginFormSubmit() {
    handleLoginSubmit('loginform');
    return false;
}
function handleLoginCreateSubmit() {
    handleLoginSubmit('loginformcreate');
    return false;
}

function loginView(vis,prologue) {
    prologue = prologue || '';
    if (vis) {
        $('#logingrp,#loginform,#loginformcreate,.loginformstatus').hide();
        $('#logingrp').addClass('loginvis');
        $('#loginchoose').show();
        $('#loginpre').html(prologue);
        if ($.browser.msie && $.browser.version < 7) {
            var vptop = $(window).scrollTop();
            $('#logingrp').css({'position':'absolute','top':vptop+'px'});
        } else {
            var vpheight = window.innerHeight || self.innerHeight || (document.documentElement&&document.documentElement.clientHeight) || document.body.clientHeight;
            var vpwidth = window.innerWidth || self.innerWidth || (document.documentElement&&document.documentElement.clientWidth) || document.body.clientWidth;
            $('#loginmask').css({width:2*vpwidth+'px',height:2*vpheight+'px'});
            $('#loginmask').css({opacity:0,display:'block'}).fadeTo(700,0.6);
        }
        $('#logingrp').fadeIn(500);
    } else {
        $('#loginmask,#logingrp').fadeOut(800);
    }
    return false;
}

function loginHook(opt) {
    if (typeof(WF.username) != 'undefined' && WF.username) {
        opt.fn();
        return true;
    } else {
        window.WF.onloginsuccess = opt.fn;
        loginView(true,opt.message);
        return false;
    }
}

})();
/* **************************** login ************************ */


/* ******************** unimplemented pref update hooks ******************************* */
/*
function showprefs_refresh(data) {
    showdate = data.currentshowdate;
    if (showdate != lastshowdate) {
        prefs_request('get/favorite/0','fav_show_'+showdate);
    }
}
function showprefs_hookupdates() {
    // hook into show updates (radio refresh)
    if (typeof(showupdate_events) == 'object'  &&  typeof(showupdate_events.push) == 'function') {
        showupdate_events.push(showprefs_refresh);
    } else {
        showupdate_events = [showprefs_refresh];
    }
}
*/


/* **************************** UNIVERSAL ONREADY EVENTS ************************ */

$(document).ready(function(){
    WF.filerev = '';
    var scriptsrc = $('script:first').attr('src') || '';
    var match = scriptsrc.match(/\d+$/);
    if (match) {
        WF.filerev = match[0];
    }

    WF.staticwww = '';
    var bits = ($('link:first').attr('href')||'').match(/^http:..[^\/]+/);
    if (bits) {
        WF.staticwww = bits[0];
    }

    if (document.getElementById('navsearch')) {
        WF.initNavSearch();
    }

    WF.initPageLayout();
    WF.checkPageLayout();
    $(window).resize(WF.checkPageLayout);

    WF.setSideimagePinnable(true);
    $(window).trigger('scroll');

    WF.loginInit();

    WF.bindClickoutHandlers();

    var elshare = $('.boxsect.sharelinks');
    if (elshare.length > 0) {
        WF.contextualShareAdd(elshare.eq(0));
    }
});


