// Copyright 2003-2009 Emergent Music LLC  All rights reserved.
// This is the only global object in the FlyFi player (similar to http://www.dustindiaz.com/namespace-your-javascript/)

var FLYFI = function() {};

// Translate strings

FLYFI._ = function(string) {
    return string; // At some point we will translate these values.
};
// Strings
    
FLYFI.trim = function(s) {
    return s.replace(/^\s\s*/, '').replace(/\s\s*$/, '');   // from http://blog.stevenlevithan.com/archives/faster-trim-javascript
};

FLYFI.endswith = function(s, suffix) {
    return (s.match(suffix+"$")==suffix);                          // from http://www.tek-tips.com/faqs.cfm?fid=6620
}

// Event disable utilities
FLYFI.nop = function(event) {
    event.preventDefault();
};
FLYFI.stopProp = function(event) {
    event.stopPropagation();
};

// Page

FLYFI.isPostStart = function () {
    return $('body').hasClass('poststart');
};
FLYFI.isCoolStart = function () {
    return $('body').hasClass('coolstart');
};

FLYFI.isContest = function () {
    return $('body').hasClass('contest');
};

FLYFI.isContestCreation = function () {
    return $('body').hasClass('contestcreation');
};

// Embedded IDs

FLYFI.IDFromWidget = function(classPrefix, widget) {
    // return the ID embedded in the class with the specified prefix for the supplied widget
    if (!widget) {
        return null;
    }
    var classes = String(widget.attr('className')).split(' ');
    var l = classes.length;
    for (var i=0; i< l; i++) {
        var c = classes[i];
        if (c.substr(0, classPrefix.length) == classPrefix) {
            return c.slice(classPrefix.length);
        }
    }
    return null;
};

FLYFI.trackIDFromWidget = function(widget) {
    return FLYFI.IDFromWidget('track-', widget);
};

// YouTube

FLYFI.youTubeIDFromVideoURL = function(url) {
    var parts = url.split('/');
    return parts[parts.length-1];
};

// AJAX - support error handling, see: http://groups.google.com/group/jquery-en/browse_thread/thread/d9f190e6a6b9eb5f

FLYFI.getJSON = function(url, successFunction, errorFunction) {
    FLYFI._get_ajax('json', url, successFunction, errorFunction);
};

FLYFI.get_NoResponse = function(url, successFunction, errorFunction) {
    FLYFI._get_ajax('text', url, successFunction, errorFunction);
};

FLYFI._get_ajax = function(dataType, url, successFunction, errorFunction) {
    var params = { type: 'GET', url: url, dataType: dataType, success: successFunction };
    if (errorFunction) {
        params.error = errorFunction;
    }
    $.ajax(params);
};


FLYFI.getJSONWithSpinner = function(url, spinnerSelector, successFunction, errorFunction) {
    if (!spinnerSelector) {
        FLYFI.getJSON(url, successFunction, errorFunction);
        return;
    }
    
    var spinner = $(spinnerSelector);
    spinner.show();
    
    var sFunc = function(result) {
        spinner.hide(); // do first so we can keep it going if necessary in the successFunction
        successFunction(result); 
    };
    
    var eFunc = function(request, textStatus, errorThrown) {
        spinner.hide(); // do first so we can keep it going if necessary in the errorFunction
        if (errorFunction) {
            errorFunction(request, textStatus, errorThrown); 
        }
    };
    
    FLYFI.getJSON(url, sFunc, eFunc);
};

FLYFI.post_NoResponse = function(url, data, successFunction, errorFunction) {
    FLYFI._post_ajax('text', url, data, successFunction, errorFunction);
};
FLYFI.postText = FLYFI.post_NoResponse; // for documentation

FLYFI.postJSON = function(url, data, successFunction, errorFunction) {
    FLYFI._post_ajax('json', url, data, successFunction, errorFunction);
};

FLYFI._post_ajax = function(dataType, url, data, successFunction, errorFunction) {
    var params = { type: 'POST', url: url, data: data, dataType: dataType, success: successFunction};
    if (errorFunction) {
        params.error = errorFunction;
    }
    $.ajax(params);
};

