function loadLinkReportForm(watchlinkURL, atomTitle, watchlinkID) {
    var panel = new Ext.Panel({
        html: '<iframe src="http://spreadsheets.google.com/a/sidereel.com/viewform?hl=en&formkey=dGp2cFFTdWZDOFRrRzFYMzNGYWRiMEE6MA..&entry_0=' + watchlinkURL + '&entry_1=' + atomTitle + '&entry_5=' + watchlinkID + '" width="700" height="700" frameborder="0" marginheight="0" marginwidth="0">Loading...</iframe>',
        hideBorders: true,
        bodyBorder: false,
        border: false
    });
    var win = generateLightboxWindow(740, 740, panel, 'linkReportForm', 'Report Link', true);
    win.show();
}


function fillAsk() {
    document.getElementById("siteSearchInput").setAttribute("value", "Powered by Ask");
    document.getElementById("siteSearchInput").style.color = "#C4C4C4";
}
function removeAsk() {
    document.getElementById("siteSearchInput").setAttribute("value", "");
    document.getElementById("siteSearchInput").style.color = "#333";
}


Ext.onReady(function() {
    if (Ext.get('statusFilter')) {
        var converted = new Ext.form.ComboBox({
            typeAhead: false,
            triggerAction: 'all',
            transform:'statusFilter',
            forceSelection:true,
            editable: false
        });
        converted.on('select', function(updateServer) {
            if (this.value == 'hiatus') {
                Ext.select('.cancelled').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.current').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.upcoming').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.hiatus').each(function(el) {
                    el.setDisplayed('block');
                });
            } else if (this.value == 'current') {
                Ext.select('.cancelled').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.hiatus').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.upcoming').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.current').each(function(el) {
                    el.setDisplayed('block');
                });
            } else if (this.value == 'cancelled') {
                Ext.select('.current').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.hiatus').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.upcoming').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.cancelled').each(function(el) {
                    el.setDisplayed('block');
                });
            } else if (this.value == 'upcoming') {
                Ext.select('.current').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.hiatus').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.cancelled').each(function(el) {
                    el.setDisplayed('none');
                });
                Ext.select('.upcoming').each(function(el) {
                    el.setDisplayed('block');
                });
            } else if (this.value == 'all') {
                Ext.select('.current').each(function(el) {
                    el.setDisplayed('block');
                });
                Ext.select('.hiatus').each(function(el) {
                    el.setDisplayed('block');
                });
                Ext.select('.upcoming').each(function(el) {
                    el.setDisplayed('block');
                });
                Ext.select('.cancelled').each(function(el) {
                    el.setDisplayed('block');
                });
            }
        });
    }
})


function initLightbox() {
    Ext.select('.lbOn').each(
            function(el) {
                el.removeClass('lbOn');
                var loadHref = el.getAttributeNS('ext', 'href');
                el.on('click', function(e) {
                    e.preventDefault();
                    var winHeight;
                    if (loadHref.search("_registration") > -1) {
                        winHeight = 240;
                    } else if (loadHref.search("_compliment") > -1) {
                        winHeight = 400;
                    } else if (loadHref.search("login") > -1) {
                        winHeight = 130;
                    } else {
                        winHeight = 300;
                    }
                    var winWidth = 540;
                    var panel = new Ext.Panel({
                        autoLoad: {
                            url: loadHref,
                            nocache: true,
                            autoHeight: true
                        },
                        hideBorders: true,
                        bodyStyle: 'padding: 10px;',
                        bodyBorder: false,
                        border: false
                    });
                    var win = generateLightboxWindow(winWidth, winHeight, panel, 'modalWindow', '', true);
                    win.show();
                });
            });
}
Ext.onReady(initLightbox);


//Promos Code
//lightbox gone wild

/*-------------------------------GLOBAL VARIABLES------------------------------------*/

var detect = navigator.userAgent.toLowerCase();
var OS,browser,version,total,thestring;

/*-----------------------------------------------------------------------------------------------*/

//Browser detect script origionally created by Peter Paul Koch at http://www.quirksmode.org/

function getBrowserInfo() {
    if (checkIt('konqueror')) {
        browser = "Konqueror";
        OS = "Linux";
    }
    else if (checkIt('safari')) browser = "Safari"
    else if (checkIt('omniweb')) browser = "OmniWeb"
        else if (checkIt('opera')) browser = "Opera"
            else if (checkIt('webtv')) browser = "WebTV";
                else if (checkIt('icab')) browser = "iCab"
                    else if (checkIt('msie')) browser = "Internet Explorer"
                        else if (!checkIt('compatible')) {
                                browser = "Netscape Navigator"
                                version = detect.charAt(8);
                            }
                            else browser = "An unknown browser";

    if (!version) version = detect.charAt(place + thestring.length);

    if (!OS) {
        if (checkIt('linux')) OS = "Linux";
        else if (checkIt('x11')) OS = "Unix";
        else if (checkIt('mac')) OS = "Mac"
            else if (checkIt('win')) OS = "Windows"
                else OS = "an unknown operating system";
    }
}

function checkIt(string) {
    place = detect.indexOf(string) + 1;
    thestring = string;
    return place;
}

/*-----------------------------------------------------------------------------------------------*/


/*Global Utils
 -------------------------------------------------------------------------------------*/

/* Watchlink goodies */
function openerBrowse(url) {
    if (opener != null) {
        opener.document.location = url;
        opener.focus();
    }
    return false;
}

function timedPageReload() {
    setTimeout("window.location.reload()", 1740000);
}

function clearText(thefield) {

    if (thefield.defaultValue == thefield.value) {
        thefield.value = ""
    }
    if (thefield.defaultValue == 'password') {
        thefield["type"] = 'password';
    }
}

/*Ajax
 ------------------------------------------------------------------------------------------------*/
var DEFAULT_ERROR_TEXT = "Apologies, our system has encountered an error.";

/* testing to make sure that the URL
 * - contains a domain
 * - contains something close to a valid TLD
 * - if a protocol exists it is http://, https://, ftp://
 * - path contains no spaces
 */
