/**
 * The main, sitewide JavaScript used on EBC* sites.
 *
 * We use YUI2 library for handling DOM and Events on the page.
 *
 * YUI2 reference:
 * Home: http://developer.yahoo.com/yui/2/
 * DOM: http://developer.yahoo.com/yui/dom/
 * Event Utility: http://developer.yahoo.com/yui/event/
 */

/**
 * Wrap local variables inside EBC global namespace.
 */
var EBC = {

  /**
   * Classnames for the nav and nav-title state.
   */
  NAV_STATE: {
    ACTIVE: "navi-active",
    INACTIVE: "navi-inactive"
  },

  NAV_TITLE_STATE: {
    ACTIVE: "navi-2-active",
    INACTIVE: "navi-2-inactive"
  },

  /**
   * Classnames for the display state of the content.
   */
  CONTENT_STATE: {
    SHOWN: "shown",
    HIDDEN: "hidden"
  },

  /**
   * String used for nav classname and ID
   */
  NAV: "navi",

  /**
   * Classname associated with nav title.
   */
  NAV_TITLE: "navi-2",

  /**
   * String used for module-content classname
   */
  CONTENT: "module-content",

  /**
   * String used for module-content id
   */
  CONTENTID: "content",

  /**
   * String used for internal anchor classname
   */
  INTERNAL_ANCHOR: "internal-anchor",

  /**
   * List of navs found on the page.
   */
  navs: [],

  /**
   * List of module-contents found on the page.
   */
  contents: [],

  /**
   * List of internal anchors found on the page.
   */
   internal_anchors: []
};

/**
 * Initializes the page.
 * It finds and caches navs and contents on the page. It also attaches onclick
 * handler to each of the navs found.
 *
 */
function init() {
    // cache navs and module-contents
    EBC.navs = YAHOO.util.Dom.getElementsByClassName(EBC.NAV, "div");
    EBC.contents = YAHOO.util.Dom.getElementsByClassName(EBC.CONTENT, "div");
    EBC.internal_anchors = YAHOO.util.Dom.getElementsByClassName(EBC.INTERNAL_ANCHOR, "a");

    // Attach onclick handler to each of the navs
    for (var i=0; i < EBC.navs.length; ++i) {
        YAHOO.util.Event.addListener(EBC.navs[i], "click", moduleNavSwitchHandler);
    }

    // Any additional internal anchors should trigger activateLandingModule()
    for (var i=0; i < EBC.internal_anchors.length; ++i) {
        YAHOO.util.Event.addListener(EBC.internal_anchors[i], "click", activateLandingModule);
    }

    activateLandingModule();

    updateExternalLinkTargets();

    var moduleHeaders = YAHOO.util.Dom.getElementsByClassName("header-1", "div");
    for (var i=0; i < moduleHeaders.length; ++i) {
        EBC.ANIMATIONS.slideInFromRight(moduleHeaders[i]);
    }

    //EBC.ANIMATIONS.fadeIn(document.body);
}

/**
 * If someone bookmarks the URL with a module selected, e.g. /about#servants
 * -or-
 * An internal anchor besides a nav item to a module is clicked
 *
 * Then start the page with that module activated
 */
function activateLandingModule(e) {
    var hash = location.hash;

    if (e) {
        var target = getEventTarget(e);
        if (target.href.indexOf(location.pathname) > -1) {
            // anchor is on the same page
            hash = target.href.substring(target.href.indexOf("#"));
        } else {
            // anchor is to a different page
            hash = "";
        }
    }

    if ( hash != "" ) {
        var landingModule = hash.replace("#", "");
        var oLandingNav = document.getElementById(landingModule + "-" + EBC.NAV);
        handleModuleNavSelected(oLandingNav);
    }
}

/**
 * Get an event's target
 * Has special handling for IE and Safari
 * Fix from http://www.quirksmode.org/js/events_properties.html
 * "Which HTML element is the target of the event?"
 */
function getEventTarget(e) {
    var target;
    if (!e) var e = window.event;
    if (e.target) target = e.target;
    else if (e.srcElement) target = e.srcElement;
    if (target.nodeType == 3) // defeat Safari bug
        target = target.parentNode;
    return target;
}

