// settings

// millisecond interval to check if hash changes, for back/forward button functionality
window.check_hash_interval = 400;


// initialize the page
jQuery(document).ready(function() {
  // if there's a link to an episode in the location hash, load that
  // note: if there isn't an episode in the location hash, initTabs() will load first one after it's run its course
  if (hasEpisode(hashFromLocation()))
    selectEpisode(hashFromLocation(), true);
  initTabs();
  initHash();
});


// detect the href hash changes and auto update the page in certain circumstances
function initHash() {
  // Google Analytics
  var newpath = location.pathname + (hashFromLocation() ? '/'+hashFromLocation() : '')
  var refurl = window.oldHash===undefined ? null : location.protocol+'//'+location.host+location.pathname;
  if (refurl && window.oldHash) refurl = refurl+'/'+window.oldHash;
  try{
    if (refurl) window._gaq.push(['_setReferrerOverride',refurl])
    window._gaq.push(['_trackPageview',newpath])
  } catch(err) {alert(err);} 
  window.oldHash = hashFromLocation();
  window.hashInterval = setInterval(checkHashInterval, window.check_hash_interval);
}
function checkHashInterval() {
  var hash = hashFromLocation();
  if (window.oldHash != hash) {
    if (! hash)
      // if there's no hash choose the first one on the page
      selectTab(hashFromAnchor(tabFirst()), true);
    else if (hasEpisode(hash))
      // if there's an episode in the hash, load it (syncing the bottom part afterward)
      selectEpisode(hash, true);
    else
      // otherwise load the indicated tab (forcing first menu/etc to be selected if hash doesn't indicate otherwise)
      selectTab(hash, true);
    window.oldHash = hash;
  }
}
function updateHash(hash) {
  clearInterval(window.hashInterval);
  location.hash = hash;
  initHash();
}