FLYFI.postJSONWithSpinner = function(url, data, spinnerSelector, successFunction, errorFunction) {
    if (!spinnerSelector) {
        FLYFI.postJSON(url, data, successFunction, errorFunction);
        return;
    }
    
    var spinner = $(spinnerSelector);
    spinner.show();
    
    var sFunc = function(result) {
        successFunction(result); 
        spinner.hide();
    };
    
    var eFunc = function(request, textStatus, errorThrown) {
        if (errorFunction) {
            errorFunction(request, textStatus, errorThrown); 
        }
        spinner.hide();
    };
    
    FLYFI.postJSON(url, data, sFunc, eFunc);
};


FLYFI.showJSONError = function(request, textStatus, errorThrown) {
    if (textStatus == 'error') {
        return; // user clicked away while the JSON is pending - don't report it
    }
    var messageArray = [];
    messageArray.push('Server Error: ' + textStatus);
    messageArray.push('in response to request: ' + request);
    if (errorThrown) {
        messageArray.push('error: ' + errorThrown);
    }
    alert(messageArray.join("\n"));
};

FLYFI.ignorePostError = function(request, textStatus, errorThrown) {
};

// Scrollers

FLYFI.getScroller = function(item) {
    // return the item that does scrolling for the supplied item
    if ($(item).css('overflow') == 'auto') {
        return item[0];
    }
    
    var parents = $(item).parents();
    var l = parents.length;
    for (var i=0; i< l; ++i) {
        var next = parents[i];
        if ($(next).css('overflow') == 'auto') {
            return $(next).get(0);
        }
        if ($(next).hasClass('stations')) {
            return $(next).get(0);
        }
    }
    return null;
};

FLYFI.getOffsetTopIn = function(scroller, item) {
    // return the offset to the top of the item within the scroller
    var topOffset = 0;
    var next = item;
    while (next && (next != scroller) && ($(next).parents().index(scroller) >= 0)) {
        topOffset += next.offsetTop;
        next = next.offsetParent;
    }
    return topOffset;
};

FLYFI.scrollListToRow = function(list, row, extra) {
    // Scroll the given row into view in the list, with 'extra' pixels showing at the bottom
    
    if (! extra) {
        extra = 0;
    }
    
    if (row.length === 0) {
        return; // row may not be in this list
    }
    var rowItem = row[0];
    var scroller = FLYFI.getScroller(list);
    if (scroller === null) {
        return; // nothing to do 
    }
    extra = Math.min(extra, scroller.clientHeight - rowItem.offsetHeight); // Can only show extra if there is room for it.
    var rowTopInScroller = FLYFI.getOffsetTopIn(scroller, rowItem);
    if (scroller.scrollTop > rowTopInScroller) { // track is above the top of the visible area
        scroller.scrollTop = Math.max(0, rowTopInScroller - extra);
    } else if (scroller.scrollTop + scroller.clientHeight < rowTopInScroller + rowItem.offsetHeight) {  // track is below the bottom of the visible area
        scroller.scrollTop = Math.min(scroller.scrollHeight, rowTopInScroller + rowItem.offsetHeight + extra) -
                                scroller.clientHeight;
    }
};

// Cell Contents

FLYFI.textOrNbsp = function(t) {
    if (!t || t.length === 0) {
        return "&nbsp;";
    } else {
        return t;
    }
};

// CheckBoxes

FLYFI.setCheckBox = function(selector, checkIt) {
    if (checkIt) {
        $(selector).attr('checked', 'checked');
    } else {
        $(selector).removeAttr('checked');
    }
};

FLYFI.isChecked = function(selector) {
    return $(selector).is(':checked');
};

// browsers

FLYFI.isSafari = function () {
    var agent = navigator.userAgent;
    return agent.indexOf('Safari') != -1;
};

FLYFI.isFireFox = function () {
    var agent = navigator.userAgent;
    return agent.indexOf('Firefox') != -1;
};

