/*
 * Load schedule content into the main area of the screen when the user clicks on
 * on the schedule bar on the left side.
 *
 * The content is loaded via ajax (without loading an entirely new page). The content
 * is dynamically inserted into the page.  Once a new content section is loaded, the 
 * jquery history plugin adds a new item to the browser history by adjusting the 
 * url fragment identifier in the url (the stuff after the #).  This enables user 
 * bookmarking, makes the back button work correctly, doesn't reload the outer
 * content (menus, etc.), and works entirely via client scripting (the server need only
 * serve static pages).
 *
 * A few ids and classes are expected to be in the html file:
 *
 *    id="schedule"       schedule content goes inside this element
 *
 *    id="scheduleMenu"   the schedule bar menu.  should contains a list (<ul>), 
 *                        and list elements elements (<li>) containing links (<a>)
 *                        that point to the content to be loaded
 *
 *      class="default"   the default content for the schedule.  place within
 *                        the schedule menu on a link (<a>)
 *
 *   class='selected'     this is added to the currently selected menu item
 *                        (so that we can change the background color of the current item
 *                         via .css styling)
 *
 *   class='menuClick'    anchors (<a>) with menuClick and with a fake #
 *   #faq.html            in the section content or schedule menu are hijacked 
 *                        into clicks on the schedule menu
 *                        (so that the menu selection highlight will change too)
 *
 *   #faq.html&fragment   section content can use links to fragments in this form
 *                        (but not the normal #fragment form which)
 */
$(document).ready(function() {  // call this stuff after document is fully loaded
  var $schedule = $("#schedule");  // container that shows the schedule contents
  var $selected; // currently selected menu item
  var menuTargets = {}; // map of href -> <a> elements of the menu items (e.g. #faq.html -> <a href="#faq.html">)
  var defaultContent = $("#scheduleMenu a.default").attr("href"); // load this section by default

  /* Setup for sponge website environment
   */
  var init = function() {
    var $menuLinks = $("#scheduleMenu li a").not(".menuClick");
    var section;

        // setup side menu
    $menuLinks.click(menuClicked);    // capture click events on menu item links
    $menuLinks.each(function() {
      menuTargets[$(this).attr("href")] = this; // cache a map of href -> link
    });
    attachMenuClick($("#scheduleMenu"));    // allow "menuClick" style hrefs in the menu itself

      // we use the tarodenberg's history plugin to manage history via url #fragments 
    $(window).history(locationChanged);     // navigation changes
    $(window).historyadd(locationChanged);  // back button changes

        // load the initial section content
    section = sectionFragment($.history.getCurrent());
    if (menuTargets[section]) {
      highlightMenuItem($(menuTargets[section]));
    }
    locationChanged(null, $.history.getCurrent());
  }

  /*
   * called when the location changes:  e.g. page is loaded, a menu item is clicked, the back 
   * button is pressed, etc.
   *
   * we try and load the right section contents. 
   */
  var locationChanged = function(e, hash, prevHash) {
    var loadDefault = false, section;  

    if (hash) {
      // section content link is after the # and before the (optional) &
      section = sectionFragment(hash);
      if (menuTargets.hasOwnProperty(section)) {
        $schedule.load(section, loaded);  // hash section is for a valid menu target
      } else if ($schedule.children().length === 0) {
        loadDefault = true; // unrecognized hash
      }
    } else {
      loadDefault = true; // no hash 
    }
    if (loadDefault) {
      $schedule.load(defaultContent, loaded);  
    }
  }

  /* get the section part of the hash fragment.
   * e.g. from faq.html&barbar, return faq.html
   */
  var sectionFragment = function(hash) {
      return hash && hash.replace(/(^[^&]+)&.*/,function(whole, match) {return match});
  }

  /* clicks on menu items will instead trigger the history plugin */
  var menuClicked = function() {
    var $this = $(this);

    // get the partial href from the <a> link in the menu item
    // add the href to the history, 
    // (which will also trigger the locationChanged function and load the new section)
    $.history.add($this.attr("href")); 

    highlightMenuItem($this);

    return false;  // we replace the normal browser click behavior
  }

  /* adjust menu highlighting */
  var highlightMenuItem = function($link) {
    $selected && $selected.removeClass("selected");
    $selected = $link.parent().addClass("selected");  // highlight the containing <li> element
  }


  /* when the new section content is loaded, scan for <a> links of class="menuclick" in 
   * the loaded content, and override them so that instead of simply loading the content, 
   * a lick on the link will instead synthesize a click on the menu (which loads the content
   * AND changes the menu highlight)
   *
   * So you can include a link in the section content that causes a change in the menu.  e.g.
   *    <a href="#faq.html" class="menuClick">What level should we take?</a>
   * Clicking on the link will not only navigate to the new section, it will also update the menu
   * to highlight the new section
   */
  var loaded = function (responseText, textStatus, XMLHttpRequest) {
    if (textStatus === "success") {
      attachMenuClick($schedule);
    }
  }

  /* find links of the form <a href="#faq.html" class="menuClick">, and
   * convert them into a function that simulates a click on the menu item
   * that references faq.html
   */
  var attachMenuClick = function($container) {
    $container.find("a.menuClick").each(function() {
      var href, $link = $(this); 

      // hijack the click if the link has a similar href to a menu item 
      href = $link.attr("href").replace(/^[^#]*#/,'');
      if (menuTargets.hasOwnProperty(href)) {   
        $link.click(function() {
          return menuClicked.apply(menuTargets[href]);
        });
      }
    });
  }

  init();
});