/**
 * Click handler for the LHS navs on the page.
 *
 * @param e The event fired.
 */
function moduleNavSwitchHandler(e) {
    var eventTarget = getEventTarget(e);
    var oSelectedNav = YAHOO.util.Dom.getAncestorByClassName(eventTarget, EBC.NAV);
    handleModuleNavSelected(oSelectedNav);
}

/**
 *
 * When a nav is selected, it sets the state to active while setting others to inactive.
 * It also shows the associated content while hiding others.
 *
 */
function handleModuleNavSelected(oSelectedNav) {
    var clickedNavId = YAHOO.util.Dom.getAttribute(oSelectedNav, "id");
    var targetContentId = clickedNavId.replace(EBC.NAV, EBC.CONTENTID);

    // Loop through the nav divs and toggle active/inactive
    for (var i=0; i < EBC.navs.length; ++i) {
        var oNav = EBC.navs[i];

        if (oNav == oSelectedNav) {
            activateNav(oNav);
        } else {
            deactivateNav(oNav);
        }
    }

    // Loop through content divs and toggle active/inactive
    for (var i=0; i < EBC.contents.length; ++i) {
        var oContent = EBC.contents[i];
        var contentId = YAHOO.util.Dom.getAttribute(oContent, "id");

        if (contentId == targetContentId) {
            activateContent(oContent);
        } else {
            deactivateContent(oContent);
        }
    }

    return false;
}

/**
 * Activate a side-nav
 */
function activateNav(oNav) {
    YAHOO.util.Dom.removeClass(oNav, EBC.NAV_STATE.INACTIVE);
    YAHOO.util.Dom.addClass(oNav, EBC.NAV_STATE.ACTIVE);

    var oNavTitle = YAHOO.util.Dom.getElementsByClassName(EBC.NAV_TITLE, "div", oNav);
    YAHOO.util.Dom.removeClass(oNavTitle, EBC.NAV_TITLE_STATE.INACTIVE);
    YAHOO.util.Dom.addClass(oNavTitle, EBC.NAV_TITLE_STATE.ACTIVE);
}

/**
 * Dectivate a side-nav
 */
function deactivateNav(oNav) {
    YAHOO.util.Dom.removeClass(oNav, EBC.NAV_STATE.ACTIVE);
    YAHOO.util.Dom.addClass(oNav, EBC.NAV_STATE.INACTIVE);

    var oNavTitle = YAHOO.util.Dom.getElementsByClassName(EBC.NAV_TITLE, "div", oNav);
    YAHOO.util.Dom.removeClass(oNavTitle, EBC.NAV_TITLE_STATE.ACTIVE);
    YAHOO.util.Dom.addClass(oNavTitle, EBC.NAV_TITLE_STATE.INACTIVE);
}

/**
 * Activate a module content, making it visible
 */
function activateContent(oContent) {
    YAHOO.util.Dom.removeClass(oContent, EBC.CONTENT_STATE.HIDDEN);
    YAHOO.util.Dom.addClass(oContent, EBC.CONTENT_STATE.SHOWN);
    EBC.ANIMATIONS.fadeIn(oContent);
}

/**
 * Deactivate a module content, making it visible
 */
function deactivateContent(oContent) {
    YAHOO.util.Dom.removeClass(oContent, EBC.CONTENT_STATE.SHOWN);
    YAHOO.util.Dom.addClass(oContent, EBC.CONTENT_STATE.HIDDEN);
    EBC.ANIMATIONS.fadeOut(oContent);
}

/**
 * Open offsite links in a new window
 */
function updateExternalLinkTargets() {
    var elts = document.getElementsByTagName("a");
    var hostname = location.hostname;
    for (var i=0; i < elts.length; ++i) {
        var elt = elts[i];
        if (elt.href.indexOf(hostname) == -1) {
            elt.target = "_blank";
        }
    }
}

// Initialize the modules
YAHOO.util.Event.onDOMReady(init);