FLYFI.consoleLog_FireFox = function(s) {
    // write the supplied string to the FireFox console, if running in FireFox
    try {
        if (console) {
            console.log(s);
        }
    } catch(err) { if (window.level != 'live') { alert(s); } }
};

FLYFI.getIEVersion = function () {
    //Returns the version of Internet Explorer or null
    //(indicating the use of another browser).
    var rv = -1; // Return value assumes failure.
    if (navigator.appName == 'Microsoft Internet Explorer') {
        var ua = navigator.userAgent;
        var re  = /MSIE ([0-9]{1,}[\.0-9]{0,})/;
        if (re.exec(ua) !== null) {
            rv = parseFloat( RegExp.$1 );
        }
    }
    return rv;
};
FLYFI.isIE = function() { return FLYFI.getIEVersion() > -1; };

// Device

FLYFI.isLikeIPhone = function() {
    // return whether running on an iPhone, iPod, etc.
    var agent = navigator.userAgent.toLowerCase();
    return (agent.indexOf('iphone') != -1) || (agent.indexOf('ipod') != -1);
};

FLYFI.showIPhonePlayer = function() {
    window.scroll(0, 0);
};

// Dummy console class for browsers that do not have a console.
FLYFI.console = function() {
    var self = this;
    self.log = function(message) {}; // Throw away message.
};

//global toggle

FLYFI.onClick_CollapseLink = function(event) {
    $(this).parents('.collapsable_container').find('.collapsable_items').toggle('collapsed');
    event.preventDefault();
};

// Google analytics

FLYFI.googleAnalytics = function() {
    try {
        var key = FLYFI.environment == "PROD" ? (window.location.hostname == "contest.flyfi.com" ? "UA-7363056-4" : "UA-7363056-1") : "UA-7363056-2";
        var pageTracker = _gat._getTracker(key);
        pageTracker._trackPageview(); // Track the basic page load.
        FLYFI.trackAjaxCall = function(ajaxCall) { // Define the function to track the Ajax calls.
            try {
                pageTracker._trackPageview("/ajax" + (ajaxCall.substr(0,1) == "/" ? "" : "/") + ajaxCall + (ajaxCall.substr(ajaxCall.length - 1,1) == "/" ? "" : "/"));
            } catch(err) {
                if (console) {
                    console.log("Error in AJAX tracker: " + err);
                }
            }
        };
        for (var i = 0; i < FLYFI.trackAjaxQueue.length; i++) { // Track Ajax calls that happened before the tracker was ready.
            FLYFI.trackAjaxCall(FLYFI.trackAjaxQueue[i]);
        }
    } catch(err) {
        if (console) {
            console.log("ERROR: Tracker call or setup failed: " + err);
        }
    }
};

// Window management - switching and messaging between browser windows.

FLYFI.windowID = (new Date()).getTime();
FLYFI.windowMessageID = null;

FLYFI.sendOtherWindowMessage = function(message) {
    // Send a message to other windows through the messaging cookie.
    var cookie = new FLYFI.Preferences(FLYFI.WINDOW_COOKIE);
    cookie.setString(FLYFI.WINDOW_MESSAGE, FLYFI.windowID + ":" + (new Date()).getTime() + ":" + message);
};

FLYFI.getOtherWindowMessage = function() {
    // Check for a message from the other window through the messaging cookie.
    var cookie = new FLYFI.Preferences(FLYFI.WINDOW_COOKIE);
    var message = cookie.getString(FLYFI.WINDOW_MESSAGE);
    if (message) {
        var parts = message.split(":", 3);
        if (((new Date()).getTime() - parts[1]) > 20000) { // Don't return messages if they are older than 20 seconds.
            cookie.setString(FLYFI.WINDOW_MESSAGE, null);
            return null;
        }
        if (parts[0] == FLYFI.windowID || parts[1] == FLYFI.windowMessageID) {
            return null; // Message was sent from this window or was already seen - ignore it.
        }
        FLYFI.windowMessageID = parts[1];
        message = parts[2];
    }
    return message;
};

