﻿// Functions
var FUNC_RECENT = 'GetRecentVideos';
var FUNC_POPULAR = 'GetMostPopular';
var FUNC_ALL = 'GetAllVideos';
var FUNC_PLAYLIST = 'GetPlaylist';

// Tabs
var TAB_RECENT = 0;
var TAB_POPULAR = 1;
var TAB_ALL = 2;

// Display Types
var THUMBNAIL_VIEW = 0;
var LIST_VIEW = 1;

// Default values
var NO_VIDEO_SELECTED = 0;
var DEFAULT_TAB = TAB_RECENT;
var DEFAULT_VIEW = THUMBNAIL_VIEW;
var DEFAULT_CHANNEL = 0;
var DEFAULT_SEARCH = '';

// Globals
var itemWidth;
var itemCount;
var pageSize = 1;
var pageCount = itemCount / pageSize;

// Videos
var MAX_VIEWABLE_PLAYLIST_VIDEOS = 1
var MAX_VIEWABLE_PLAYLIST_HEIGHT = 285;
var MAX_VIEWABLE_VIDEOS_WIDTH = 568;

// Encoding
function urlEncode(str) {
    // The Javascript escape and unescape functions do not correspond
    // with what browsers actually do...
    var SAFECHARS = "0123456789" + 				    // Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +  // Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()"; 				    // RFC2396 Mark characters
    var HEX = "0123456789ABCDEF";

    var plaintext = str;
    var encoded = "";
    for (var i = 0; i < plaintext.length; i++) {
        var ch = plaintext.charAt(i);
        if (ch == " ") {
            encoded += "+"; 			// x-www-urlencoded, rather than %20
        } else if (SAFECHARS.indexOf(ch) != -1) {
            encoded += ch;
        } else {
            var charCode = ch.charCodeAt(0);
            if (charCode > 255) {
                alert("Unicode Character '"
                        + ch
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted.");
                encoded += "+";
            } else {
                encoded += "%";
                encoded += HEX.charAt((charCode >> 4) & 0xF);
                encoded += HEX.charAt(charCode & 0xF);
            }
        }
    }
    return encoded;
}
function urlDecode(str) {
    // Replace + with ' '
    // Replace %xx with equivalent character
    // Put [ERROR] in output if %xx is invalid.
    var HEXCHARS = "0123456789ABCDEFabcdef";
    var encoded = str;
    var plaintext = "";
    var i = 0;
    while (i < encoded.length) {
        var ch = encoded.charAt(i);
        if (ch == "+") {
            plaintext += " ";
            i++;
        } else if (ch == "%") {
            if (i < (encoded.length - 2)
					&& HEXCHARS.indexOf(encoded.charAt(i + 1)) != -1
					&& HEXCHARS.indexOf(encoded.charAt(i + 2)) != -1) {
                plaintext += unescape(encoded.substr(i, 3));
                i += 3;
            } else {
                alert('Bad escape combination near ...' + encoded.substr(i));
                plaintext += "%[ERROR]";
                i++;
            }
        } else {
            plaintext += ch;
            i++;
        }
    } // while
    return plaintext;
}
function htmlDecode(s) {
    var out = "";
    if (s == null) return;
    var l = s.length;
    for (var i = 0; i < l; i++) {
        var ch = s.charAt(i);
        if (ch == '&') {
            var semicolonIndex = s.indexOf(';', i + 1);
            if (semicolonIndex > 0) {
                var entity = s.substring(i + 1, semicolonIndex);
                if (entity.length > 1 && entity.charAt(0) == '#') {
                    if (entity.charAt(1) == 'x' || entity.charAt(1) == 'X')
                        ch = String.fromCharCode(eval('0' + entity.substring(1)));
                    else
                        ch = String.fromCharCode(eval(entity.substring(1)));
                } else {
                    switch (entity) {
                        case 'quot': ch = String.fromCharCode(0x0022); break;
                        case 'amp': ch = String.fromCharCode(0x0026); break;
                        case 'lt': ch = String.fromCharCode(0x003c); break;
                        case 'gt': ch = String.fromCharCode(0x003e); break;
                        case 'nbsp': ch = String.fromCharCode(0x00a0); break;
                        case 'iexcl': ch = String.fromCharCode(0x00a1); break;
                        case 'cent': ch = String.fromCharCode(0x00a2); break;
                        case 'pound': ch = String.fromCharCode(0x00a3); break;
                        case 'curren': ch = String.fromCharCode(0x00a4); break;
                        case 'yen': ch = String.fromCharCode(0x00a5); break;
                        case 'brvbar': ch = String.fromCharCode(0x00a6); break;
                        case 'sect': ch = String.fromCharCode(0x00a7); break;
                        case 'uml': ch = String.fromCharCode(0x00a8); break;
                        case 'copy': ch = String.fromCharCode(0x00a9); break;
                        case 'ordf': ch = String.fromCharCode(0x00aa); break;
                        case 'laquo': ch = String.fromCharCode(0x00ab); break;
                        case 'not': ch = String.fromCharCode(0x00ac); break;
                        case 'shy': ch = String.fromCharCode(0x00ad); break;
                        case 'reg': ch = String.fromCharCode(0x00ae); break;
                        case 'macr': ch = String.fromCharCode(0x00af); break;
                        case 'deg': ch = String.fromCharCode(0x00b0); break;
                        case 'plusmn': ch = String.fromCharCode(0x00b1); break;
                        case 'sup2': ch = String.fromCharCode(0x00b2); break;
                        case 'sup3': ch = String.fromCharCode(0x00b3); break;
                        case 'acute': ch = String.fromCharCode(0x00b4); break;
                        case 'micro': ch = String.fromCharCode(0x00b5); break;
                        case 'para': ch = String.fromCharCode(0x00b6); break;
                        case 'middot': ch = String.fromCharCode(0x00b7); break;
                        case 'cedil': ch = String.fromCharCode(0x00b8); break;
                        case 'sup1': ch = String.fromCharCode(0x00b9); break;
                        case 'ordm': ch = String.fromCharCode(0x00ba); break;
                        case 'raquo': ch = String.fromCharCode(0x00bb); break;
                        case 'frac14': ch = String.fromCharCode(0x00bc); break;
                        case 'frac12': ch = String.fromCharCode(0x00bd); break;
                        case 'frac34': ch = String.fromCharCode(0x00be); break;
                        case 'iquest': ch = String.fromCharCode(0x00bf); break;
                        case 'Agrave': ch = String.fromCharCode(0x00c0); break;
                        case 'Aacute': ch = String.fromCharCode(0x00c1); break;
                        case 'Acirc': ch = String.fromCharCode(0x00c2); break;
                        case 'Atilde': ch = String.fromCharCode(0x00c3); break;
                        case 'Auml': ch = String.fromCharCode(0x00c4); break;
                        case 'Aring': ch = String.fromCharCode(0x00c5); break;
                        case 'AElig': ch = String.fromCharCode(0x00c6); break;
                        case 'Ccedil': ch = String.fromCharCode(0x00c7); break;
                        case 'Egrave': ch = String.fromCharCode(0x00c8); break;
                        case 'Eacute': ch = String.fromCharCode(0x00c9); break;
                        case 'Ecirc': ch = String.fromCharCode(0x00ca); break;
                        case 'Euml': ch = String.fromCharCode(0x00cb); break;
                        case 'Igrave': ch = String.fromCharCode(0x00cc); break;
                        case 'Iacute': ch = String.fromCharCode(0x00cd); break;
                        case 'Icirc': ch = String.fromCharCode(0x00ce); break;
                        case 'Iuml': ch = String.fromCharCode(0x00cf); break;
                        case 'ETH': ch = String.fromCharCode(0x00d0); break;
                        case 'Ntilde': ch = String.fromCharCode(0x00d1); break;
                        case 'Ograve': ch = String.fromCharCode(0x00d2); break;
                        case 'Oacute': ch = String.fromCharCode(0x00d3); break;
                        case 'Ocirc': ch = String.fromCharCode(0x00d4); break;
                        case 'Otilde': ch = String.fromCharCode(0x00d5); break;
                        case 'Ouml': ch = String.fromCharCode(0x00d6); break;
                        case 'times': ch = String.fromCharCode(0x00d7); break;
                        case 'Oslash': ch = String.fromCharCode(0x00d8); break;
                        case 'Ugrave': ch = String.fromCharCode(0x00d9); break;
                        case 'Uacute': ch = String.fromCharCode(0x00da); break;
                        case 'Ucirc': ch = String.fromCharCode(0x00db); break;
                        case 'Uuml': ch = String.fromCharCode(0x00dc); break;
                        case 'Yacute': ch = String.fromCharCode(0x00dd); break;
                        case 'THORN': ch = String.fromCharCode(0x00de); break;
                        case 'szlig': ch = String.fromCharCode(0x00df); break;
                        case 'agrave': ch = String.fromCharCode(0x00e0); break;
                        case 'aacute': ch = String.fromCharCode(0x00e1); break;
                        case 'acirc': ch = String.fromCharCode(0x00e2); break;
                        case 'atilde': ch = String.fromCharCode(0x00e3); break;
                        case 'auml': ch = String.fromCharCode(0x00e4); break;
                        case 'aring': ch = String.fromCharCode(0x00e5); break;
                        case 'aelig': ch = String.fromCharCode(0x00e6); break;
                        case 'ccedil': ch = String.fromCharCode(0x00e7); break;
                        case 'egrave': ch = String.fromCharCode(0x00e8); break;
                        case 'eacute': ch = String.fromCharCode(0x00e9); break;
                        case 'ecirc': ch = String.fromCharCode(0x00ea); break;
                        case 'euml': ch = String.fromCharCode(0x00eb); break;
                        case 'igrave': ch = String.fromCharCode(0x00ec); break;
                        case 'iacute': ch = String.fromCharCode(0x00ed); break;
                        case 'icirc': ch = String.fromCharCode(0x00ee); break;
                        case 'iuml': ch = String.fromCharCode(0x00ef); break;
                        case 'eth': ch = String.fromCharCode(0x00f0); break;
                        case 'ntilde': ch = String.fromCharCode(0x00f1); break;
                        case 'ograve': ch = String.fromCharCode(0x00f2); break;
                        case 'oacute': ch = String.fromCharCode(0x00f3); break;
                        case 'ocirc': ch = String.fromCharCode(0x00f4); break;
                        case 'otilde': ch = String.fromCharCode(0x00f5); break;
                        case 'ouml': ch = String.fromCharCode(0x00f6); break;
                        case 'divide': ch = String.fromCharCode(0x00f7); break;
                        case 'oslash': ch = String.fromCharCode(0x00f8); break;
                        case 'ugrave': ch = String.fromCharCode(0x00f9); break;
                        case 'uacute': ch = String.fromCharCode(0x00fa); break;
                        case 'ucirc': ch = String.fromCharCode(0x00fb); break;
                        case 'uuml': ch = String.fromCharCode(0x00fc); break;
                        case 'yacute': ch = String.fromCharCode(0x00fd); break;
                        case 'thorn': ch = String.fromCharCode(0x00fe); break;
                        case 'yuml': ch = String.fromCharCode(0x00ff); break;
                        case 'OElig': ch = String.fromCharCode(0x0152); break;
                        case 'oelig': ch = String.fromCharCode(0x0153); break;
                        case 'Scaron': ch = String.fromCharCode(0x0160); break;
                        case 'scaron': ch = String.fromCharCode(0x0161); break;
                        case 'Yuml': ch = String.fromCharCode(0x0178); break;
                        case 'fnof': ch = String.fromCharCode(0x0192); break;
                        case 'circ': ch = String.fromCharCode(0x02c6); break;
                        case 'tilde': ch = String.fromCharCode(0x02dc); break;
                        case 'Alpha': ch = String.fromCharCode(0x0391); break;
                        case 'Beta': ch = String.fromCharCode(0x0392); break;
                        case 'Gamma': ch = String.fromCharCode(0x0393); break;
                        case 'Delta': ch = String.fromCharCode(0x0394); break;
                        case 'Epsilon': ch = String.fromCharCode(0x0395); break;
                        case 'Zeta': ch = String.fromCharCode(0x0396); break;
                        case 'Eta': ch = String.fromCharCode(0x0397); break;
                        case 'Theta': ch = String.fromCharCode(0x0398); break;
                        case 'Iota': ch = String.fromCharCode(0x0399); break;
                        case 'Kappa': ch = String.fromCharCode(0x039a); break;
                        case 'Lambda': ch = String.fromCharCode(0x039b); break;
                        case 'Mu': ch = String.fromCharCode(0x039c); break;
                        case 'Nu': ch = String.fromCharCode(0x039d); break;
                        case 'Xi': ch = String.fromCharCode(0x039e); break;
                        case 'Omicron': ch = String.fromCharCode(0x039f); break;
                        case 'Pi': ch = String.fromCharCode(0x03a0); break;
                        case ' Rho ': ch = String.fromCharCode(0x03a1); break;
                        case 'Sigma': ch = String.fromCharCode(0x03a3); break;
                        case 'Tau': ch = String.fromCharCode(0x03a4); break;
                        case 'Upsilon': ch = String.fromCharCode(0x03a5); break;
                        case 'Phi': ch = String.fromCharCode(0x03a6); break;
                        case 'Chi': ch = String.fromCharCode(0x03a7); break;
                        case 'Psi': ch = String.fromCharCode(0x03a8); break;
                        case 'Omega': ch = String.fromCharCode(0x03a9); break;
                        case 'alpha': ch = String.fromCharCode(0x03b1); break;
                        case 'beta': ch = String.fromCharCode(0x03b2); break;
                        case 'gamma': ch = String.fromCharCode(0x03b3); break;
                        case 'delta': ch = String.fromCharCode(0x03b4); break;
                        case 'epsilon': ch = String.fromCharCode(0x03b5); break;
                        case 'zeta': ch = String.fromCharCode(0x03b6); break;
                        case 'eta': ch = String.fromCharCode(0x03b7); break;
                        case 'theta': ch = String.fromCharCode(0x03b8); break;
                        case 'iota': ch = String.fromCharCode(0x03b9); break;
                        case 'kappa': ch = String.fromCharCode(0x03ba); break;
                        case 'lambda': ch = String.fromCharCode(0x03bb); break;
                        case 'mu': ch = String.fromCharCode(0x03bc); break;
                        case 'nu': ch = String.fromCharCode(0x03bd); break;
                        case 'xi': ch = String.fromCharCode(0x03be); break;
                        case 'omicron': ch = String.fromCharCode(0x03bf); break;
                        case 'pi': ch = String.fromCharCode(0x03c0); break;
                        case 'rho': ch = String.fromCharCode(0x03c1); break;
                        case 'sigmaf': ch = String.fromCharCode(0x03c2); break;
                        case 'sigma': ch = String.fromCharCode(0x03c3); break;
                        case 'tau': ch = String.fromCharCode(0x03c4); break;
                        case 'upsilon': ch = String.fromCharCode(0x03c5); break;
                        case 'phi': ch = String.fromCharCode(0x03c6); break;
                        case 'chi': ch = String.fromCharCode(0x03c7); break;
                        case 'psi': ch = String.fromCharCode(0x03c8); break;
                        case 'omega': ch = String.fromCharCode(0x03c9); break;
                        case 'thetasym': ch = String.fromCharCode(0x03d1); break;
                        case 'upsih': ch = String.fromCharCode(0x03d2); break;
                        case 'piv': ch = String.fromCharCode(0x03d6); break;
                        case 'ensp': ch = String.fromCharCode(0x2002); break;
                        case 'emsp': ch = String.fromCharCode(0x2003); break;
                        case 'thinsp': ch = String.fromCharCode(0x2009); break;
                        case 'zwnj': ch = String.fromCharCode(0x200c); break;
                        case 'zwj': ch = String.fromCharCode(0x200d); break;
                        case 'lrm': ch = String.fromCharCode(0x200e); break;
                        case 'rlm': ch = String.fromCharCode(0x200f); break;
                        case 'ndash': ch = String.fromCharCode(0x2013); break;
                        case 'mdash': ch = String.fromCharCode(0x2014); break;
                        case 'lsquo': ch = String.fromCharCode(0x2018); break;
                        case 'rsquo': ch = String.fromCharCode(0x2019); break;
                        case 'sbquo': ch = String.fromCharCode(0x201a); break;
                        case 'ldquo': ch = String.fromCharCode(0x201c); break;
                        case 'rdquo': ch = String.fromCharCode(0x201d); break;
                        case 'bdquo': ch = String.fromCharCode(0x201e); break;
                        case 'dagger': ch = String.fromCharCode(0x2020); break;
                        case 'Dagger': ch = String.fromCharCode(0x2021); break;
                        case 'bull': ch = String.fromCharCode(0x2022); break;
                        case 'hellip': ch = String.fromCharCode(0x2026); break;
                        case 'permil': ch = String.fromCharCode(0x2030); break;
                        case 'prime': ch = String.fromCharCode(0x2032); break;
                        case 'Prime': ch = String.fromCharCode(0x2033); break;
                        case 'lsaquo': ch = String.fromCharCode(0x2039); break;
                        case 'rsaquo': ch = String.fromCharCode(0x203a); break;
                        case 'oline': ch = String.fromCharCode(0x203e); break;
                        case 'frasl': ch = String.fromCharCode(0x2044); break;
                        case 'euro': ch = String.fromCharCode(0x20ac); break;
                        case 'image': ch = String.fromCharCode(0x2111); break;
                        case 'weierp': ch = String.fromCharCode(0x2118); break;
                        case 'real': ch = String.fromCharCode(0x211c); break;
                        case 'trade': ch = String.fromCharCode(0x2122); break;
                        case 'alefsym': ch = String.fromCharCode(0x2135); break;
                        case 'larr': ch = String.fromCharCode(0x2190); break;
                        case 'uarr': ch = String.fromCharCode(0x2191); break;
                        case 'rarr': ch = String.fromCharCode(0x2192); break;
                        case 'darr': ch = String.fromCharCode(0x2193); break;
                        case 'harr': ch = String.fromCharCode(0x2194); break;
                        case 'crarr': ch = String.fromCharCode(0x21b5); break;
                        case 'lArr': ch = String.fromCharCode(0x21d0); break;
                        case 'uArr': ch = String.fromCharCode(0x21d1); break;
                        case 'rArr': ch = String.fromCharCode(0x21d2); break;
                        case 'dArr': ch = String.fromCharCode(0x21d3); break;
                        case 'hArr': ch = String.fromCharCode(0x21d4); break;
                        case 'forall': ch = String.fromCharCode(0x2200); break;
                        case 'part': ch = String.fromCharCode(0x2202); break;
                        case 'exist': ch = String.fromCharCode(0x2203); break;
                        case 'empty': ch = String.fromCharCode(0x2205); break;
                        case 'nabla': ch = String.fromCharCode(0x2207); break;
                        case 'isin': ch = String.fromCharCode(0x2208); break;
                        case 'notin': ch = String.fromCharCode(0x2209); break;
                        case 'ni': ch = String.fromCharCode(0x220b); break;
                        case 'prod': ch = String.fromCharCode(0x220f); break;
                        case 'sum': ch = String.fromCharCode(0x2211); break;
                        case 'minus': ch = String.fromCharCode(0x2212); break;
                        case 'lowast': ch = String.fromCharCode(0x2217); break;
                        case 'radic': ch = String.fromCharCode(0x221a); break;
                        case 'prop': ch = String.fromCharCode(0x221d); break;
                        case 'infin': ch = String.fromCharCode(0x221e); break;
                        case 'ang': ch = String.fromCharCode(0x2220); break;
                        case 'and': ch = String.fromCharCode(0x2227); break;
                        case 'or': ch = String.fromCharCode(0x2228); break;
                        case 'cap': ch = String.fromCharCode(0x2229); break;
                        case 'cup': ch = String.fromCharCode(0x222a); break;
                        case 'int': ch = String.fromCharCode(0x222b); break;
                        case 'there4': ch = String.fromCharCode(0x2234); break;
                        case 'sim': ch = String.fromCharCode(0x223c); break;
                        case 'cong': ch = String.fromCharCode(0x2245); break;
                        case 'asymp': ch = String.fromCharCode(0x2248); break;
                        case 'ne': ch = String.fromCharCode(0x2260); break;
                        case 'equiv': ch = String.fromCharCode(0x2261); break;
                        case 'le': ch = String.fromCharCode(0x2264); break;
                        case 'ge': ch = String.fromCharCode(0x2265); break;
                        case 'sub': ch = String.fromCharCode(0x2282); break;
                        case 'sup': ch = String.fromCharCode(0x2283); break;
                        case 'nsub': ch = String.fromCharCode(0x2284); break;
                        case 'sube': ch = String.fromCharCode(0x2286); break;
                        case 'supe': ch = String.fromCharCode(0x2287); break;
                        case 'oplus': ch = String.fromCharCode(0x2295); break;
                        case 'otimes': ch = String.fromCharCode(0x2297); break;
                        case 'perp': ch = String.fromCharCode(0x22a5); break;
                        case 'sdot': ch = String.fromCharCode(0x22c5); break;
                        case 'lceil': ch = String.fromCharCode(0x2308); break;
                        case 'rceil': ch = String.fromCharCode(0x2309); break;
                        case 'lfloor': ch = String.fromCharCode(0x230a); break;
                        case 'rfloor': ch = String.fromCharCode(0x230b); break;
                        case 'lang': ch = String.fromCharCode(0x2329); break;
                        case 'rang': ch = String.fromCharCode(0x232a); break;
                        case 'loz': ch = String.fromCharCode(0x25ca); break;
                        case 'spades': ch = String.fromCharCode(0x2660); break;
                        case 'clubs': ch = String.fromCharCode(0x2663); break;
                        case 'hearts': ch = String.fromCharCode(0x2665); break;
                        case 'diams': ch = String.fromCharCode(0x2666); break;
                        default: ch = ''; break;
                    }
                }
                i = semicolonIndex;
            }
        }
        out += ch;
    }
    return out;
}

// Getters / Setters
function getTabId() {
    var tabId = $('#hActiveTab').val();
    if (tabId == null || tabId == '' || isNaN(tabId) || (tabId != TAB_RECENT && tabId != TAB_POPULAR && tabId != TAB_ALL)) {
        tabId = DEFAULT_TAB;
    }
    tabId = parseInt(tabId);
    return tabId;
}
function setTabId(tabId) {
    // check invalid values
    if (tabId == null || tabId == '' || isNaN(tabId) || (tabId != TAB_RECENT && tabId != TAB_POPULAR && tabId != TAB_ALL)) {
        tabId = DEFAULT_TAB;
    }

    $('#hActiveTab').val(tabId);
}

function getChannelId() {
    var channelId = $('#hChannel').val();
    if (channelId == null || channelId == '' || isNaN(channelId) || channelId < 0) {
        channelId = DEFAULT_CHANNEL;
    }
    channelId = parseInt(channelId);
    return channelId;
}
function setChannelId(channelId) {
    if (channelId == null || channelId == '' || isNaN(channelId) || channelId < 0) {
        channelId = DEFAULT_CHANNEL;
    }
    channelId = parseInt(channelId);

    $('#hChannel').val(channelId);
}

function getViewId() {
    var viewId = $('#hDisplayType').val();

    if (viewId == null || viewId == '' || isNaN(viewId) || (viewId != THUMBNAIL_VIEW && viewId != LIST_VIEW)) {
        viewId = DEFAULT_VIEW;
    }
    viewId = parseInt(viewId);
    return viewId;
}
function setViewId(viewId) {
    if (viewId == null || viewId == '' || isNaN(viewId) || (viewId != THUMBNAIL_VIEW && viewId != LIST_VIEW)) {
        viewId = DEFAULT_VIEW;
    }
    viewId = parseInt(viewId);

    $('#hDisplayType').val(viewId);
}

function getVideoId() {
    var videoId = $('#hVideoId').val();
    if (videoId == null || videoId == '' || isNaN(videoId) || videoId <= 0) {
        videoId = DEFAULT_VIDEO;
    }
    videoId = parseInt(videoId);
    return videoId;
}
function setVideoId(videoId) {
    if (videoId == null || videoId == '' || isNaN(videoId) || videoId <= 0) {
        videoId = DEFAULT_VIDEO;
    }
    videoId = parseInt(videoId);
    $('#hVideoId').val(videoId);
}

function getSearchTerm() {
    var searchTerm = $('#hSearch').val();
    if (searchTerm == '') {
        searchTerm = DEFAULT_SEARCH;
    }
    searchTerm = urlDecode(searchTerm);
    return searchTerm;
}
function setSearchTerm(searchTerm) {
    if (searchTerm.toLowerCase() != 'type search here') {
        searchTerm = urlEncode(searchTerm);
    } else {
        searchTerm = '';
    }

    $('#hSearch').val(searchTerm);
}

function getDisplayFunction(tabId) {
    var func = FUNC_RECENT;
    switch (tabId) {
        case TAB_RECENT:
            func = FUNC_RECENT;
            break;
        case TAB_POPULAR:
            func = FUNC_POPULAR;
            break;
        case TAB_ALL:
            func = FUNC_ALL;
            break;
    }
    return func;
}

function getHash() {
    var hash = '';

    hash += 'tab=' + getTabId();
    hash += '&view=' + getViewId();
    hash += '&vid=' + getVideoId();
    hash += '&ch=' + getChannelId();
    var searchTerm = getSearchTerm();
    searchTerm = urlEncode(searchTerm);
    hash += '&q=' + searchTerm;
    
    return hash;
}

function setHistory() {
    $.history.load(getHash());
}

function HashContainer() { }
HashContainer.prototype.VideoId = DEFAULT_VIDEO;
HashContainer.prototype.TabId = DEFAULT_TAB;
HashContainer.prototype.ChannelId = DEFAULT_CHANNEL;
HashContainer.prototype.SearchTerm = DEFAULT_SEARCH;
HashContainer.prototype.ViewId = DEFAULT_VIEW;

function getHashContainer(hashValue) {
    var hContainer = new HashContainer();

    // decode hash values
    var params = hashValue.split('&');
    var item;
    var key = '';
    var value = '';
    for (var i = 0; i < params.length; i++) {
        item = params[i].split('=');
        key = item[0].toLowerCase();
        value = item[1];

        switch (key) {
            case 'tab':
                hContainer.TabId = value;
                break;
            case 'view':
                hContainer.ViewId = value;
                break;
            case 'vid':
                hContainer.VideoId = value;
                break;
            case 'ch':
                hContainer.ChannelId = value;
                break;
            case 'q':
                hContainer.SearchTerm = value;
        }
    }

    return hContainer;
}

function getHistory(hash) {
    if (hash != null && hash != '') {
        // decode hash values
        var params = hash.split('&');
        var item;
        var key = '';
        var value = '';
        for (var i = 0; i < params.length; i++) {
            item = params[i].split('=');
            key = item[0].toLowerCase();
            value = item[1];

            switch (key) {
                case 'tab':
                    setTabId(value);
                    break;
                case 'view':
                    setViewId(value);
                    break;
                case 'vid':
                    setVideoId(value);
                    break;
                case 'ch':
                    setChannelId(value);
                    break;
                case 'q':
                    value = urlDecode(value);
                    setSearchTerm(value);
            }
        }
    }
    
    // set defaults
    updateTabUI();
    updateViewUI();
    updateChannelUI();
    updateSearchUI();
    updateClearUI();  

    var prevHash = $('#hHash').val();

    var currentHashContainer = getHashContainer(hash);
    var prevHashContainer = getHashContainer(prevHash);

    // only update display if property other than video has changed or no hash set
    var updateVideoDisplay = false;

    var channelChanged = (currentHashContainer.ChannelId != prevHashContainer.ChannelId);
    var searchChanged = (currentHashContainer.SearchTerm != prevHashContainer.SearchTerm);
    var tabChanged = (currentHashContainer.TabId != prevHashContainer.TabId);
    var viewChanged = (currentHashContainer.ViewId != prevHashContainer.ViewId);
    var videoChanged = (currentHashContainer.VideoId != prevHashContainer.VideoId);
    var prevEmpty = (prevHash == '');
    var noChange = (prevHash == hash);

    updateVideoDisplay = channelChanged || searchChanged || tabChanged || viewChanged || prevEmpty || noChange;

    if (videoChanged || prevEmpty) {
        getVideo();
        // update highlight (if video in list, select it, else hide selections)
        updatePlaylistUI(currentHashContainer.VideoId);
    }
    
    if (updateVideoDisplay) {
        // show video display
        getDisplayVideos();
    }

    // save hash value
    $('#hHash').val(hash);

    // reset page title
    document.title = "Walmart Media Room";
}

function setSelectedTab(tabId) {
    // clear existing search
    setChannelId(DEFAULT_CHANNEL);
    setSearchTerm(DEFAULT_SEARCH);

    // set tab id
    setTabId(tabId);
    // update UI
    updateTabUI();
    updateChannelUI();
    updateSearchUI();

    // hide clear button
    $('#clearButton').hide();
    
    // reload videos
    setHistory();
}

function setSelectedView(viewId) {
    // set view id
    setViewId(viewId);
    // update UI
    updateViewUI();
    
    setHistory();
}

function setSelectedChannel(channelId) {
    // set channel id
    setChannelId(channelId);
    // update UI
    updateChannelUI();

    setHistory();
}

function setSelectedSearch(searchTerm) {
    // set search term
    setSearchTerm(searchTerm);
    // update UI
    updateSearchUI();

    setHistory();
    return false;
}

function setSelectedVideo(videoId) {
    // set video id
    setVideoId(videoId);

    setHistory();
}

function setClear() {
    // clear existing search
    setChannelId(DEFAULT_CHANNEL);
    setSearchTerm(DEFAULT_SEARCH);

    // update UI
    updateChannelUI();
    updateSearchUI();

    // hide clear button
    $('#clearButton').hide();

    // reload videos
    setHistory();
}

// Slider functions
function getDisplayListWidth() {
    // get viewable area
    var pls = $('#videos ul');
    // get width of list
    var firstItem = $('#videos ul li:first');
    var leftMarginWidth = parseInt(firstItem.css('margin-left'));
    var rightMarginWidth = parseInt(firstItem.css('margin-right'));

    // get with of each item in list
    itemWidth = firstItem.width() + leftMarginWidth + rightMarginWidth;

    // get item count for list
    itemCount = $('#videos ul li').size();
    // total list width
    return itemWidth * itemCount;
}

function slideDisplayVideos(event, ui) {
    // get viewable area
    var pls = $('#videos ul');
    // find total list width
    var playlistWidth = getDisplayListWidth();
    // set size of list container
    pls.width(playlistWidth);

    // set slide bounds
    var slideMargin = playlistWidth - MAX_VIEWABLE_VIDEOS_WIDTH;
    if (slideMargin > 0) {
        var leftOffset = (((ui.value) / 100) * slideMargin * -1) + 'px';
        // set top of slider to percentage of slide
        pls.css({ left: leftOffset });
    }
}

function hideDisplayVideoSlider() {
    $('#slider').hide();
}

// UI Updates
function updateTabUI() {
    var tabId = getTabId();
    
    var tabRecent = $('#tabRecent'), tabPopular = $('#tabPopular'), tabAll = $('#tabAll');
    tabRecent.removeClass('active');
    tabPopular.removeClass('active');
    tabAll.removeClass('active');

    switch (tabId) {
        case TAB_RECENT:
            tabRecent.addClass('active');
            break;
        case TAB_POPULAR:
            tabPopular.addClass('active');
            break;
        case TAB_ALL:
            tabAll.addClass('active');
            break;
    }
}
function updateViewUI() {
    var viewId = getViewId();

    if (viewId == THUMBNAIL_VIEW) {
        $('#thumbSwitcher').addClass('active');
        $('#listSwitcher').removeClass('active');
    } else {
        $('#listSwitcher').addClass('active');
        $('#thumbSwitcher').removeClass('active');
    }
}
function updateChannelUI() {
    var channelId = getChannelId();

    $('#categorySearch').text('');
    
    var channel = getChannel(channelId);
    $('#categorySearch').text(channel.Name);

    updateClearUI();
}
function updateSearchUI() {
    var searchTerm = getSearchTerm();

    if (searchTerm == DEFAULT_SEARCH) {
        searchTerm = 'Type search here';
    }

    $('#txtSearch').val(searchTerm);
    updateClearUI();
}
function updateClearUI() {
    var channelId = getChannelId();
    var searchTerm = getSearchTerm();

    var showClearButton = false;

    if (channelId != DEFAULT_CHANNEL || searchTerm != DEFAULT_SEARCH) {
        showClearButton = true;
    }

    if (showClearButton) {
        $('#clearButton').show();
    } else {
        $('#clearButton').hide();
    }
}
function updateVideoMetaUI(title, duration, description, id) {
    updatePlaylistUI(id)
    setVideoMeta(title, duration, description);
}
function updatePlaylistUI(videoId) {
    var selectedPlaylistItemName = 'playlist' + videoId;

    $('#playlistInner ul li').each(function(i) {
        var divs = $(this).children('div');
        // if not selected item, clear selection
        if ($(this).attr('id') != selectedPlaylistItemName) {
            divs.each(function(j) {
                if ($(this).hasClass('playItemHeaderSelected')) {
                    $(this).removeClass('playItemHeaderSelected').addClass('playItemHeader');
                } else if ($(this).hasClass('playItemFooterSelected')) {
                    $(this).removeClass('playItemFooterSelected').addClass('playItemFooter');
                } else if ($(this).hasClass('playItemContentSelected')) {
                    $(this).removeClass('playItemContentSelected').addClass('playItemContent');
                }

            });
        } else {
            // selected item - set selection
            divs.each(function(j) {
                if ($(this).hasClass('playItemHeader')) {
                    $(this).removeClass('playItemHeader').addClass('playItemHeaderSelected');
                } else if ($(this).hasClass('playItemFooter')) {
                    $(this).removeClass('playItemFooter').addClass('playItemFooterSelected');
                } else if ($(this).hasClass('playItemContent')) {
                    $(this).removeClass('playItemContent').addClass('playItemContentSelected');
                }
            });
        }
    });
}

function setVideoMeta(title, duration, description) {
    $('#titleInformation h2').html(title);

    var vidDescription = '(' + duration + ') ' + htmlDecode(description);
    $('#videoDescription').html(vidDescription);
}

// User messages
function showLoading() {
    var loadingList = '<div id="loadingList" class="displayMessage">';
    loadingList += '<h3>Your Videos are Loading</h3>';
    loadingList += '<img src="/Images/Layout/bg_loadingSpark.gif" alt="Loading" title="Loading" />';
    loadingList += '</div>';

    $('#videos').html(loadingList);

    // hide slider
    hideDisplayVideoSlider();
}
function showEmptyList() {
    var emptyList = '<div id="emptyList" class="displayMessage">';
    emptyList += '<h4>No Videos were Found for this Search</h4>';
    emptyList += '<p>To change your search, select a new channel from the list above or type in a new search phrase in the textbox above.</p>';
    emptyList += '<p>To clear your search and start over, click the "Clear" button above.</p>';
    emptyList += '</div>';

    $('#videos').html(emptyList);

    // hide slider
    hideDisplayVideoSlider();
}
function showError() {
    var errorList = '<div id="errorList" class="displayMessage">';
    errorList += '<h4>An error occurred while loading your videos</h4>';
    errorList += '<p>Often times this is a temporary glitch that will be fixed within a few seconds or minutes.</p>';
    errorList += '<p>If you continue to see this error, please refresh the page.</p>';
    errorList += '</div>';

    $('#videos').html(errorList);

    // hide slider
    hideDisplayVideoSlider();
}

function showVideos(videos) {
    var viewId = getViewId();
    // get CSS classes for display
    var classToAdd = 'thumbnailView';
    var classToRemove = 'listView';
    // get template path
    var templateUrl = '/Templates/ThumbView.htm';
    if (viewId != THUMBNAIL_VIEW) {
        classToAdd = 'listView';
        classToRemove = 'thumbnailView';
        templateUrl = '/Templates/ListView.htm';
    }
    // select template to apply for view
    $('#videos').setTemplateURL(templateUrl);
    // fill template and assign classes
    $('#videos').processTemplate(videos).removeClass(classToRemove).addClass(classToAdd);

    if (getDisplayListWidth() >= MAX_VIEWABLE_VIDEOS_WIDTH) {
        // remove existing slider
        $('#sliderRange').slider('destroy');
        // create new slider
        $('#sliderRange').slider({
            orientation: "horizontal",
            min: 0,
            max: 100,
            value: 0,
            slide: slideDisplayVideos
        });
        $('#slider').show();
        
    } else {
        hideDisplayVideoSlider();
    }

    // get viewable area
    var pls = $('#videos ul');
    // find total list width
    var playlistWidth = getDisplayListWidth();
    // set size of list container
    pls.width(playlistWidth);
}
function showVideo(video) {
    var title = '', duration = '0:00', description = '';

    var xmlVideoId = video.Id;
    if (xmlVideoId == NO_VIDEO_SELECTED) {
        xmlVideoId = 100000;
    }

    if (swfobject.hasFlashPlayerVersion("8.0.0")) {
        // load video
        $('#player').html('<div id="flPlayer">&nbsp;</div>');        // add container for display
        swfobject.removeSWF('ytPlayer');                             // remove previous SWF (if any)
        var params = { allowScriptAccess: 'always', wmode: 'opaque', allowFullScreen: 'true' };
        var atts = { id: "ytPlayer" };
        var flashvars = { xmlPath: '/Feed/xml.aspx?id=' + xmlVideoId };
        swfobject.embedSWF('/Flash/VideoPlayer.swf', 'flPlayer', 575, 348, "8", false, flashvars, params, atts);
    } else {
        var noFlash = '<img src="/Images/Layout/video_Spark.gif" alt="Walmart Media Room" title="Walmart Media Room" />';
        noFlash += '<div id="noFlash">';
        noFlash += '<style type="text/css">#player img { margin-top: 100px; }</style>';
        noFlash += '<p>This site requires the latest version of Adobe\'s Flash Player.  If you are seeing this message, it is likely ';
        noFlash += 'that you do not have the latest version of Flash or Flash is disabled in your browser.</p>';
        noFlash += '<p><a href="http://www.adobe.com/go/getflashplayer/" target="_blank">Get the latest Flash player</a>.</p>';
        noFlash += '</div>';

        $('#player').html(noFlash);
    }
    
    if (video.Id != NO_VIDEO_SELECTED) {
        title = video.Title;
        duration = video.Duration;
        description = video.Description;
    } else {
        title = 'Video Not Available';
        duration = '0:00';
        description = 'This video is no longer available.';
    }
    
    setVideoMeta(title, duration, description);
}

// Channel DDL Functions
function makeShort() {
    $('#categoryDdl').slideToggle(500);
}
function makeTall() {
    $('#categoryDdl').slideToggle(500);
}