function initEpisode() {
  // set up more/less links
  if (moreEpiDescLink()) {
    jQuery(moreEpiDescLink()).click(function(){
      expandEpisodeDescription();
      return false;
    });
  }
  if (lessEpiDescLink()) {
    jQuery(lessEpiDescLink()).click(function(){
      contractEpisodeDescription();
      return false;
    });
  }
}
function selectEpisode(hash, loadhash) {
  loadEpisode(hash, loadhash, true);
}
function loadEpisode(hash, loadhash, selectepi) {
  crossFadeBody(
    episodeBody(),
    episodeBody(),
    '/mediacasts/' + hash + '.js',
    function() {
      if (selectepi) {
        // note: same episode may be listed in multiple places, they should all be highlighted (or unhighlighted) when you select one
        episodeActives().removeClass('active');
        episodeHeaders(hash).addClass('active');
      }
    },
    function() {
      initEpisode();
      if (downloadUrlFromEpisodeBody()) {
        jQuery("#no_flash_url").attr('href',downloadUrlFromEpisodeBody());
        jQuery("#no_flash_url > img").css('visibility','visible');
      } else {
        jQuery("#no_flash_url > img").css('visibility','hidden');
      }
      if (swfobject.getFlashPlayerVersion().major > 9) {
        if (playerUrlFromEpisodeBody())
          swfobject.getObjectById('videoplayer').playFile(playerUrlFromEpisodeBody());
        else
          swfobject.getObjectById('videoplayer').playFile('http://invalid.url.test/');
      }
      if (loadhash)
        selectTab(bottomHashFromEpisodeBody());
      if (storeWidgetBody()) {
        if (storeUrl() && (storeImage() || storeDescription())) {
          if (! window.default_store_widget) window.default_store_widget = storeWidgetBody().innerHTML;
          crossFade(storeWidgetBody(), storeWidgetBody(), makeStoreWidget(storeUrl(), storeImage(), storeDescription(), storeButtonTitle()));
        } else if (window.default_store_widget) {
          crossFade(storeWidgetBody(), storeWidgetBody(), window.default_store_widget);
        } else {
          jQuery(storeWidgetBody()).hide();
          setVisibility(storeWidgetBody(), storeWidgetBody(), 'visible');
          fadeIn(storeWidgetBody(), storeWidgetBody(), window.anim_times.fade_in);
        }
      }
    }
  );
}
function makeStoreWidget(url, image, description, title) {
  return (image ? ('<p class="WidgetStoreImage"><a href="' + entityEscape(url) + '"><img class="WidgetStoreImage" src="' + entityEscape(image) + '" /></a></p>') : '') +
    (description ? ('<p class="WidgetStoreDescription">' + entityEscape(description) + '</p>') : '') +
    '<p class="WidgetStoreUrl"><a href="' + entityEscape(url) + '"><span class="WidgetBuyBtn"><span>' + (title ? entityEscape(title) : 'Buy It Now') + '</span></span></a></p>';
}
function entityEscape(str) {
  return str.replace(/&/gm, '&amp;').replace(/"/gm, '&quot;').replace(/>/gm, '&gt;').replace(/</gm, '&lt;');
}
function expandEpisodeDescription() {
  var shortdesc = shortEpiDesc();
  var longdesc = longEpiDesc();
  var startheight = shortdesc.clientHeight;
  // swap to longer one, remember its normal height
  jQuery(shortdesc).hide();
  jQuery(longdesc).show();
  var endheight = longdesc.clientHeight;
  // set long one to short one's height
  jQuery(longdesc).css('height', startheight);
  // animate the long one to normal height
  jQuery(longdesc).animate({height: endheight}, {
    duration: 'fast',
    complete: function() {
      jQuery(this).css('height', null);
    }
  });
}
function contractEpisodeDescription() {
  var shortdesc = shortEpiDesc();
  var longdesc = longEpiDesc();
  var startheight = longdesc.clientHeight;
  // get the height of the short one (while it's still hidden, which is not easy)
  jQuery(shortdesc).css('width', longdesc.clientWidth);
  jQuery(shortdesc).css('marginLeft', -1000);
  jQuery(shortdesc).show();
  var endheight = shortdesc.clientHeight;
  jQuery(shortdesc).hide();
  jQuery(shortdesc).css('marginLeft', null);
  jQuery(shortdesc).css('width', null);
  // animate the long one to the short height, swapping which is shown when we're done
  jQuery(longdesc).animate({height: endheight}, {
    duration: 'fast',
    complete: function(){
      jQuery(this).css('height', null);
      jQuery(this).hide();
      jQuery(shortdesc).show();
    }
  });
}


// initialize bottom tabs (jquery tabs doesn't support spinners properly and requires junking/rewriting)
function initTabs() {
  // link tab click events to selecting tabs
  if (tabHeaders()) tabHeaders().each(function(){
    jQuery(this).click(function(){
      var hash = hashFromAnchor(this);
      selectTab(hash);
      updateHash(hash);
      return false;
    });
  });
  // select initial tab based on location hash, or select first one
  // skipped if there's an episode in location hash
  var hash = hashFromLocation();
  if (! hasEpisode(hash)) {
    if (! hash) hash = hashFromAnchor(tabFirst());
    selectTab(hash, false, true);
  }
}
function selectTab(hash, forcedefault, loadepisode) {
  var tab = tabHeader(hash);
  var lastTab = tabActive();
  if (tab != lastTab) {
    // fade out old body (if there was one), load via ajax (if not alredy done previously), then fade in new one
    crossFadeCachedBody(
      tabArea(),
      tabBodies(hash),
      tabBody(hashFromAnchor(lastTab)),
      tabBody(hash),
      '/mediacasts/tabs/' + hash + '.js',
      function(){
        // unselect old tab, select new one
        tabHeaders().removeClass('active');
        jQuery(tab).addClass('active');        
      },
      function(){
        initMenu(hash);
        var secthash = hasSection(hash) ? hash : hashFromAnchor(sectionActive(hash));
        if (secthash && sectionBody(secthash)) {
          initSection(secthash, loadepisode);
          sectionBody(secthash).finishedinit = true;
        }
      },
      function() {
        // var gohash = hasMenu(hash) ? hash : (forcedefault ? hashFromAnchor(menuFirst(hash)) : null);
        // if (gohash) selectMenu(gohash, forcedefault);
        if (hasMenu(hash)) selectMenu(hash, forcedefault);
      }
    );
  } else {
    var gohash = hasMenu(hash) ? hash : (forcedefault ? hashFromAnchor(menuFirst(hash)) : null);
    if (gohash) selectMenu(gohash, forcedefault);
  }
}


// initialize bottom left menu accordion
function initMenu(hash) {
  // set up the jquery accordion widget for the menu
  if (menuArea(hash)) jQuery(menuArea(hash)).accordion({
    header: 'div.SubmenuTitle',
    active: 'div.active',
    autoHeight: false,
    clearStyle: true,
    collapsible: true,
    changestart: function(event, ui){
      jQuery(ui.newHeader).addClass('active');
      jQuery(ui.oldHeader).removeClass('active');
      if (! window.cancelHash && hashFromAnchor(ui.newHeader)) updateHash(hashFromAnchor(ui.newHeader));
    }
  });
  // link menu sub item click events to selecting sections
  if (sectionHeaders(hash)) sectionHeaders(hash).each(function(){
    jQuery(this).click(function(){
      var sechash = hashFromAnchor(this);
      selectSection(sechash);
      updateHash(sechash);
      return false;
    });
  });
}
function selectMenu(hash, forcedefault) {
  if (hash != hashFromAnchor(menuActive(hash))) {
    window.cancelHash = true; // ugg
    jQuery(menuArea(hash)).accordion('activate', menuHeader(hash));
    window.cancelHash = false;
  }
  var gohash = hasSection(hash) ? hash : (forcedefault ? hashFromAnchor(sectionFirst(hash)) : null);
  if (gohash) selectSection(gohash, forcedefault);
}

// initialize bottom right section
function initSection(hash, loadepisode) {
  // set up the accordion thing
  if (partArea(hash)) jQuery(partArea(hash)).accordion({
    header: 'div.RowTitle',
    active: 'div.active',
    autoHeight: false,
    clearStyle: true,
    collapsible: true,
    changestart: function(event, ui){
      jQuery(ui.newHeader).addClass('active');
      jQuery(ui.oldHeader).removeClass('active');
      if (! window.cancelHash && hashFromAnchor(ui.newHeader)) updateHash(hashFromAnchor(ui.newHeader));
    }
  });
  // set up section breadcrumb header to select the correct left side menu
  if (sectionCrumb(hash)) jQuery(sectionCrumb(hash)).click(function(){
    var hash = hashFromAnchor(this);
    selectMenu(hash);
    updateHash(hash);
    return false;
  });
  // set up episode boxes to...
  if (episodesSect(hash)) {
    episodesSect(hash).each(function(){
      // ...to repsond to click events
      jQuery(this).click(function(){
        var hash = hashFromAnchor(this);
        if (topHashFromEpisodeBody() != hash) {
          selectEpisode(hash);
          updateHash(hash);
        }
        return false;
      });
      // ...to be pre-selected if they represent another link to an already-playing episode
      if (topHashFromEpisodeBody() == hashFromAnchor(this))
        jQuery(this).addClass('active');
    });
    // if given 'loadepisode' flag, load selected episode (selecting first one if none selected)
    if (loadepisode) {
      if (! episodeActives()[0]) jQuery(episodesSect(hash)[0]).addClass('active');
      if (episodeActives()[0]) loadEpisode(hashFromAnchor(episodeActives()[0]));
    }
  }
}
function selectSection(hash, forcedefault) {
  var section = sectionHeader(hash);
  var lastSection = sectionActive(hash);
  if (section != lastSection) {
    // fade out old body, load via ajax (if not already done previously), then fade in new one
    crossFadeCachedBody(
      tabBody(hash),
      sectionBodies(hash),
      sectionBody(hashFromAnchor(lastSection)),
      sectionBody(hash),
      '/mediacasts/sections/' + hash + '.js',
      function(){
        // unselect old section, select new one
        sectionHeaders(hash).removeClass('active');
        jQuery(section).addClass('active');
      },
      function(){
        initSection(hash);
      },
      function() {
        // var gohash = hasPart(hash) ? hash : (forcedefault ? hashFromAnchor(partFirst(hash)) : null);
        // if (gohash) selectPart(gohash, forcedefault);
        if (hasPart(hash)) selectPart(hash);
      }
    );
  } else {
    var gohash = hasPart(hash) ? hash : (forcedefault ? hashFromAnchor(partFirst(hash)) : null);
    if (gohash) selectPart(gohash, forcedefault);
  }
}
function selectPart(hash, forcedefault) {
  window.cancelHash = true; // ugg
  jQuery(partArea(hash)).accordion('activate', partHeader(hash));
  window.cancelHash = false;
}

// utility stubs for common hash and selector functionality

function hashFromAnchor(elem) { return elem && jQuery(elem).find('a')[0] ? stripHashMark(jQuery(elem).find('a')[0].href) : null; }
function hashFromLocation()   { var h = location.hash; return h && h != '#archive' ? stripHashMark(h) : null; }
function topHashFromEpisodeBody(){ return hashFromAnchor(episodeBody()); }
function bottomHashFromEpisodeBody(){ return jQuery('input#episode_hash')[0] ? jQuery('input#episode_hash')[0].value : null; }
function playerUrlFromEpisodeBody(){ return jQuery('input#playerfile')[0] ? jQuery('input#playerfile')[0].value : null; }
function downloadUrlFromEpisodeBody(){ return jQuery('input#downloadfile')[0] ? jQuery('input#downloadfile')[0].value : null; }
function storeUrl(){ return jQuery('input#store_url')[0] ? jQuery('input#store_url')[0].value : null; }
function storeImage(){ return jQuery('input#store_image')[0] ? jQuery('input#store_image')[0].value : null; }
function storeDescription(){ return jQuery('input#store_description')[0] ? jQuery('input#store_description')[0].value : null; }
function storeButtonTitle(){ return jQuery('input#store_button_title')[0] ? jQuery('input#store_button_title')[0].value : null; }

function storeWidgetBody()    { return                     jQuery('.TelevisionLayout .Top .RightSidebar #container01 .content-associated-product .ContentInfo')[0]; }
function episodeBody()        { return                     jQuery('.TelevisionLayout .Top .TelevisionFeature .FeatureBottom')[0]; }
function tabArea()            { return                     jQuery('.TelevisionLayout .Bottom')[0]; }
function tabFirst()           { return                     jQuery('.TelevisionLayout .Bottom > ul li')[0]; }
function tabActive()          { return                     jQuery('.TelevisionLayout .Bottom > ul li.active')[0]; }
function tabHeaders()         { return                     jQuery('.TelevisionLayout .Bottom > ul li'); }
function tabHeader(hash)      { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom ul li#tab')[0]; }
function tabBody(hash)        { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody')[0]; }
function tabBodies(hash)      { return                     jQuery('.TelevisionLayout .Bottom > div'); }
function menuArea(hash)       { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion')[0]; }
function menuFirst(hash)      { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion > div')[0]; }
function menuActive(hash)     { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion > div.active')[0]; }
function menuHeader(hash)     { return getElemsFromHash(hash,  1, '.TelevisionLayout .Bottom div .Left .MenuAccordion div#menu')[0]; }
function menuBody(hash)       { return getElemsFromHash(hash,  1, '.TelevisionLayout .Bottom div .Left .MenuAccordion ul#menubody')[0]; }
function sectionFirst(hash)   { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion > ul li')[0]; }
function sectionActive(hash)  { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion > ul li.active')[0]; }
function sectionHeaders(hash) { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Left .MenuAccordion > ul li'); }
function sectionHeader(hash)  { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Left .MenuAccordion ul li#sect')[0]; }
function sectionBody(hash)    { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody')[0]; }
function sectionBodies(hash)  { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Right > div'); }
function sectionCrumb(hash)   { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody', ' .TVBreadcrumbs')[0]; }
function partArea(hash)       { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody', ' .SectionAccordion')[0]; }
function partFirst(hash)      { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody', ' .SectionAccordion > div')[0]; }
function partActive(hash)     { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody', ' .SectionAccordion > div.active')[0]; }
function partHeader(hash)     { return getElemsFromHash(hash,  3, '.TelevisionLayout .Bottom div .Right div .SectionAccordion div#part')[0]; }
function partBody(hash)       { return getElemsFromHash(hash,  3, '.TelevisionLayout .Bottom div .Right div .SectionAccordion div#partbody')[0]; }
function episodeFirst()       { return                     jQuery('.TelevisionLayout .Bottom div .Right div .SectionAccordion .RowContent div.ShowBox')[0]; }
function episodeActives()     { return                     jQuery('.TelevisionLayout .Bottom div .Right div .SectionAccordion .RowContent div.active'); }
// function episodesAll()        { return                     jQuery('.TelevisionLayout .Bottom div .Right div .SectionAccordion .RowContent div.ShowBox'); }
function episodeHeaders(hash) { return getElemsFromHash(hash,null,'.TelevisionLayout .Bottom div .Right div .SectionAccordion .RowContent div.Episode'); }
// function episodesTab(hash)    { return getElemsFromHash(hash,  0, '.TelevisionLayout .Bottom div#tabbody', ' .Right div .SectionAccordion .RowContent div.ShowBox'); }
function episodesSect(hash)   { return getElemsFromHash(hash,  2, '.TelevisionLayout .Bottom div .Right div#sectbody', ' .SectionAccordion .RowContent div.ShowBox'); }
function longEpiDesc()        { return                     jQuery('.TelevisionLayout .Top .TelevisionFeature .FeatureBottom .LongDescription')[0]; }
function shortEpiDesc()       { return                     jQuery('.TelevisionLayout .Top .TelevisionFeature .FeatureBottom .ShortDescription')[0]; }
function moreEpiDescLink()    { return                     jQuery('.TelevisionLayout .Top .TelevisionFeature .FeatureBottom .ShortDescription .MoreLink')[0]; }
function lessEpiDescLink()    { return                     jQuery('.TelevisionLayout .Top .TelevisionFeature .FeatureBottom .LongDescription .LessLink')[0]; }

function bodyHasEpisode()     { return jQuery(episodeBody()).find('a')[0] ? true : false; }
function hasEpisode(hash)     { return getEpisodeFromHash(hash) != null; }
function hasMenu(hash)        { return ! hasEpisode(hash) && getHashPieces(hash, 1) != null; }
function hasSection(hash)     { return ! hasEpisode(hash) && getHashPieces(hash, 2) != null; }
function hasPart(hash)        { return ! hasEpisode(hash) && getHashPieces(hash, 3) != null; }

// internal stuff used by utility stubs above
function stripHashMark(hash) {
  if (! hash) return hash;
  var idx = hash.indexOf('#');
  return idx >= 0 ? hash.substring(idx + 1) : hash;
}
function getElemsFromHash(hash, num, selector_prefix, selector_postfix) {
  var episode = getEpisodeFromHash(hash);
  if (episode) return jQuery(selector_prefix + episode + (selector_postfix ? selector_postfix : ''));
  var pieces = getHashPieces(hash, num);
  return pieces ? jQuery(selector_prefix + '_' + pieces.join('_') + (selector_postfix ? selector_postfix : '')) : [];
}
function getHashPieces(hash, num) {
  if (! hash || num == null) return null;
  var matches = hash.match(/^([^\/]+)?(?:\/([^\/]+))?(?:\/([^\/]+))?(?:\/([^\/]+))?/);
  if (! matches) return null;
  matches = matches.slice(1, num + 2);
  return matches[num] && matches.length == num + 1 ? matches : null;
}
function getEpisodeFromHash(hash) {
  if (! hash) return null;
  var matches = hash.match(/^episodes\/([0-9]+)/);
  return matches ? matches[1] : null;
}