FLYFI.startOtherWindowMonitor = function() {
    FLYFI.stopOtherWindowMonitor();
    FLYFI.monitorWindowTimer = setInterval(FLYFI.monitorOtherWindow, 1000); // Listen for the other window to start playing a track.
};
FLYFI.stopOtherWindowMonitor = function() {
    if (FLYFI.monitorWindowTimer) { // If we previously switched and the user came back and we're switching again - get rid of the old timer.
        clearInterval(FLYFI.monitorWindowTimer);
        FLYFI.monitorWindowTimer = null;
    }
};

FLYFI.monitorOtherWindow = function() {
    // Periodically check whether the other window has started playing - if so stop this one.
    var message = FLYFI.getOtherWindowMessage();
    if (message == "play") {
        FLYFI.onMonitorCount = 0;
        FLYFI.onMonitorMessage_stopPlaying();
        if (FLYFI.monitorWindowTimer) {
            clearInterval(FLYFI.monitorWindowTimer); // Once we get the "play" message we can stop listening as well as playing.
        }
    }
};

FLYFI.onMonitorMessage_stopPlaying = function() {
    // If there is currently a track playing then stop playing.
    // NOTE: We try this a few times in case we happen to hit the player while it is switching from track to track.
    if (FLYFI.playingTrack.playing || FLYFI.onMonitorCount > 5) {
        if (FLYFI.playingTrack.playing) {
            FLYFI.playingTrack.pause();
        }
        return;
    }
    FLYFI.onMonitorCount += 1;
    setInterval(FLYFI.onMonitorMessage_stopPlaying, 1000); // Try again.
};

FLYFI.onClick_switchPage = function(event) {
    // When the user clicks a link see whether to open it in the current window or in a new one.
    // We open links in a new window if the current window is playing a track.
    if ($(event.target).hasClass("logclick")) {
        return;
    }
    var url = $(event.target).closest('a').attr('href');
    if (!url || url === '' || url.substr(0,1) === '#') {
        return;
    }
    event.preventDefault();
    if (url == window.location) {
        return;
    }
    if (FLYFI.leavePageFunction) {
        if (!FLYFI.leavePageFunction(event.target)) {
            return;
        }
    }
    var leavingFlyFi = (url.indexOf('flyfi.com') == -1);
    if (!FLYFI.playingTrack || !FLYFI.playingTrack.playing) {
        if (leavingFlyFi) {
            window.name = '';
        }
        window.location = url;
        return;
    }
    if (!leavingFlyFi) {
        FLYFI.sendOtherWindowMessage("open"); // Notify the other window to do the alert that brings the window to the front.
    }
    if (window.name != 'flyfi1' && window.name != 'flyfi2') {
        window.name = 'flyfi1';
    }
    var otherWindow = leavingFlyFi ? 'flyfi3' : (window.name == 'flyfi1') ? 'flyfi2' : 'flyfi1';
    window.open(url, otherWindow);
};

FLYFI.addLinkFollower = function(containerSelector) {
    $(containerSelector).find('a').not('.logclick').not('[href$="#"]').click(FLYFI.onClick_switchPage);
};

// Utility to display an alert that dismisses itself after a few seconds
// NOTE: For now this just displays a regular alert

FLYFI.showFadingAlert = function(message, dismissAfter) {
    alert(message);
};

// Page ready

$(document).ready(function() {
    var initialMessage = FLYFI.getOtherWindowMessage(); // Try to get this message before it times out (if the page is loading slowly).
    $('a[href="#"]').click(
                        function(event) { 
                            event.preventDefault(); 
                        });
    FLYFI.addLinkFollower('body');
    $('.collapsed').show();
    $('.collapselink').click(FLYFI.onClick_CollapseLink);
    if (!FLYFI.isFireFox() && !FLYFI.isSafari()) {
        console = new FLYFI.console();
    }
    setTimeout(FLYFI.googleAnalytics, 10000); // Do this after other page initializations
    
    if (initialMessage == "open") {
        FLYFI.monitorIsActive = true;
//        alert("To not interrupt your music, we've opened this page in a new window.\n\nIf you play a song here the music in your other window will pause.");
    }
});