function isValidUrl(url) {
    var regExp = /^\s*((http(s)?|ftp):\/\/)?([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,6}(\/[\S]*)?\s*$/i;
    return regExp.test(url);
}


/* make an ajax request to the server
 * url - destination for the request
 * requestParams - hash of http POST parameters
 * successFunc - callback function for successful reply
 * errorFunc - callback function for unsuccessful reply
 */
function makeAjaxPost(url, postParams, successFunc, errorFunc) {
    return makeAjaxRequest(url, "POST", postParams, successFunc, errorFunc);
}

function makeAjaxGet(url, getParams, successFunc, errorFunc) {
    return makeAjaxRequest(url, "GET", getParams, successFunc, errorFunc);
}

function makeAjaxRequest(url, method, params, successFunc, errorFunc) {
    var canonicalizedUrl = url.replace(/%20/g, "_");
    return Ext.Ajax.request(
    {
        url: canonicalizedUrl,
        method: method,
        params: params,
        headers: {Accept: "application/json"},
        success: successFunc,
        failure: errorFunc,
        disableCaching: false
    });
}

/* escape any javascript
 */
function escapeJs(string) {
    return String.escape(string);
}

function canonicalizeId(id) {
    return (id.toString()).gsub(/_/, '');
}


var srl_TOGGLE_OPEN = "topen";
var srl_TOGGLE_CLOSED = "tog";
var srl_TOGGLE_LINK_SUFFIX = "_tl";
var srl_TOGGLE_CONTENTS_SUFFIX = "_contents";

function togVis(clickedEl) {
    var toggleLinkId = clickedEl.id;
    var contentsId = srl_getToggleContentsId(toggleLinkId);
    var contents = Ext.get(contentsId);
    if (contents.getStyle("display") == "block") {
        contents.setStyle('display', 'none');
    } else {
        contents.setStyle('display', 'block');
    }
    var toggleLink = Ext.get(toggleLinkId);
    if (toggleLink.dom.className == srl_TOGGLE_CLOSED) {
        toggleLink.dom.className = srl_TOGGLE_OPEN;
    } else {
        toggleLink.dom.className = srl_TOGGLE_CLOSED;
    }

    //always return false.  This is a "clever hack" to keep the page from refreshing when links that call this function are clicked
    return false;
}

function srl_getToggleContentsId(linkId) {
    return linkId.replace(srl_TOGGLE_LINK_SUFFIX, srl_TOGGLE_CONTENTS_SUFFIX);
}

function showLogin() {
    document.getElementById("loginForm").style.display = "block";
}

function handleSuccessfulLoginResponse(transport, messageId) {
    var response = Ext.util.JSON.decode(transport.responseText).response;
    if (response.result == "SUCCESS") {
        updatePageForSuccessfulLogin(response, true);
    } else {
        handleFailedLoginResponse(messageId);
    }
}

function updatePageForSuccessfulLogin(response, refreshPage) {
    if (refreshPage) {
        window.location.reload();
    } else {
        Ext.get('profileLinks').update("<li><a href=\"/_user/" + escape(response.username) + "\">My Profile</a></li>")
        Ext.get('loginForm').hide();
    }
}

function handleFailedLoginResponse(messageId) {
    Ext.get(messageId).update("Sorry, your information is incorrect.<br /> Please try again or <a href='/_user/_account/'>create an account</a> or <a href='/_user/_resetpassword'>reset your password</a>.")
}

function makeLoginRequest(params, messageId) {
    return makeAjaxPost("/_user/_login", { username: params['username'], password: params['password']},
            function(transport) {
                handleSuccessfulLoginResponse(transport, messageId);
            }, function() {
        handleFailedLoginResponse(messageId);
    }
            );
}

function login(params) {
    makeLoginRequest(params, 'loginMessages');
}

function loginFromRestrictedPage(params) {
    makeLoginRequest(params, 'restrictedLoginMessages');
}

function loginFromCreateAccountPage(params) {
    makeAjaxPost("/_user/_login", { username: params['username'], password: params['password']},
            handleSuccessfulLoginFromCreateAccountPageResponse, handleFailedLoginFromCreateAccountPageResponse);
}

function handleSuccessfulLoginFromCreateAccountPageResponse(transport) {
    var response = transport.responseText.evalJSON().response;
    if (response.result == "SUCCESS") {
        window.location.href = Ext.get('createAccountLoginFormDestination').dom.value;
    } else {
        handleFailedLoginFromCreateAccountPageResponse(transport);
    }
}

function handleFailedLoginFromCreateAccountPageResponse(transport) {
    Ext.get('createAccountLoginFormMessages').update("Sorry, your information is incorrect. Please try again.");
}

function getCategoryWatchLinksRequest(elmId) {
    var url = atomLink + "/_season/" + getUrlEncodedCategoryIdFromHtmlId(elmId) + "/_watchlinks";
    var elmUpdater = new LinkBoxElementUpdater(elmId);
    elmUpdater.update({
        url: url,
        callback: function() {
            initLightbox();
            Playlist.attachToAnchors();
            addLinkForm.attachToEdits();
        }
    });
}

function displayCategoryLoadingMessage(elmId) {
    Ext.get(elmId).update(Ext.get(elmId).dom.innerHTML + "<p style='clear: left; margin-left: 10px; padding-bottom: 4px;'><img src='/_img/ajax_loader.gif' /></p>");
}

function handleGetCategoryWatchLinksFailure(elmId) {
    Ext.get(elmId).update(categoryWatchLinksError);
}

var categoryWatchLinksError = "An error has occurred. Please refresh the page";

function getUrlEncodedCategoryIdFromHtmlId(elmId) {
    return escape(Ext.util.Format.htmlDecode(elmId.replace("wlS_", ""))).replace(/\//g, "%2F").replace(/\+/g, "%2B");
}

/*
 * addComplimentRequest creates and sends the ajax request for adding a new compliment
 */
function addComplimentRequest(values) {
    makeAjaxPost("/_user/" + values["complimentee"] + "/_compliment",
    {action: "add", message: values["message"]
        , recaptcha_challenge_field: values["recaptcha_challenge_field"]
        , recaptcha_response_field: values["recaptcha_response_field"]},
            handleComplimentResponse, handleComplimentResponse);
}

function handleComplimentResponse(transport) {
    Ext.get('complimentBody').update(transport.responseText);
}

function removeComplimentRequest(id, complimentee) {
    makeAjaxPost("/_user/" + complimentee + "/_compliment",
    {action: "delete", id: id},
            handleRemoveComplimentResponse, handleRemoveComplimentResponse);
}

function handleRemoveComplimentResponse() {
    window.location.reload();
}


function srl_setCookie(name, value, expires, path, domain, secure) {
    var cookie_string = name + "=" + escape(value);
    if (expires) {
        cookie_string += "; expires=" + expires.toGMTString();
    }
    if (path) {
        cookie_string += "; path=" + escape(path);
    }
    if (domain) {
        cookie_string += "; domain=" + escape(domain);
    }
    if (secure) {
        cookie_string += "; secure";
    }
    document.cookie = cookie_string;
}

function srl_getCookie(cookie_name) {
    var results = document.cookie.match('(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
    if (results) {
        return ( unescape(results[2]) );
    } else {
        return null;
    }
}

function getLinksForSubcategory(elm) {
    var elmId = elm.id;
    elmId = elmId.substring(0, elmId.lastIndexOf("_tl"));
    var subcatIds = elmId.split("_");
    var url = atomLink + "/_season/" + subcatIds[1] + "/_episode/" + subcatIds[3];
    var elmUpdater = new LinkBoxElementUpdater(elmId);
    elmUpdater.update({
        url: url,
        callback: handleGetLinksResponse
    });
    return false;
}

function handleGetLinksResponse(elmId, success) {
    if (success) {
        initLightbox();
        addLinkForm.attachToEdits();
        Playlist.attachToAnchors();
    } else {
        displaySubcategoryLinksFailure(elmId);
    }
}

function displaySubcategoryLinksFailure(elm) {
    elm.update('<div class="linkError" style="font-weight: normal; color: #666;">Sorry, this episode was deleted.</div>');
}


function flagPost(postId, isRemove) {
    var action = "add";
    if (isRemove == 'true') {
        action = "delete";
    }
    makeAjaxPost("/_post/" + postId + "/_flag", {action:action}, new function() {
        updateFlag(postId);
    }, new function() {
        updateFlag(postId);
    });
}

function updateFlag(postId) {
    document.getElementById("flagReviewLink" + postId).innerHTML = "";
}

function refreshingPostDelete(postId) {
    makeAjaxPost("/_post/" + postId, {action: "delete"}, handlePostDeleteResponse, handlePostDeleteResponse);
}

function handlePostDeleteResponse() {
    document.location.reload();
}

function markNaughty(postId) {
    makeAjaxPost("/_inappropriate/_post/" + postId, {action: "add"}, function() {
        handleNaughtyPostSuccess(postId)
    }, function() {
        handleNaughtyPostFailure(postId)
    });
}

function handleNaughtyPostSuccess(postId) {
    replaceElementWith('naughtyLink' + postId, {html:'reported'});
}

function handleNaughtyPostFailure(postId) {
    replaceElementWith('naughtyLink' + postId, {html:'Error Marking Inappropriate'});
}

/*Filterlist
 ----------------------------------------------------------------------------------------------------*/
function filterlist(selectobj) {
    this.selectobj = selectobj;
    this.flags = 'i';
    this.match_text = true;
    this.match_value = false;
    this.show_debug = false;

    this.init = function() {
        if (!this.selectobj) return this.debug('selectobj not defined');
        if (!this.selectobj.getElementsByTagName('li')) return this.debug('selectobj.elements not defined');
        this.listcopy = new Array();
        if (this.selectobj && this.selectobj.getElementsByTagName('li')) {
            for (var i = 0; i < this.selectobj.getElementsByTagName('li').length; i++) {
                this.listcopy[i] = document.createElement('li');
                this.listcopy[i].innerHTML = selectobj.getElementsByTagName('li')[i].innerHTML;
            }
        }
    };

    //--------------------------------------------------
    this.reset = function() {
        this.set('');
    }

    //--------------------------------------------------
    this.set = function(pattern) {
        var loop = 0, index = 0, regexp, e;
        if (!this.selectobj) return this.debug('selectobj not defined');
        if (!this.selectobj.getElementsByTagName('li')) return this.debug('selectobj.options not defined');
        this.selectobj.innerHTML = '';
        try {
            regexp = new RegExp(pattern, this.flags);
        } catch(e) {
            if (typeof this.hook == 'function') {
                this.hook();
            }
            return;
        }

        var count = 1;

        for (loop = 0; loop < this.listcopy.length; loop++) {
            var item = this.listcopy[loop];
            if ((this.match_text && regexp.test(item.getElementsByTagName('a')[0].firstChild.nodeValue)) ||
                (this.match_value && regexp.test(option.value))) {
                var match = document.createElement('li')
                match.innerHTML = item.innerHTML;
                this.selectobj.appendChild(match);
                count++;
            }
        }

        if (count <= 1) {
            var match = document.createElement('li')
            match.innerHTML = '<p>Sorry, no matches.</p>';
            this.selectobj.appendChild(match);
        }

        if (typeof this.hook == 'function') {
            this.hook();
        }
    };

    this.set_ignore_case = function(value) {
        if (value) {
            this.flags = 'i';
        } else {
            this.flags = '';
        }
    };


    this.debug = function(msg) {
        if (this.show_debug) {
            alert('FilterList: ' + msg);
        }
    };

    this.init();

}

var indexLoader = {
    load: function() {
        if (Ext.get('contentLoading')) {
            Ext.get('contentLoading').setStyle('display', 'none');
            Ext.get('aFilters').setStyle('display', 'block');
            Ext.get('filterForm').setStyle('display', 'block');
        }
    }
}
Ext.onReady(indexLoader.load);


function FeaturedSlots(firstBlockNum, path) {
    var _min = 0;
    var _max = 7;
    var _index = 0;
    var nextFetch = firstBlockNum < _max ? firstBlockNum + 1 : _min + 1;
    var showBlockClasses = ['show', 'item', 'clearfix'];
    var listElement = Ext.get('featuredBlock');
    var chooser = new Chooser(listElement, doPrev, doNext, _max);
    updateBlock();
    function Chooser(listElement, prevFunction, nextFunction, maxSlides) {
        var hideClass = 'hide';
        var chooserElement = Ext.DomHelper.insertAfter(listElement, {tag: 'p', cls:'slidecounter', children:[
            {
                tag:'a',
                href:'#',
                html:'previous',
                cls:hideClass
            },
            {
                tag:'span'
            },
            {
                tag:'a',
                href:'#',
                html:'next'
            }
        ]}, true);
        var prev = new Ext.Element(chooserElement.query('a')[0]);
        var next = new Ext.Element(chooserElement.query('a')[1]);
        prev.on('click', prevFunction, this, {preventDefault: true});
        next.on('click', nextFunction, this, {preventDefault: true});
        var counter = chooserElement.child('span');
        var workingElement = Ext.DomHelper.insertAfter(chooserElement,
        {tag: 'p', cls:'slidecounter featuredLoading ' + hideClass, html: "loading"}, true);
        this.update = function(slideNum) {
            chooserElement.removeClass(hideClass);
            workingElement.addClass(hideClass);
            if (slideNum == maxSlides) {
                next.addClass(hideClass);
            } else {
                next.removeClass(hideClass);
            }
            if (slideNum == 1) {
                prev.addClass(hideClass);
            } else {
                prev.removeClass(hideClass);
            }
            counter.update(slideNum + " of " + maxSlides);
        };
        this.working = function() {
            chooserElement.addClass(hideClass);
            workingElement.removeClass(hideClass);
        };
    }

    function doPrev() {
        if (_index != _min) {
            _index--;
        }
        updateAll();
    }

    function doNext() {
        if (_index < _max) {
            _index++;
        }
        updateAll();
    }

    function updateAll() {
        if (listElement.query('li').length <= _index) {
            fetch();
        } else {
            updateBlock();
        }
    }

    // TODO: if this method doesn't use featuredElement why is it still in the parameter list?
    function updateBlock(featuredElement) {
        showBlock();
        chooser.update(_index + 1);
    }

    function showBlock() {
        var i = _min;
        listElement.select('li').each(function(block) {
            if (_index == i++) {
                block.addClass(showBlockClasses);
            } else {
                block.removeClass(showBlockClasses);
            }
        });
    }

    function fetch() {
        chooser.working();
        makeAjaxGet("/_featuredblock/" + path + "/" + nextFetch + ".html", null, handleFetchSuccess, handleFetchFail);
        if (nextFetch == _max) {
            nextFetch = 1;
        } else {
            nextFetch++;
        }
    }

    function handleFetchSuccess(transport) {
        Ext.DomHelper.append(listElement, {tag: 'li', html: transport.responseText}, true);
        updateBlock();
    }

    function handleFetchFail() {
        doPrev();
    }
}

/*--------------------------------------------------------------------------
 *  Smooth Scroller Script, version 1.0.1
 *  (c) 2007 Dezinerfolio Inc. <midart@gmail.com>
 *
 *  For details, please check the website : http://dezinerfolio.com/
 *
 /*---#set($featuredPosts = $popularPosts)
 #parse("includes/featuredPostsList.vm")-----------------------------------------------------------------------*/

var Scroller = {
    // control the speed of the scroller.
    // dont change it here directly, please use Scroller.speed=50;
    speed:15,

    // returns the Y position of the div
    gy: function (d) {
        gy = d.offsetTop;
        if (d.offsetParent) while (d = d.offsetParent) gy += d.offsetTop;
        return gy;
    },

    // returns the current scroll position
    scrollTop: function () {
        body = document.body;
        d = document.documentElement;
        if (body && body.scrollTop) return body.scrollTop;
        if (d && d.scrollTop) return d.scrollTop;
        if (window.pageYOffset) return window.pageYOffset;
        return 0;
    },

    // attach an event for an element
    // (element, type, function)
    add: function(event, body, d) {
        if (event.addEventListener) return event.addEventListener(body, d, false);
        if (event.attachEvent) return event.attachEvent('on' + body, d);
    },

    // kill an event of an element
    end: function(e) {
        if (window.event) {
            window.event.cancelBubble = true;
            window.event.returnValue = false;
            return;
        }
        if (e.preventDefault && e.stopPropagation) {
            e.preventDefault();
            e.stopPropagation();
        }
    },

    // move the scroll bar to the particular div.
    scroll: function(d) {
        i = window.innerHeight || document.documentElement.clientHeight;
        h = document.body.scrollHeight;
        a = Scroller.scrollTop();
        if (d > a)
            if (h - d > i)
                a += Math.ceil((d - a) / Scroller.speed);
            else
                a += Math.ceil((d - a - (h - d)) / Scroller.speed);
        else
            a = a + (d - a) / Scroller.speed;
        window.scrollTo(0, a);
        if (a == d || Scroller.offsetTop == a)clearInterval(Scroller.interval);
        Scroller.offsetTop = a;
    },
    // initializer that adds the renderer to the onload function of the window
    init: function() {
        Scroller.add(window, 'load', Scroller.render);
    },

    // this method extracts all the anchors and validates then as # and attaches the events.
    render: function() {
        var a = '';
        if (document.getElementById('scrollList')) {
            a = document.getElementById('scrollList').getElementsByTagName('a');
        }
        Scroller.end(this);
        if (a.length) {
            for (i = 0; i < a.length; i++) {
                l = a[i];
                if (l.href && l.href.indexOf('#') != -1 && ((l.pathname == location.pathname) || ('/' + l.pathname == location.pathname))) {
                    Scroller.add(l, 'click', Scroller.end);
                    l.onclick = function() {
                        Scroller.end(this);
                        l = this.hash.substr(1);
                        a = document.getElementsByTagName('a');
                        for (i = 0; i < a.length; i++) {
                            if (a[i].name == l) {
                                clearInterval(Scroller.interval);
                                Scroller.interval = setInterval('Scroller.scroll(' + Scroller.gy(a[i]) + ')', 10);
                            }
                        }
                    };
                }
            }
        }
    }
};
// invoke the initializer of the scroller
if (checkIt('msie') != 26) {
    Scroller.init();
}

var LoginState = function() {
    var srLoginState;
    var facebookActiveState;

    function setLoginState(srLoggedIn, facebookActive) {
        if (srLoginState == undefined) srLoginState = srLoggedIn;
        if (facebookActiveState == undefined) facebookActiveState = facebookActive;
    }

    return {
        isLoggedIn : function() {
            return srLoginState;
        },
        isFbActive : function() {
            return facebookActiveState;
        },
        init : function(srState, fbState) {
            setLoginState(srState, fbState);
        }
    };
}();


/*------------------------------------------------------------
 *						END OF CODE
 /*-----------------------------------------------------------*/

var VoteHandler = function() {
    function handleFetchSuccess(transport) {
        var parsed = Ext.util.JSON.decode(transport.responseText);
        var parsedVotes = [].concat(parsed.voteInfo.votes);
        for (var i = 0; i < parsedVotes.length; i++) {
            var postVote = parsedVotes[i];
            var voteBlock = Ext.select(".voteBlock" + postVote.id);
            if (voteBlock != null) {
                voteBlock.each(function(el, composite, index) {
                    el.update(makePostVoteBlockHtml(postVote.count, postVote.id, postVote.voted));
                });
            }
        }
    }

    function handleFetchFail(transport) {
        //do nothing if there was an error getting vote data
    }

    function makePostVoteBlockHtml(count, id, voted) {
        var votePlural = (count == 1 ? ' vote' : ' votes');
        var postVoteHtml = "<span><span class='voteCount'>" + count + votePlural + "</span>";
        if (voted == "true") {
            postVoteHtml += "<span class='voted'>I voted!</span>";
        } else {
            postVoteHtml += "<a class=\"iLikeIt\" href='#' onclick='VoteHandler.addVote(" + id + "); return false;'>I Like It!</a>";
        }
        return postVoteHtml + "</span>";
    }

    function handleAddVoteSuccess(postId) {
        var voteBlock = Ext.select(".voteBlock" + postId);
        if (voteBlock != null) {
            voteBlock.each(function(el, composite, index) {
                var countSpan = el.child("span[class='voteCount']", true);
                var currentCount = countSpan.innerHTML;
                currentCount = parseInt(currentCount) + 1;
                el.update(makePostVoteBlockHtml(currentCount, postId, "true"));
            });
        }
    }

    function handleAddVoteFail() {
        //do nothing
    }

    return {
        fetch : function(postIds) {
            makeAjaxGet("/_vote/" + postIds.join(","), {}, handleFetchSuccess, handleFetchFail);
        },
        addVote : function(postId) {
            makeAjaxPost("/_vote/" + postId, {action:"add"}, function() {
                handleAddVoteSuccess(postId);
            }, handleAddVoteFail);
        }
    };
}();

var ModuleFilters = function() {
    function setFilter(e) {
        e.preventDefault();
        var onLink = e.target;
        updateLinks(onLink);
        updateBlocks(onLink);
    }

    function updateLinks(onLink) {
        var uls = Ext.select(".dynFilters");
        uls.each(function(el) {
            el.select('a').each(function(el) {
                el.removeClass('on');
            });
        });
        onLink.className = 'on';
    }

    function updateBlocks(onLink) {
        Ext.select('.setParent').each(function(el) {
            el.setVisibilityMode(Ext.Element.DISPLAY);
            el.hide();
        });
        var href = onLink.getAttribute('href');
        var displayID = href.substring(href.indexOf('#') + 1);
        Ext.get(displayID).show(true);
    }

    return {init: function() {
        var filtersBlock = Ext.select(".dynFilters");
        filtersBlock.show();
        Ext.select('.filterLink').each(
                function(el) {
                    el.addListener('click', function(e) {
                        setFilter(e);
                    });
                });
    }};
}();
Ext.onReady(ModuleFilters.init);

Ext.Updater.defaults.loadScripts = true;

function EpisodeTracker(atomLink, store) {
    var episodeTrackerParent;
    var episodeComboHolder;
    var playLastViewedContainer;
    var playNextEpisode;
    var episodeDropdownConverted;
    var guideCombo;

    init();

    function init() {
        episodeTrackerParent = Ext.get('episodeTrackerParent_' + atomLink);
        episodeComboHolder = episodeTrackerParent.child('.episodeComboHolder', true);
        playLastViewedContainer = episodeTrackerParent.child('.playLastViewedContainer', true);
        playNextEpisode = episodeTrackerParent.child('.playNextEpisode', true);
        episodeDropdownConverted = 'episodeDropdownConverted_' + atomLink;
        guideCombo = new Ext.form.ComboBox({
            id: episodeDropdownConverted,
            displayField: 'text',
            valueField: 'value',
            mode: 'local',
            store: store,
            applyTo: episodeComboHolder,
            typeAhead: true,
            triggerAction: 'all',
            editable: false,
            width:250,
            forceSelection: true,
            emptyText:'select the episode you last viewed...'
        });
        guideCombo.on('select', function(updateServer) {
            if (this.value != '') {
                var values = this.value.split("|");
                setEpisodeTracker(values[0], values[1], updateServer);
                playLastViewedContainer.innerHTML = '<a onclick="EpisodeTrackerManager.get(\'' + atomLink + '\').updateEpisodeDropdown(this)" href="' + atomLink + '/' + values[0] + '/' + values[1] + '/_watchlinkviewer" target="_blank" class="playLastViewed">Play</a>';
            }
        });
    }

    this.setValue = function(value) {
        guideCombo.setValue(value);
    };

    this.makeVisible = function() {
        episodeComboHolder.style.visibility = 'visible';
    };

    function setEpisodeTracker(categoryId, subcategoryId, updateServer) {
        playNextEpisode.innerHTML = '<p class="loader injected">loading . . .</p>';
        if (updateServer) {
            makeAjaxPost(atomLink + "/_tracker/" + categoryId + "/" + subcategoryId, {action: 'add'}, handleEpisodeTrackerSuccess, handleEpisodeTrackerFailure);
        } else {
            makeAjaxGet(atomLink + "/_nextepisode/" + categoryId + "/" + subcategoryId, {}, handleEpisodeTrackerSuccess, handleEpisodeTrackerFailure);
        }
    }

    this.updateEpisodeTracker = function() {
        episodeTrackerParent.getUpdater().update({url: atomLink + "/_tracker/"});
    };

    function parseEpisodeFromLink(link) {
        var theParts = link.href.split('/');
        var idx = theParts.length;
        return theParts[idx - 3] + "|" + theParts[idx - 2];
    }

    this.updateEpisodeDropdown = function(el) {
        var optionValue = parseEpisodeFromLink(el);
        this.setEpisodeDropdown(optionValue, episodeDropdownConverted);
    }

    this.setEpisodeDropdown = function(optionValue) {
        this.setValue(optionValue);
        guideCombo.fireEvent("select", false);
    }

    function handleEpisodeTrackerSuccess(transport) {
        var response = Ext.util.JSON.decode(transport.responseText).response;
        var nextSeasonId = response['nextsId'];
        var nextEpisodeId = response['nexteId'];
        var nextEpisodeTitle = response['nexteTitle'];
        var nextTitle = response['nextTitle'];
        var consecutiveEpisodes = response['consecutive'];
        var hasLink = response['hasLink'];
        var atomLink = response['atomId'];
        var userName = response['user'];
        if (nextSeasonId == null) {
            playNextEpisode.innerHTML = '<a class="profileLink injected" href=\"/_user/' + userName + '\">Stay tuned for updates</a>';
        } else {
            playNextEpisode.innerHTML = '<a class="injected" title="' + nextEpisodeTitle + '" target="_blank" onclick="EpisodeTrackerManager.get(\'' + atomLink + '\').updateEpisodeDropdown(this); pageTracker._trackPageview(\'/activity/episodeguide/upnext' + atomLink + '/\')" href="' + atomLink + '/' + nextSeasonId + '/' + nextEpisodeId + '/_watchlinkviewer' + '">' + nextTitle + '</a>';
            if (consecutiveEpisodes == 'false') {
                episodeTrackerParent.child(".episodeNext", true).innerHTML = 'Next Available Episode:';
            } else {
                episodeTrackerParent.child(".episodeNext", true).innerHTML = 'Up Next:';
            }

        }
        if (hasLink == 'false') {
            playLastViewedContainer.innerHTML = '<span class="playLastViewed inactive"></span>';
        }
    }

    function handleEpisodeTrackerFailure() {
        EpisodeTracker.updateEpisodeTracker("episodeTrackerParent_" + atomLink);
    }
}

var EpisodeTrackerManager = function() {
    var episodeTrackers = {};
    return {
        create : function(atomLink, store) {
            var episodeTracker = new EpisodeTracker(atomLink, store);
            episodeTrackers[atomLink] = episodeTracker;
            return episodeTracker;
        },
        get : function(atomLink) {
            var episodeTracker = episodeTrackers[atomLink];
            if (episodeTracker == null) {
                return new NullEpisodeTracker();
            }
            return episodeTracker;
        }
    }
}();

function NullEpisodeTracker() {
    this.setValue = function() {
    };
    this.makeVisible = function() {
    };
    this.updateEpisodeTracker = function() {
    };
    this.updateEpisodeDropdown = function() {
    };
    this.setEpisodeDropdown = function() {
    };
}

var LinkBoxElementUpdater = Ext.extend(Ext.Updater, {
    showLoading: function() {
        displayCategoryLoadingMessage(this.getEl().id);
    },
    failure: function() {
        displaySubcategoryLinksFailure(this.getEl().id);
    }
});

var PostForm = function() {
    var nameKey = 'name';
    var tagsId = 'postTags';
    var tagInput;
    var form = 'createReviewForm';
    var nextId;
    var selectedTags = {
        tagsArray: new Array(),
        init: function() {
            if (Ext.get('primaryTagInput')) {
                selectedTags.add(Ext.get('primaryTagInput').getValue());
            }
            Ext.get(tagsId).select('li').each(function(el) {
                var name = el.child('input').getValue();
                selectedTags.add(name);
                attachDeleteEvent(new Ext.Element(el.dom), name);
            });
        },
        add: function(name) {
            selectedTags.tagsArray.push(name);
        },
        remove: function(name) {
            selectedTags.tagsArray.remove(name);
        },
        length: function() {
            return selectedTags.tagsArray.length;
        },
        contains: function(name) {
            return selectedTags.tagsArray.indexOf(name) != -1;
        }
    };
    this.init = function() {
        Ext.get(form).on('submit', function(event, element) {
            var value = Ext.get('recaptcha_response_field').getValue();
            if (value == "") {
                event.preventDefault();
            } else {
                limitTextArea();
                var seasonsOrEpisodes = Ext.get('seasonsOrEpisodes');
                if (seasonsOrEpisodes != null) {
                    var seasonOrEpisodes = seasonsOrEpisodes.getValue().split('|');
                    Ext.get('season').set({'value' : seasonOrEpisodes[0]});
                    Ext.get('episode').set({'value' : seasonOrEpisodes[1]});
                }
            }
        });
        Ext.get('reviewContent').on({
            'keypress': {fn: limitTextArea},
            'keyup':    {fn: limitTextArea}
        });
        tagInput = new Ext.form.ComboBox({
            applyTo: 'tagInput',
            width: 250,
            hideTrigger: true,
            store: new Ext.data.Store({
                proxy: new Ext.data.HttpProxy({
                    url: '/_search',
                    method: 'GET'
                }),
                baseParams: {outputFormat: 'xml'},
                reader: new Ext.data.XmlReader({
                    record: 'res'
                }, [
                    {
                        name: 'name'
                    }
                ])
            }),
            displayField: nameKey,
            mode: 'remote',
            queryParam:'searchQuery',
            forceSelection: true,
            typeAhead: true,
            typeAheadDelay: 100,
            height: 14,
            emptyText: 'add a topic ...',
            enableKeyEvents: true,
            onSelect:
                    function(record) {
                        this.emptyText = '';
                        this.clearValue();
                        this.collapse();
                        var name = record.get(nameKey);
                        if (!selectedTags.contains(name)) {
                            disability(selectedTags.length() + 1);
                            var newItem = Ext.DomHelper.append(tagsId, {tag: 'li', cls: 'tag', id: 'tagItem' + nextId++,
                                children: [
                                    {
                                        tag: 'span',
                                        html: name
                                    },
                                    {
                                        tag: 'input',
                                        value: name,
                                        name: 'atomId',
                                        type: 'hidden'
                                    },
                                    {
                                        tag: 'a',
                                        href: '#',
                                        html:'X'
                                    }
                                ]
                            }, true);
                            attachDeleteEvent(newItem, name);
                            selectedTags.add(name);
                        }
                    }
        });
        selectedTags.init();
        var numTags = selectedTags.length();
        disability(numTags);
        nextId = numTags + 1
        tagInput.on('beforequery', function(queryEvent) {
            var query = queryEvent.query;
            if (query.length > 2) {
                queryEvent.query = "TITLE:" + query + "*";
            } else {
                queryEvent.cancel = true;
            }
        });
    };
    function disability(size) {
        if (size >= 5) tagInput.disable();
    }

    function attachDeleteEvent(newItem, name) {
        newItem.child('a').on('click', function() {
            newItem.remove();
            selectedTags.remove(name);
            tagInput.enable();
        }, newItem, {preventDefault: true});
    }

    function limitTextArea() {
        limitCharacters('reviewContent', 40000);
    }

};
Ext.onReady(function() {
    if (Ext.get('postForm')) {
        new PostForm().init();
    }
});

function limitCharacters(id, maxSize) {
    var textElm = Ext.get(id);
    var currentSize = textElm.dom.value.length;
    if (currentSize >= maxSize) {
        textElm.dom.value = textElm.dom.value.substring(0, maxSize);
    }
}

function loadScript(src) {
    newjs = document.createElement("script");
    newjs.src = src;
    newjs.type = 'text/javascript';
    head = document.getElementsByTagName("head")[0];
    head.appendChild(newjs);
}

function generateCaptcha(tabIndex) {
    Recaptcha.create("6LeWhgAAAAAAAC53fL6M6U2XMMGHsZodhzWnfNaK",
            document.getElementById("recaptcha_div"), {
        theme: "white",
        tabindex: tabIndex
    })
}

function waitForCaptcha(tabIndex) {
    if ("undefined" == typeof(Recaptcha)) {
        setTimeout(function() {
            waitForCaptcha(tabIndex);
        }, 1000);
    } else {
        generateCaptcha(tabIndex);
    }
}

Ext.onReady(function() {
    Ext.select('.imageBox').each(function(el) {
        if (el.getWidth() > 280) {
            var paragraph = el.next('p');
            if (paragraph) {
                paragraph.addClass('clear');
            }
        }
    });
});

var SREmailConfirmer = {
    send: function(username) {
        makeAjaxGet("/_user/" + username + "/_confirm", "destination=" + window.location, null, null);
        Ext.get('modalConfirmEmail').update("<p>You have been sent an email. Please check your inbox and click the confirmation link!</p>");
    }
};

var SubscriptionHandler = function() {
    var canSubscribe = false;
    var hrefVal = "#";

    function handleSubscriptionsResponse(transport) {
        var response = Ext.util.JSON.decode(transport.responseText);
        canSubscribe = response.subscriptionInfo.canSubscribe == "true";
        var subscriptionInfo = [].concat(response.subscriptionInfo.subscriptions);
        if (!canSubscribe) {
            hrefVal = '/_user/_registration';
        }
        for (var i = 0; i < subscriptionInfo.length; i++) {
            var info = subscriptionInfo[i];
            var postElement = Ext.select('.postid_' + info.postId);
            postElement.each(function(element) {
                updateSubscribeLink(info.subscribed == "true", element.child(".postSubscriber"), info.postId);
            });
        }
        if (!canSubscribe) {
            initLightbox();
        }
    }

    function updateSubscribeLink(isSubscribed, element, postId) {
        var prefix = isSubscribed ? "Uns" : "S";
        var tooltip = isSubscribed ? "<span>Stop notifying me of new<br />comments via email</span>" : "<span>Notify me of new<br />comments via email</span>";
        var classVal = 'post' + prefix + 'ubscribe';
        var onClick = 'SubscriptionHandler.subscribe(' + (!isSubscribed) + ', this, ' + postId + ');return false;';

        if (!canSubscribe) {
            classVal += ' lbOn';
            onClick = "";
        }
        element.update('<a href="' + hrefVal + '" onclick="' + onClick + '" class="info ' + classVal + '">' + prefix + 'ubscribe' + tooltip + '</a>');
    }

    function subscribe(subscribe, element, postId) {
        var parentEl = Ext.get(element).parent();
        var message;
        var actionVal;
        if (subscribe) {
            message = 'Subscribing';
            actionVal = 'add';
        } else {
            message = 'Unsubscribing';
            actionVal = 'delete';
        }
        parentEl.update("<span class='postSubscriptionLoading'>" + message + "</span>");
        makeAjaxPost("/_subscription/_post/" + postId, {action: actionVal}, function() {
            updateSubscribeLink(subscribe, parentEl, postId)
        }, function() {
            parentEl.update('Error');
        });
    }

    return {
        init : function(postIds) {
            makeAjaxGet("/_subscription/_post/" + postIds.join(","), null, handleSubscriptionsResponse, function() {
                Ext.select(".postSubscriber").update('Error')
            });
        },
        subscribe: subscribe
    };
}();

function LinkTvControls(seasons, episodes, selectedSeason, selectedEpisode) {
    var seasonCombo;
    var episodeCombo;
    renderTvControls();
    if (seasons.length > 0) {
        document.getElementById('addWatchLinkForm').style.display = "block";
        document.getElementById('addCatMessage').style.display = "none";
    } else {
        document.getElementById('addWatchLinkForm').style.display = "none";
        document.getElementById('addCatMessage').style.display = "block";
    }

    function buildSeasonCombo() {
        seasonCombo = new Ext.form.ComboBox({
            store:  new Ext.data.SimpleStore({
                fields: ['seasonValue', 'seasonName'],
                data : seasons
            }),
            id: 'categoryDropdownConverted',
            displayField: 'seasonName',
            valueField: 'seasonValue',
            mode: 'local',
            applyTo: 'addWatchLinkSeasonNumber',
            typeAhead: true,
            triggerAction: 'all',
            editable: false,
            width:300,
            forceSelection: true,
            emptyText:'Select a Season...'
        });
        seasonCombo.on('select', function(box, record, index) {
            episodeCombo.destroy();
            document.getElementById('hiddenSeason').setAttribute('value', record.get('seasonValue'));
            buildEpisodeCombo(index);
        });
    }

    function buildEpisodeCombo(index) {
        episodeCombo = new Ext.form.ComboBox({
            store:  new Ext.data.SimpleStore({
                fields: ['episodeValue','episodeName'],
                data : index < 0 ? [
                    []
                ] : episodes[index]
            }),
            displayField:'episodeName',
            selectOnFocus:true,
            id: 'subcategoryDropdownConverted',
            valueField: 'episodeValue',
            tabIndex: 3,
            mode: 'local',
            renderTo: 'addWatchLinkEpisodeNumber',
            typeAhead: true,
            triggerAction: 'all',
            editable: false,
            width:300,
            forceSelection: true,
            emptyText:'Select an Episode...'
        });
        episodeCombo.on('select', function(box, record, index) {
            document.getElementById('hiddenEpisode').setAttribute('value', record.get('episodeValue'));
        });
    }

    function renderTvControls() {
        buildSeasonCombo();
        var index = nestedIndexOf(seasonCombo.getValue(), seasons);
        buildEpisodeCombo(index);
        if (selectedEpisode != "") {
            episodeCombo.setValue(selectedEpisode);
        }
    }

    function nestedIndexOf(value, listOfArrays) {
        var index = -1;
        for (var i = 0; i < listOfArrays.length; i++) {
            if (listOfArrays[i][0] == value) {
                index = i;
                break;
            }
        }
        return index;
    }
}

Ext.onReady(function() {
    var postIds = new Array();
    Ext.select('.postElement').each(function (postElement) {
        postIds.push(/postid_(\d+)/.exec(postElement.dom.className)[1]);
    });
    if (postIds.length > 0) {
        SubscriptionHandler.init(postIds);
        VoteHandler.fetch(postIds);
    }
});

function makeLockPost(lockType, action) {
    var typeNoun = "lock";
    if ("episode" == lockType) {
        typeNoun = "eplock";
    }
    makeAjaxPost(atomLink + "/_" + typeNoun, {"action" : action}, handleLockPostResponse, handleLockPostResponse);
    return false;
}

function handleLockPostResponse() {
    document.location.reload();
}

function showFacebookFeedDialog(bundleName, template_data, isConnectedCallback, isNotConnectedCallback) {
    execIfConnected(function() {
        FB.Connect.showFeedDialog(FacebookTemplateManager.bundle(bundleName), template_data, [], "",
                FB.FeedStorySize.shortStory, FB.RequireConnect.require, function() {
            pageTracker._trackPageview('/activity/facebook/feedDialog/' + bundleName);
            if (isConnectedCallback) isConnectedCallback();
        });
    }, function() {
        if (isNotConnectedCallback) isNotConnectedCallback();
    });
}

var calendarScroll = {
    position: 3,
    stepForward: undefined,
    stepBackward: undefined,
    sections: undefined,
    CAL_BEGIN: 2,
    CAL_CENTER : 3,
    CAL_END : 4,
    init: function() {
        calendarScroll.sections = Ext.get('watchCalendar').select('.calendarSecion');
        var calendarScrollDiv = Ext.get('calendarScroll');
        calendarScroll.attachScrolltoLinks();
        calendarScrollDiv.show();
    },
    attachScrolltoLinks: function() {
        calendarScroll.stepForward = Ext.get('stepForward');
        calendarScroll.stepForward.on('click', function(event, element) {
            event.preventDefault();
            pageTracker._trackPageview('/activity/calendar/forward');
            calendarScroll.shiftVisibility(true);
        });
        calendarScroll.stepBackward = Ext.get('stepBackward');
        calendarScroll.stepBackward.on('click', function(event, element) {
            event.preventDefault();
            pageTracker._trackPageview('/activity/calendar/back');
            calendarScroll.shiftVisibility(false);
        });
    },
    shiftVisibility: function(forward) {
        if (forward && calendarScroll.position < calendarScroll.CAL_END) {
            calendarScroll.position++;
        } else if (!forward && calendarScroll.position > calendarScroll.CAL_BEGIN) {
            calendarScroll.position--;
        }
        calendarScroll.displayControls();
        calendarScroll.displayDateRange();
        calendarScroll.setSectionVisibility();
    },

    setSectionVisibility: function() {
        for (var i = 1; i <= 5; i++) {
            if (i == calendarScroll.position - 1 || i == calendarScroll.position || i == calendarScroll.position + 1)
                calendarScroll.sections.item(i - 1).setDisplayed('block');
            else
                calendarScroll.sections.item(i - 1).setDisplayed('none');
        }
    },
    displayDateRange: function() {
        Ext.get('calendarScroll').select('span').each(function(element) {
            element.setDisplayed('none');
        });
        Ext.get('dateRange' + (calendarScroll.position - 1)).setDisplayed('inline');
    },
    displayControls: function() {
        switch (calendarScroll.position) {
            case calendarScroll.CAL_BEGIN:
                calendarScroll.stepBackward.addClass("scrollLimit"); break;
            case calendarScroll.CAL_END:
                calendarScroll.stepForward.addClass("scrollLimit"); break;
            default:
                calendarScroll.stepBackward.removeClass("scrollLimit");
                calendarScroll.stepForward.removeClass("scrollLimit");
        }
    }
}
Ext.onReady(function() {
    if (Ext.get('calendarScroll')) {
        calendarScroll.init();
    }
});

function toggleSubscriptionLinkState(state) {
    if (!state) {
        Ext.get('watchCalendarSubscribe').removeClass('hdn');
        Ext.get('watchCalendarUnsubscribe').addClass('hdn');
    } else {
        Ext.get('watchCalendarUnsubscribe').removeClass('hdn');
        Ext.get('watchCalendarSubscribe').addClass('hdn');
    }
}

var calendarSubscribe = {
    init: function() {
        var subscribeLink = Ext.get('calendarSubscribe');
        subscribeLink.on('click', function(event, element) {
            event.preventDefault();
            var subscribeState = element.className;
            calendarSubscribe.loading(element);
            var state = '';
            if (subscribeState == 'calendarSubscribe') {
                state = 'add';
            } else if ((subscribeState == 'calendarUnsubscribe')) {
                state = 'delete';
            } else {
                return;
            }
            makeAjaxPost("/_subscription/_calendar/", {action : state}, function() {
                calendarSubscribe.success(element, state)
            }, function() {
                calendarSubscribe.error(element)
            });
        });
    },
    success: function(element, state) {
        if (state == "add") {
            element.className = "calendarUnsubscribe";
        } else {
            element.className = "calendarSubscribe";
        }
        element.innerHTML = "Email Me Daily Updates";
        calendarSubscribe.init();
    },
    loading: function(element) {
        element.className = "working";
    },
    error: function(element) {
        element.className = "error";
        element.innerHTML = "Oops! Please try again later.";
    }
}
Ext.onReady(function() {
    if (Ext.get('calendarSubscribe')) {
        calendarSubscribe.init();
    }
});

var starRater = {
    atomThumb: undefined,
    atomTitle: undefined,
    atomUrl: undefined,
    rating: undefined,
    summary: undefined,
    hasRated: false,
    init: function(atomThumb, atomTitle, atomUrl, summary) {
        starRater.atomThumb = atomThumb;
        starRater.atomTitle = atomTitle;
        starRater.atomUrl = atomUrl;
        starRater.summary = summary;
        var raters = Ext.select('.rater');
        if (raters.getCount() > 0) {
            raters.each(function(el, ignored, index) {
                var element = Ext.get(el);
                element.on('click', function() {
                    starRater.submitAddRatingRequest(index + 1);
                    pageTracker._trackPageview('/activity' + atomLink + '/rate');
                });
                if (element.hasClass('anonRater')) {
                    element.removeClass('rater');
                    element.on('click', function(e) {
                        e.preventDefault();
                        var panel = new Ext.Panel({
                            html: starRater.getRatingPopupContent(),
                            hideBorders: true,
                            bodyStyle: 'padding: 10px;',
                            bodyBorder: false,
                            border: false
                        });
                        generateLightboxWindow(500, 150, panel, 'ratingModalWindow', '', true).show();
                    });
                }
            });
        }
    },
    submitAddRatingRequest: function (rating) {
        Ext.get('unit_ul').update('<div class="loading"></div>');
        starRater.rating = rating;
        makeAjaxPost(atomLink + "/_rating", { action: 'add',
            rating: rating},
                starRater.handleAddRatingSuccess, starRater.handleAddRatingFailure);
    },
    handleAddRatingSuccess: function(transport) {
        Ext.get('unit_long').update(transport.responseText);
        starRater.init(starRater.atomThumb, starRater.atomTitle, starRater.atomUrl, starRater.summary);
        if (!starRater.hasRated) {
            starRater.hasRated = true;
            var template_data = {"images":[
                {
                    "src": starRater.atomThumb,
                    "href":starRater.atomUrl
                }
            ],
                "atom":starRater.atomTitle,
                "atomUrl":starRater.atomUrl,
                "rating":starRater.rating + " star" + (starRater.rating > 1 ? "s" : ""),
                "summary":starRater.summary};
            showFacebookFeedDialog('FbRatingBundleId', template_data, function() {
            }, function() {
            });
        }
    },
    handleAddRatingFailure: function () {
        Ext.get('unit_ul').update('<li>There was a problem setting the rating</li>');
    },
    getRatingPopupContent:function() {
        var content = "<p>Thanks for rating!</p><p><a href='/_user/_account'>Sign up</a> for a SideReel account to stay up-to-date with all your favorite shows, movies, and actors!</p></div>";
        var contentEl = document.getElementById("ratedMessage");
        if (contentEl) {
            content = contentEl.innerHTML;
        }
        return content;
    }

}


/*Episode Guide Utilities
 ----------------------------------------------------------------------------*/
function episodeAdd(state, values) {
    new EpisodeAddForm(state, values);
}

function EpisodeAddForm(state, values) {
    var addEpWin;
    init();
    function init() {
        addEpWin = new Ext.Window({
            id:'addEpisodeWindow',
            layout:'fit',
            title: state + " an Episode",
            width:480,
            height: 460,
            draggable: false,
            hideBorders: true,
            bodyBorder: false,
            border: false,
            modal: true,
            buttonAlign: 'left',
            resizable: false,
            closeAction:'close',
            shadow: false,
            shadowDisabled: true,
            items: new Ext.Panel({
                bodyBorder: false,
                border: false,
                hideBorders: true,
                autoLoad: {
                    url: '/_html/addEpisode.html',
                    callback: function() {
                        if (values) {
                            document.getElementById('editLabels').innerHTML = '<p>Season: ' + values[0] + '</p><p>Episode: ' + values[1] + '</p>';
                            document.getElementById('seasonEp').style.display = "none";
                            document.getElementById('epSeason').setAttribute('value', values[0]);
                            document.getElementById('epEpisode').setAttribute('value', values[1]);
                            document.getElementById('epTitle').setAttribute('value', values[2]);
                            document.getElementById('epMonth').selectedIndex = values[3];
                            document.getElementById('epDay').selectedIndex = values[4];
                            document.getElementById('epYear').selectedIndex = getYearSelectedIndex(values[5]);
                            document.getElementById('epSummary').innerHTML = values[6];
                            document.getElementById('addEpisodeBox').style.display = "block";
                        } else {
                            var seasonInput = new Ext.form.NumberField({
                                applyTo: 'epSeason',
                                allowBlank: false,
                                allowDecimals: false,
                                allowNegative: false,
                                minValue: 1
                            });
                            var episodeInput = new Ext.form.NumberField({
                                applyTo: 'epEpisode',
                                allowBlank: false,
                                allowDecimals: false,
                                allowNegative: false,
                                minValue: 1
                            });
                            document.getElementById('addEpisodeBox').style.display = "block";
                        }
                    }
                }
            }),

            buttons: [
                {
                    text:'Save',
                    handler: function() {
                        limitCharacters('epSummary', 1024);
                        var formData = new Ext.form.BasicForm("addEpisodeForm").getValues(false);
                        var seasonNum = parseInt(formData['categoryid']);
                        var episodeNum = parseInt(formData['subcategoryid']);
                        if ((!seasonNum || (seasonNum < 1)) || (!episodeNum || (episodeNum < 1))) {
                            Ext.get('editLabels').addClass('messages');
                            document.getElementById('editLabels').innerHTML = 'Season and episode are both required';
                        } else {
                            var episodeInput = addSubcategoryRequest(formData);
                            addEpWin.close();
                        }
                    }
                },
                {
                    text: 'Cancel',
                    handler: function() {
                        addEpWin.close();
                    }
                }
            ]
        });
        addEpWin.show();
    }

    // TODO: change name to addEpisodeRequest
    function addSubcategoryRequest(values) {
        makeAjaxPost(makeSubcategoryUrl(values['categoryid'], values['subcategoryid']),
        {action: 'add', title: values['title'], summary: values['summary'], month: values['month'], day: values['day'], year: values['year']},
                handleSubcategoryResponse, handleSubcategoryResponse);
    }

}

function getYearSelectedIndex(yearValue) {
    var yearIndex = 0;
    if (yearValue != "") {
        yearIndex = -1 * (parseInt(yearValue) - 2011);
    }
    return yearIndex;
}

var summaryTruncator = {
    init: function(id) {
        var atomSummary = Ext.get(id);
        if (atomSummary && atomSummary.getHeight() > 86) {
            atomSummary.addClass('truncated');
            Ext.get("moreSummary").on('click', function(e) {
                e.preventDefault();
                atomSummary.removeClass('truncated');
                Ext.get("moreSummary").dom.style.display = "none";
            });
            Ext.get("moreSummary").dom.style.display = "inline";
        }
        atomSummary.dom.style.visibility = "visible";
    }
};


var addLinkForm = {
    frm: '',
    url: '',
    frmAction: '',
    win: '',
    init: function() {
        var linkButton = Ext.select('.addLink');
        linkButton.each(function(el) {
            el.on('click', addLinkForm.attachForm);
            el.removeClass('x-hidden');
        });
        addLinkForm.attachToEdits();
        if (Ext.get('episodeAdd')) {
            Ext.get('episodeAdd').removeClass('x-hidden');
        }
    },
    attachToEdits: function() {
        Ext.select('.allowEdit').each(function(el) {
            el.removeAllListeners();
            el.on('click', addLinkForm.attachForm);
            el.show();
        });
    },
    attachForm: function(event, element) {
        event.preventDefault();
        element = (element.tagName.toLowerCase != "a") ? Ext.get(element).findParent("a") : element;
        addLinkForm.win = new Ext.Window({
            layout: 'fit',
            id: 'addLinkWindow',
            plain: true,
            title: 'Add/Edit a Link',
            resizable: false,
            hideBorders: true,
            draggable: false,
            width: 500,
            height: 530,
            modal: true,
            bodyBorder: false,
            border: false,
            closeAction:'close',
            shadow: false,
            shadowDisabled: true,
            buttonAlign: 'left',
            items: new Ext.Panel({
                autoLoad: {
                    url: element,
                    callback: function() {
                        addLinkForm.frmAction = Ext.get('addWatchLinkForm').getAttributeNS('ext', 'rel');
                        addLinkForm.frm = new Ext.form.BasicForm('addWatchLinkForm');
                        addLinkForm.url = new Ext.form.TextField({
                            applyTo: 'addWatchLinkUrl',
                            vtype:'srlUrl',
                            allowBlank: false,
                            vtypeText:"please enter a valid url",
                            validationDelay: 1000
                        });
                        addLinkForm.frm.add(addLinkForm.url);
                        if (Ext.get('addWatchLinkTags')) {
                            addLinkForm.tags = new Ext.form.TextField({
                                applyTo: 'addWatchLinkTags',
                                vtype:'tagValidation',
                                allowBlank: false,
                                vtypeText:"please enter a comma-seperated list of tags (consisting of letters, numbers, or dashes)",
                                validationDelay: 1000
                            });
                            addLinkForm.linkTitle = new Ext.form.TextField({
                                applyTo: 'addWatchLinkTitle',
                                vtype:'notBlank',
                                vtypeText:"please enter a title",
                                allowBlank: false,
                                blankText: "please enter a title",
                                validationDelay: 500
                            });
                            addLinkForm.frm.add(addLinkForm.linkTitle);
                            addLinkForm.frm.add(addLinkForm.tags);
                        }
                        // Convert comboboxes (or maybe this script is already in the form?)
                    },
                    autoHeight: true
                },
                hideBorders: true,
                bodyStyle: 'padding: 10px;',
                bodyBorder: false,
                border: false
            }),
            buttons: [
                {
                    text: 'Save',
                    handler: function() {
                        var submitUrl = addLinkForm.url.getRawValue();
                        if (addLinkForm.frm.isValid()) {
                            var submitButton = this;
                            submitButton.disable();
                            addLinkForm.frm.submit({
                                url: addLinkForm.frmAction,
                                method: 'POST',
                                clientValidation: false,
                                success: function(form, action) {
                                    var resultValue = action.result.value;
                                    if (resultValue == "OK") {
                                        if ("undefined" != typeof(Recaptcha)) {
                                            Recaptcha.destroy();
                                        }
                                        addLinkForm.win.destroy();
                                        thankUserAndUpdateTracker();

                                    } else {
                                        submitButton.enable();
                                        addLinkForm.displayError(action.result.message);
                                        if ("undefined" != typeof(Recaptcha)) {
                                            Recaptcha.reload();
                                        }
                                    }
                                },
                                failure: function(form, action) {
                                    submitButton.enable();
                                    addLinkForm.displayError(DEFAULT_ERROR_TEXT);
                                }
                            });
                        } else {
                            addLinkForm.url.markInvalid();
                        }
                    }
                },
                {
                    text: 'Cancel',
                    handler: function() {
                        if ("undefined" != typeof(Recaptcha)) {
                            Recaptcha.destroy();
                        }
                        addLinkForm.win.close();
                    }
                }
            ]
        });

        addLinkForm.win.show();
    },
    displayError: function(message) {
        var messagesParagraph = Ext.get('addWatchLinkMessages');
        if (messagesParagraph) {
            messagesParagraph.update(message);
        } else {
            Ext.DomHelper.insertFirst(Ext.get("addWatchLinkForm"), { tag: 'p', id: 'addWatchLinkMessages', cls: 'message', html: message });
        }
    }
}
Ext.onReady(function() {
    if (Ext.query('.addLink').length > 0) {
        addLinkForm.init();
    }
});
Ext.apply(Ext.form.VTypes, {
    srlUrl: function(val, field) {
        return isValidUrl(field.getValue());
    },
    tagValidation: function(val, field) {
        var regex = /^(([a-zA-Z0-9 -]+),?){1,16}$/;
        return regex.test(val);
    },
    notBlank: function(val, field) {
        var regex = /[^\s]+/;
        return regex.test(val);
    }
});

var atomSearchToggle = {
    init : function() {
        var localSearchForm = Ext.get("searchForm");
        var converted = new Ext.form.ComboBox({
            typeAhead: false,
            triggerAction: 'all',
            transform:'searchToggle',
            width:60,
            forceSelection:true,
            editable: false
        });
        localSearchForm.on('submit', function(e) {
            if (converted.getValue() == 'site') {
                e.preventDefault();
                var query = Ext.get('atomSearchInput').dom.value;
                SiteSearch.search(query);
            }
        });
    }
}
Ext.onReady(function() {
    if (Ext.get('atomSearchInput')) {
        atomSearchToggle.init();
    }
});

function confirmDelete(watchLinkId, atomUrl, linkElemId) {
    var deleteLink = confirm('Are you sure you want to delete this link?');
    if (deleteLink) {
        removeWatchLinkRequest(watchLinkId, atomUrl);
        var linkID = 'wl_' + linkElemId;
        if (document.getElementById(linkID)) {
            document.getElementById(linkID).style.display = 'none';
        }
    }
    return false;
}

function removeWatchLinkRequest(watchLinkId, atomUrl) {
    return makeAjaxPost(atomUrl + "/_watchlink/" + watchLinkId, {action: 'delete'},
            function() {
                handleRemoveWatchLinkSuccess(atomUrl)
            }, handleRemoveWatchLinkFailure);
}

function handleRemoveWatchLinkFailure() {
    //do nothing
}

function handleRemoveWatchLinkSuccess(atomUrl) {
    thankUserAndUpdateTracker(atomUrl);
}


function confirmRemoveEpisode(categoryId, subcategoryId) {
    var removeEpisode = confirm('Are you sure you want to remove this episode?');
    if (removeEpisode) {
        removeSubcategoryRequest(categoryId, subcategoryId);
    }
}

function removeSubcategoryRequest(categoryId, subcategoryId) {
    makeAjaxPost(makeSubcategoryUrl(categoryId, subcategoryId), {action: "delete"}
            , handleSubcategoryResponse, handleSubcategoryResponse);
}

function handleSubcategoryResponse(transport) {
    thankUserAndUpdateTracker();
}

function makeSubcategoryUrl(categoryId, subcategoryId) {
    // TODO: evil evil. Relying on this global atomLink variable, which does not actually always exist
    return atomLink + "/_info/" + encodeURIComponent(categoryId) + "/" + encodeURIComponent(subcategoryId);
}

function thankUserAndUpdateTracker(atomUrl) {
    thankUserForSubmitting();
    EpisodeTrackerManager.get(atomUrl).updateEpisodeTracker();
}

function thankUserForSubmitting() {
    var panel = new Ext.Panel({
        html:"<p>Thanks for your contribution.</p>",
        hideBorders: true,
        bodyStyle: 'padding: 10px;',
        bodyBorder: false,
        border: false,
        buttonAlign: 'left',
        buttons: [
            {
                text:'Close',
                handler: function() {
                    confirmationBlurb.close();
                }
            }
        ]
    });
    var confirmationBlurb = generateLightboxWindow(250, 100, panel, "confirmationBlurb", '');
    confirmationBlurb.show();
}


function generateLightboxWindow(winWidth, winHeight, panel, id, title, closeable) {
    return generateWindow(winWidth, winHeight, panel, id, title, closeable, true);
}

function generateWindow(winWidth, winHeight, panel, id, title, closeable, destroyOnClose) {
    return new Ext.Window({
        layout: 'fit',
        id: id,
        plain: true,
        resizable: false,
        hideBorders: true,
        draggable: false,
        width: winWidth,
        height: winHeight,
        modal: true,
        bodyBorder: false,
        border: false,
        title: title,
        closable: closeable,
        closeAction: destroyOnClose ? 'close' : 'hide',
        shadow: false,
        shadowDisabled: true,
        buttonAlign: 'left',
        items: panel
    });
}

//for iframe
function setIframeDimensions() {
    var frame = Ext.get('frame');
    var theSideReel = Ext.get('theSideReel');
    var viewSize = Ext.getDoc().getViewSize();
    frame.setWidth(viewSize.width - theSideReel.getWidth());
    frame.setHeight(viewSize.height);
    frame.setLeft(theSideReel.getWidth());
    //IE6 footer positioning fix
    Ext.get('main').setHeight(viewSize.height);
}

function toggleSideBar() {
    Ext.get('main').setVisibilityMode(Ext.Element.DISPLAY);
    Ext.get('main').toggle();
    Ext.get('toggleLink').toggleClass('on');
    setIframeDimensions();
}

//Remove Functions
function rateWatchLink(watchLinkId, atomUrl, linkId) {
    var url = atomUrl + "/_watchlink/" + watchLinkId + "/_rating";
    Ext.select(".watchLinkRating_" + linkId).each(function(elm) {
        elm.update("<span class='brokenThanks'>Thanks!</span>");
    });
    return new makeAjaxPost(url, {action:"add", rating: 'Broken'},
            function() {
            }, function() {
    });
}

function watchLinkManagerRemove(atomIdAsLink, watchLinkId) {
    return makeAjaxPost(atomIdAsLink + "/_watchlink/" + watchLinkId, {action: 'delete'},
            watchLinkManagerRemoveSuccess, watchLinkManagerRemoveFailure)
}

function watchLinkManagerRemoveSuccess() {
    updateWatchLinkTools("removed");
}

function watchLinkManagerRemoveFailure() {
    updateWatchLinkTools("error removing watchlink");
}

function watchLinkManagerAdd(atomIdAsLink, url, season, episode, tags, title) {
    return makeAjaxPost(atomIdAsLink + "/_watchlink", {action: 'add', url: url, season: season, episode: episode, tags: tags, title: title},
            watchLinkManagerAddSuccess, watchLinkManagerAddFailure);
}

function watchLinkManagerAddSuccess() {
    updateWatchLinkTools("added");
}

function watchLinkManagerAddFailure() {
    updateWatchLinkTools("error adding watchlink");
}

function updateWatchLinkTools(message) {
    Ext.get('watchLinkTools').update(message);
}

function clearHint() {
    var inputField = Ext.get('atomSearchInput');
    if (inputField.hasClass('blured')) {
        inputField.dom.setAttribute('value', '');
        inputField.removeClass('blured');
    }
}

function getMoreLinkResults(linkElm) {
    var linkElement = Ext.get(linkElm);
    linkElement.dom.style.display = "none";
    var loadingDiv = Ext.get('resultsUpdater');
    loadingDiv.dom.innerHTML = "<span class='loading'>loading</span>";
    var updater = Ext.get('resultsBox').getUpdater();
    updater.showLoadIndicator = false;
    updater.update({
        url: linkElm.href,
        method: "GET",
        callback: function() {
            initLightbox();
            addLinkForm.attachToEdits();
            loadingDiv.remove();
        }
    });
}

/* Facebook Connect */
function handleLogin() {
    execIfConnected(function() {
        makeAjaxPost("/_facebook/_link", {action: 'add'}, function(response) {
            var response = Ext.util.JSON.decode(response.responseText).response;
            if (response.result == "success_linked") {
                showFacebookFeedDialog('FbSignupBundleId', {}, function() {
                    window.location = "/_welcome";
                }, function() {
                });
            } else if (response.result == "success_not_created") {
                pageTracker._trackPageview('/activity/facebook/signups/facebookOnlySignups');
                getSuggestionAndDisplayUsernameDialog();
            } else {
                window.location.reload(true);
            }
        }, function(response) {
            getSuggestionAndDisplayUsernameDialog();
        });
    }, function() {
    });
}

function getSuggestionAndDisplayUsernameDialog() {
    FB.Facebook.apiClient.users_getInfo(FB.Facebook.apiClient.get_session().uid, ["name"], function(result) {
        var firstAndLastName = result[0].name.split(" ");
        var createFacebookConnectUserForm = new Ext.Panel({
            autoLoad: {
                url: "/_user/_suggestname?first=" + firstAndLastName[0] + "&last=" + firstAndLastName[1],
                nocache: true,
                autoHeight: true
            },
            hideBorders: true,
            bodyStyle: 'padding: 10px;',
            bodyBorder: false,
            border: false
        });
        generateLightboxWindow(530, 310, createFacebookConnectUserForm, 'createFacebookConnectUserFormWindow', 'Choose a Username', false).show();
    });
}

function handleLogout() {
    FB.ensureInit(function() {
        FB.Facebook.get_sessionState().waitUntilReady(function()
        {
            FB.Connect.logout(function(somevar) {
                window.location.href = "/_user/_logout";
            });
        });
    });
}

function execIfConnected(ifConnectedCallback, ifNotConnectedCallback) {
    var callbackCalled = false;
    FB.ensureInit(function() {
        FB.Connect.ifUserConnected(function() {
            if (!callbackCalled) {
                ifConnectedCallback();
            }
            callbackCalled = true;
        }, function() {
            if (!callbackCalled) {
                ifNotConnectedCallback();
            }
            callbackCalled = true;
        });
    });
}

function execIfLoggedInAndConnected(ifConnectedCallback, ifNotConnectedCallback) {
    if (LoginState.isLoggedIn()) {
        execIfConnected(ifConnectedCallback, ifNotConnectedCallback);
    }
}


function createFacebookUser(values) {
    makeAjaxPost("/_facebook/_user", {action: "add", username: values["username"]},
            function(transport) {
                var response = Ext.util.JSON.decode(transport.responseText).response;
                if (response.result == "fail_already_exists") {
                    injectCreateFBConnectUserMessage("Username is already taken.  Please choose another.", "");
                } else {
                    Ext.getCmp('createFacebookConnectUserFormWindow').close();
                    showFacebookFeedDialog('FbSignupBundleId', {}, function() {
                        window.location = "/_welcome";
                    }, function() {
                    });
                }
            },
            function(transport) {
                var span = document.createElement('span');
                span.innerHTML = "There was a problem with processing your request.  Please try again later.";
                Ext.get("createFacebookConnectUserFormDiv").appendChild(span);
            });
}

function injectCreateFBConnectUserMessage(messageText, cssClass) {
    var createFBConnectUserError = Ext.get('createFBConnectUserError');
    if (!createFBConnectUserError) {
        createFBConnectUserError = Ext.DomHelper.insertAfter(Ext.get("createFacebookConnectUserFormDiv"),
        {tag: 'span', id: 'createFBConnectUserError'}, true);
    }
    createFBConnectUserError.set({cls: cssClass});
    createFBConnectUserError.update(messageText);
}

function submitFacebookUsernameForm() {
    injectCreateFBConnectUserMessage("Checking username...", "loading");
    document.getElementById('createFacebookConnectUserForm').submit();
}

Ext.onReady(function() {
    FB.ensureInit(function() {
        showFacebookDependantElements();
        displayLinkToSidereelPromo();
    });
});

function showFacebookDependantElements() {
    var fbReadyClass = 'onFbReady';
    Ext.select('.' + fbReadyClass).each(function(el) {
        el.removeClass(fbReadyClass);
    });
}

function displayLinkToSidereelPromo() {
    if (!LoginState.isLoggedIn()) {
        FB.Connect.get_status().waitUntilReady(function(state)
        {
            if (FB.ConnectState.appNotAuthorized == state) {
                Ext.get('promoStrip').update("<div id='registrationCompletionPromo'><a id='joinFacebookFriends' href=\"#\" onclick=\"FB.Connect.requireSession(function() { handleLogin(); })\">Connect with your Facebook friends on SideReel &nbsp;&nbsp;<img style='vertical-align: middle;' src='/_img/connectLarge.gif' /></a></div>");
            }
        });
    }
}

function getNamespacedElements(name) {
    var elements = document.getElementsByTagName(name);
    if (elements.length == 0) { // hack for ie
        var nsDelimeter = name.indexOf(':');
        if (nsDelimeter > -1)
            elements = document.getElementsByTagName(name.substring(nsDelimeter + 1));
    }
    return elements;
}

Ext.onReady(function() {
    var friendsTags = getNamespacedElements("sr:friends");
    if (friendsTags.length > 0) {
        execIfConnected(function() {
            displayFriends(friendsTags.item(0));
        }, function() {
        });
    }
});

function replaceElementWith(domElement, elementSpec) {
    return Ext.get(domElement).replaceWith(elementSpec);
}

function displayFriends(tag) {
    var atomId = tag.getAttribute("filterByAtom");
    var sectionTitle = tag.getAttribute("sectionTitle") || "Friends";
    var elt = replaceElementWith(tag, {tag:'div', id:'srml_friends'});
    var url = "/_facebook/_friends";
    if (atomId)
        url += "?filter=favorites&atom=" + escape(atomId);
    Ext.get(elt).getUpdater().update({url:url, callback: function() {
        var friendsDiv = Ext.get("facebookFriends");
        if (friendsDiv) {
            friendsDiv.insertFirst({tag:'h2', html:sectionTitle});
            FB.XFBML.Host.parseDomTree();
            initLightbox();
        }
    }});

}

var FacebookTemplateManager = function() {
    var bundleMap;

    return {
        bundle : function(bundleName) {
            return bundleMap[bundleName];
        },
        init : function(bundles) {
            bundleMap = bundles;
        }
    };
}();

function showInviteDialog(hostUrlPrefix) {
    var fbml = "<fb:request-form requirelogin=1 " +
               "action='" + window.location + "' " +
               "method='POST' " +
               "invite='true' " +
               "type='SideReel' " +
               "content=\"Use Sidereel to watch and rate your favorite TV shows. Share favorites with your friends! <fb:req-choice url='" + hostUrlPrefix + "/_connectWithFacebook?source=facebookInvite' " +
               "label='Join SideReel!' />\"> " +
               "<fb:multi-friend-selector " +
               "showborder='false' " +
               "actiontext='Invite your friends to use SideReel.'></fb:multi-friend-selector> " +
               "</fb:request-form>";
    showFbPopupDialog("Invite your friends to SideReel!", fbml);
}

function showRequestDialog(hostUrlPrefix, atomTitle, atomSummary, rating, fbUid) {
    var contentMsg;
    if (rating > 0) {
        var star = "star";
        if (rating > 1) star += "s";
        contentMsg = "has given " + atomTitle + " " + parseInt(rating) + " " + star + " and has recommended it to you. ";
    } else {
        contentMsg = "has recommended " + atomTitle + " to you. ";
    }
    var destinationUrl = window.location.href.split('?')[0] + "?source=fbRecommendation";
    var fbml = "<fb:request-form requirelogin=1 " +
               "action='" + window.location + "' " +
               "method='POST' " +
               "invite='false' " +
               "type='SideReel' " +
               "content=\"<fb:name uid='" + fbUid + "' /> " + contentMsg + atomSummary + "<fb:req-choice url='" + destinationUrl + "' " +
               "label='Watch " + atomTitle + "!' />\"> " +
               "<fb:multi-friend-selector " +
               "showborder='false' " +
               "actiontext='Recommend " + atomTitle + " to your friends!'></fb:multi-friend-selector> " +
               "</fb:request-form>";
    showFbPopupDialog("Recommend this show to your friends!", fbml);
}

function showFbPopupDialog(windowHeader, fbml) {
    /* fortunately this method does not pull from the local cache */
    FB.Connect.requireSession(function() {
        FB.Facebook.apiClient.users_getLoggedInUser(function(user) {
            if (user) {
                var dialog = new FB.UI.FBMLPopupDialog(windowHeader, fbml);
                dialog.setContentHeight(400);
                dialog.setContentWidth(800);
                dialog.show();
            }
        });
    });
}

var LoginDialog = function() {
    var loginWindow;

    function init() {
        if (!loginWindow) {
            var loginDialog = Ext.get('loginDialog');
            loginDialog.removeClass('hidden');
            var panel = new Ext.Panel({
                applyTo: loginDialog,
                hideBorders: true,
                bodyStyle: 'padding: 10px;',
                bodyBorder: false,
                border: false
            });
            loginWindow = generateWindow(450, 210, panel, 'loginWindow', '', true, false);
        }
    }

    return {
        show : function() {
            init();
            loginWindow.show();
        }
    };
}();

var CommentForm = function() {
    var commentFormElm;
    var title;
    var link;

    function submit() {
        var commentForm = new Ext.form.BasicForm(commentFormElm);
        commentForm.submit({
            url: link + "/_comment",
            clientValidation: false,
            success: function(form, action) {
                var response = Ext.util.JSON.decode(action.response.responseText).response;
                var template_data = {"postTitle":title, "postLink":link,
                    "replyLink":link + "#commentNav" + response.id, "commentSnippet":response.comment};
                var refreshComment = function() {
                    window.location.hash = "commentNav" + response.id;
                    window.location.reload(true);
                };
                showFacebookFeedDialog('FbCommentBundleId', template_data, refreshComment, refreshComment);
            },
            failure: function(form, action) {
                var response = Ext.util.JSON.decode(action.response.responseText).response;
                Ext.get('addCommentFormError').update(response.message);
                Recaptcha.reload(true);
            }
        });
    }

    return {
        init : function(addCommentForm, postTitle, postLink) {
            commentFormElm = addCommentForm;
            commentFormElm.on('submit', function(e) {
                submit();
                e.preventDefault();
            });
            title = postTitle;
            link = postLink;
        }
    };
}();

function subscribeToWatchCalendar(username) {
    var redirectToUpdateProfile = function() {
        window.location = '/_user/' + username + '/_profile';
    };
    makeAjaxPost("/_subscription/_calendar/", {action : 'add'}, redirectToUpdateProfile, redirectToUpdateProfile);
}

var welcomeEmail = {
    congratulationHTML: "Awesome! A confirmation email was sent to your inbox.",
    errorElmId : 'validationErrorMessage',
    submit: function(username) {
        if (Ext.get(welcomeEmail.errorElmId)) Ext.get(welcomeEmail.errorElmId).remove();
        Ext.get("pleaseWait").dom.style.display = 'inline';
        var convertedForm = new Ext.form.BasicForm("enterEmailBasicForm");
        convertedForm.submit({
            url: "/_user/" + username + "/_email",
            clientValidation: false,
            success: function() {
                welcomeEmail.successUpdate();
            },
            failure: function(form, action) {
                Ext.get("pleaseWait").hide();
                welcomeEmail.displayError(action.result.message);
            }
        });
    },
    displayError: function(message) {
        Ext.get("emailActivityContainer").insertFirst({tag:'p', id:welcomeEmail.errorElmId, html:message});
    },
    resend: function(username) {
        makeAjaxGet("/_user/" + username + "/_confirm", "", function() {
        }, function() {
        });
        welcomeEmail.successUpdate();
    },
    successUpdate: function() {
        Ext.get("emailActivityContainer").dom.innerHTML = welcomeEmail.congratulationHTML;
    }
};

function showCompleteCalendar() {
    var calendar = Ext.get('watchCalendar');
    var toggleLink = Ext.get('calShowLink');
    if (calendar.getComputedHeight() < 205) {
        calendar.dom.style.maxHeight = 'none';
        toggleLink.dom.innerHTML = 'Hide';
    } else {
        calendar.dom.style.maxHeight = '200px';
        toggleLink.dom.innerHTML = 'View All';
    }
}

var UserSegmentTracker = function () {
    var USER_SEGMENT = 'user_segment';
    var SR_LOGGED_IN = "SRLoggedIn";
    var FB_ACTIVE = "FBActive";

    function init(pageTracker, cookieLifetimeInSeconds, domain) {
        Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
            path: "/",
            expires: new Date(new Date().getTime() + (cookieLifetimeInSeconds * 1000)),
            domain: domain.replace(/http:\/\//, "").replace(/[:\/].*/, "")
        }));
        var loginState = determineLoginState();
        var loginStateCookie = loginState.sort().join(".");
        var existingCookie = Ext.state.Manager.get(USER_SEGMENT);
        if (loginStateCookie != existingCookie) {
            Ext.state.Manager.set(USER_SEGMENT, loginStateCookie);
            for (var i = 0; i < loginState.length; i++) {
                pageTracker._trackPageview("/_usersegment?segment=" + loginState[i]);
            }
        }
    }

    function determineLoginState() {
        var attributes = [];
        if (LoginState.isLoggedIn()) attributes.push(SR_LOGGED_IN);
        if (LoginState.isFbActive()) attributes.push(FB_ACTIVE);
        return attributes;
    }

    return {init : init};
}();

var SiteSearch = function () {
    var siteSearchElement;
    var SIDEREEL_SEARCH_URL = "/_search";
    var ASK_SEARCH_URL = "http://www.ask.com/web";

    function setAction(action) {
        siteSearchElement.set({action: action});
    }

    function setValue(name, value) {
        getByName(name).set({value: value});
    }

    function getByName(name) {
        return Ext.get(siteSearchElement.query('input[name=' + name + ']')[0]);
    }

    function prepareSidereelSearch() {
        setAction(SIDEREEL_SEARCH_URL);
        getByName("o").remove();
        getByName("l").remove();
        getByName("q").remove();
    }

    return {
        init : function(sidereelSearchForm) {
            siteSearchElement = sidereelSearchForm;
        },
        submitSearch : function() {
            var searchForm = new Ext.BasicForm(siteSearchElement, {method: "get", standardSubmit : true});
            var searchValues = searchForm.getValues();
            var searchQuery = searchValues.searchQuery;
            if (searchValues.siteSearchType == "sidereel") {
                prepareSidereelSearch();
            } else {
                setAction(ASK_SEARCH_URL);
                setValue("q", searchQuery);
                setValue("searchQuery", "");
            }
            return true;
        },
        search: function(query) {
            getByName("searchQuery").dom.style.visibility = "hidden";
            setValue("searchQuery", query);
            prepareSidereelSearch();
            new Ext.BasicForm(siteSearchElement, {method: "get", standardSubmit : true}).submit();
        }
    };
}();

var SRUtil = {
    doNothing : function() {
    }
};

var PlaylistState = function() {
    var initialized = false;
    var subscriptionState = false;
    var addedShowToPlaylist = false;
    var episodesInPlaylist = new Object();
    var callbacks = [];

    function init(atomUrl, callbackArray) {
        callbacks = callbackArray;
        if (LoginState.isLoggedIn()) {
            makeAjaxGet(atomUrl + "/playlist", "", initPlaylistState, SRUtil.doNothing);
        }
    }

    function initPlaylistState(response) {
        var playlistForAtom = Ext.util.JSON.decode(response.responseText);
        subscriptionState = playlistForAtom.subscribed;

        for (var i = 0; i < playlistForAtom.episodes.length; i++) {
            addToPlaylist(playlistForAtom.episodes[i].season, playlistForAtom.episodes[i].episode);
        }
        initialized = true;
        for (var j = 0; j < callbacks.length; j++) {
            callbacks[j]();
        }
    }

    function setShowAddedToPlaylist() {
        addedShowToPlaylist = true;
    }

    function subscribed() {
        return subscriptionState;
    }

    function addToPlaylist(season, episode) {
        if (episodesInPlaylist[season] == undefined)
            episodesInPlaylist[season] = new Object();
        episodesInPlaylist[season][episode] = true;
    }

    function isInPlaylist(season, episode) {
        return addedShowToPlaylist || (episodesInPlaylist[season] && episodesInPlaylist[season][episode]);
    }

    return{
        init : init,
        isSubscribed : subscribed,
        isInPlaylist : isInPlaylist,
        addToPlaylist: addToPlaylist,
        setShowAddedToPlaylist: setShowAddedToPlaylist
    };
}();

var Playlist = function() {

    function attachToAnchors() {
        var playlistElms = Ext.select(".fPlaylistAdder");
        playlistElms.each(function(elm) {
            elm.removeClass("fPlaylistAdder");
            var hrefVal = elm.getAttributeNS("", "href");
            if (hrefVal.match(/season-(\d+)\/episode-(\d+)/gi)) {
                var season = RegExp.$1;
                var episode = RegExp.$2;
                if (PlaylistState.isInPlaylist(season, episode)) {
                    markAsAdded(elm);
                } else {
                    attachEpisodeAdd(elm, season, episode);
                }
            }
        });
    }

    function attachEpisodeAdd(elm, season, episode) {
        elm.on('click', function(event, el) {
            var anchor = Ext.get(el);
            var postUrl = anchor.getAttributeNS("", "href");
            makeAjaxPost(postUrl, {action:"add"}, SRUtil.doNothing, SRUtil.doNothing);
            PlaylistState.addToPlaylist(season, episode);
            event.preventDefault();
            markAsAdded(anchor);
        });
    }

    function attachAddAllEpisodesForAtom() {
        var playlistElms = Ext.select(".fPlayListAtom");
        playlistElms.each(function(elm) {
            elm.removeClass("fPlayListAtom");
            elm.on('click', function(event, el) {
                var anchor = Ext.get(el);
                var postUrl = anchor.getAttributeNS("", "href");
                makeAjaxPost(postUrl, {action:"add"}, SRUtil.doNothing, SRUtil.doNothing);
                event.preventDefault();
                anchor.parent().removeClass("addAtomToPlaylist");
                anchor.parent().addClass("addedAtomToPlaylist");
                anchor.update("All episodes added");
                anchor.removeAllListeners();
                anchor.on('click', SRUtil.doNothing, null, {preventDefault:true});
                Ext.select(".addToPlaylist").each(function(el) {
                    markAsAdded(el);
                });
                PlaylistState.setShowAddedToPlaylist();
            });
        });
    }

    function markAsAdded(elm) {
        elm.removeClass("addToPlaylist");
        elm.addClass("addedToPlaylist");
        elm.removeAllListeners();
        elm.on('click', SRUtil.doNothing, null, {preventDefault:true});
    }

    return {
        attachToAnchors: attachToAnchors,
        attachAddAllEpisodesForAtom: attachAddAllEpisodesForAtom
    };
}();

Ext.onReady(function() {
    Ext.select('.activeAddSubscriptionFromThumb').each(function(el) {
        PlaylistSubscriptionManager.attachAddSubscriptionHandler(el);
    });
});

function PlaylistManager() {
    var DELETE_ENTRY_CLASS = ".fDeletePlaylistEntry";
    var HIDDEN = "hidden";
    var playlistEntriesByUrl = {};

    this.initDeletePlaylistItemLinks = function() {
        remove(DELETE_ENTRY_CLASS);
        removeShow();
    };

    this.initUnsubscribeLinks = function() {
        remove(".fUnsubscribe");
    };

    function hideEntriesForUrl(url) {
        var entries = playlistEntriesByUrl[url];
        if (entries != undefined) {
            for (var i = 0; i < entries.length; i++) {
                Ext.get(entries[i]).parent("li").setDisplayed("none");
            }
        }
    }

    function removeShow() {
        Ext.select(".fDeleteAllPlaylistEntries", true).each(function (elm) {
            elm.removeClass(HIDDEN);
            elm.on('click', function(event, el) {
                event.preventDefault();
                if (confirm("Remove all episodes in playlist?")) {
                    var extEl = Ext.get(el);
                    var element = extEl.parent("div");
                    element.select("a" + DELETE_ENTRY_CLASS).each(function(elm) {
                        var extElm = Ext.get(elm);
                        var href = extElm.getAttributeNS("", "href");
                        hideEntriesForUrl(href);
                    });
                    element.child(".showAllItems").parent("li").setDisplayed("none");
                    extEl.setDisplayed("none");
                    makeAjaxPost(extEl.getAttributeNS("", "href"), {action: 'delete'}, SRUtil.doNothing(), SRUtil.doNothing());
                }
            });
        });
    }

    function remove(cssClassSelector) {
        Ext.select(cssClassSelector, true).each(function (elm) {
            var extElm = Ext.get(elm);
            var href = extElm.getAttributeNS("", "href");
            extElm.removeClass(HIDDEN);
            if (playlistEntriesByUrl[href] == undefined) {
                playlistEntriesByUrl[href] = [];
            }
            playlistEntriesByUrl[href].push(elm);

            elm.on('click', function(event, el) {
                event.preventDefault();
                var element = Ext.get(el);
                var href = element.getAttributeNS("", "href");
                makeAjaxPost(href, {action:'delete'}, SRUtil.doNothing, SRUtil.doNothing);
                hideEntriesForUrl(href);
            });
        });
    }
}

var PlaylistSubscriptionManager = function() {
    var ALREADY_SUBSCRIBED = "Subscribed";
    var subscriptionAdded = false;

    function addSubscriptionClickHandler(el) {
        el.show();
        el.on('click', subscribe, null, {preventDefault:true});
    }

    function subscribe(event, elm) {
        var subscriptionLink = Ext.get(elm);
        var hrefVal = subscriptionLink.getAttributeNS("", "href");
        var splitUrl = hrefVal.split("/");
        var atomName = splitUrl[splitUrl.length - 1].replace(/_/g, " ");
        pageTracker._trackPageview('/activity/playlist/subscribe' + atomName);
        makeAjaxPost(hrefVal, {action: "add"}, handleAddSubscriptionResponse, SRUtil.doNothing);
        var classToAdd;
        var elementToUpdate;
        //TODO: standardize this dom updating experience
        if (subscriptionLink.hasClass("listSubscriptions")) {
            classToAdd = "listSubscriptionAdded";
            elementToUpdate = subscriptionLink;
            subscriptionLink.removeClass("listSubscriptions");
            subscriptionLink.removeClass("activeAddSubscriptionFromThumb");
        } else if (subscriptionLink.hasClass("activeAddSubscriptionFromThumb")) {
            classToAdd = "subscribedToPlaylistThumb";
            elementToUpdate = subscriptionLink.parent("div");
            subscriptionLink.removeClass("activeAddSubscriptionFromThumb");
            elementToUpdate.removeClass("subscribeThumb");
        } else {
            classToAdd = "subscribedToPlaylist";
            elementToUpdate = subscriptionLink;
            subscriptionLink.removeClass("subscribeToPlaylist");
        }
        elementToUpdate.addClass(classToAdd);
        subscriptionLink.removeAllListeners();
        subscriptionLink.on('click', SRUtil.doNothing, null, {preventDefault:true});
        subscriptionLink.update(ALREADY_SUBSCRIBED);
    }

    function handleAddSubscriptionResponse(transport) {
        var response = Ext.util.JSON.decode(transport.responseText);
        if (!response.success) return;
        var actionLinkPhrase = response.isTelevision ? "the latest episode!" : "it here!";
        var template_data = {
            "images":[
                {
                    "src": response.thumb,
                    "href":response.link
                }
            ],
            "atom":response.name,
            "atomUrl":response.link,
            "watchUrl":response.actionUrl,
            "summary":response.summary,
            "actionLinkPhrase": actionLinkPhrase
        };
        if (!subscriptionAdded) {
            subscriptionAdded = true;
            // TODO: should be the playlist subscription bundle id
            showFacebookFeedDialog("FbFavoriteBundleId", template_data, SRUtil.doNothing, SRUtil.doNothing);
        }
    }

    function setSubscribeLinkState() {
        var playlistSubscriptionElements = Ext.select(".fSubscribeToPlaylist");
        var subscriptionCallbackFunction = PlaylistState.isSubscribed() ? SRUtil.doNothing : subscribe;
        playlistSubscriptionElements.each(function(elm) {
            elm.on('click', subscriptionCallbackFunction, null, {preventDefault:true});
            elm.removeClass('hidden');
            elm.removeClass(".fSubscribeToPlaylist");
            if (PlaylistState.isSubscribed()) {
                elm.update(ALREADY_SUBSCRIBED);
                elm.addClass("subscribedToPlaylist");
            } else {
                elm.addClass("subscribeToPlaylist");
            }
        });
    }

    return {
        attachAddSubscriptionHandler: addSubscriptionClickHandler,
        subscribe: subscribe,
        setSubscribeLinkState: setSubscribeLinkState
    };
}();

function revealAll(el) {
    var element = Ext.get(el);
    element.parent('ul').select('li').each(function (elm) {
        elm.removeClass('hidden');
    });
    element.setDisplayed("none");
}
