var tree;
var root;
var COOKIE_NAME = "tocState";

/*
 * Fallback value in case the URL is a directory: http://foo.com/bar/. 
 * Set this to your default page: index.htm, index.php, ...  
 */
var INDEX_PAGE = "index.html";  


// Set an empty state cookie, if we haven't set one yet. Otherwise getState() could fail.  
if (getState() == null) {
    document.cookie = COOKIE_NAME + "=" + ":1";
}

/*
 * 1. Create the tree.
 * 2. Add onExpand() and onCollapse() functions.
 * 3. Populate the tree with nodes. The details of how we populate the tree are not important.
 *    However, a key assumption is all files in are in a single flat directory, with all links 
 *    relative. The getPageNode() function relies on this convention.
 * 4. Expand the tree according to its previously-recorded state.
 * 5. Highlight the currently-selected page, expanding as necessary.
 * 6. Draw the tree.
 */
function treeInit() {
    tree = new YAHOO.widget.TreeView("toc");
	
    // Record expand and collapse events.
    tree.onExpand = function(node) { storeExpand(node); }
    tree.onCollapse = function(node) { storeCollapse(node); }
    root = tree.getRoot();

    // Example nodes. For a real site, we could generate these nodes somehow. Or not. 
    addNodes();

    preservePreviousExpansion(getState());
    expandAndHighlightPageNode(getPageNode());
    tree.draw();
}

/*
 * Stores an expansion event. The cookie stores the index of each expanded 
 * node, using ":" as a separator. For example, ":2:1:15" means that nodes 1, 2, 
 * and 15 are expanded. There is an initial ":" because of programmer laziness.
 *
 * We don't bother specifying the expiration date of the cookie. It would be
 * interesting to preserve the expansion state for a very long time, but the 
 * default (saving until the user closes the browser) is probably the best way
 * to go. 
 */
function storeExpand(node) {
    var state = getState(); 
    if (state.indexOf(node.index) == -1) {
        document.cookie = COOKIE_NAME + "=" + state + ":" + node.index;    
    }
}

/*
 * Stores a collapse event by removing a previously-recorded expansion event. 
 */
function storeCollapse(node) {
    var state = getState();
    if (state.indexOf(node.index) != -1) {
        re = new RegExp(":" + node.index);
        document.cookie = COOKIE_NAME + "=" + state.replace(re, "", "g");
    }
}

/*
 * Adapted from Peter-Paul Koch's readCookie() method (www.quirksmode.org). 
 * PPK's retrieved any cookie, this version retrieves the value of the specific 
 * cookie that represents the state.
 */ 
function getState() {
    var nameEQ = COOKIE_NAME + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);	
    }
    return null;
}
/*
 * Runs through the state (a colon-separated string of node indices) and
 * expands each node before displaying the tree. From the user's perspective, 
 * when they click on a link, any previous expansions are faithfully 
 * reproduced on the new page.
 * 
 * Note: because the state string always begins with a colon, we must start 
 * at i = 1. 
 */
function preservePreviousExpansion(state) {
    nodes = state.split(/:/);
    var node;
    if (nodes.length > 1) {
        for (var i = 1; i < nodes.length; i++) {
            node = tree.getNodeByIndex(nodes[i]);
            if (node != null) {
                node.expand();
            }
        }
    }
}

/*
 * Retrieves the pageNode, the node in the tree that represents the current
 * page. Since we've adopted the convention that all files in are in a single
 * flat directory, we can just use the filename as a unique identifier,
 * retrieving it from location.href.
 *
 * If you use a different convention for your files, this function breaks.
 * This function does account for:
 *   - requesting a "index.html" file implicitly (http://foo.com/bar/)
 *   - requesting an anchor that is *not* a valid node (foo.html#invalidanchor)
 */
function getPageNode() {

    /*
     * Was the request for an index page? Otherwise, grab the filename
     * and proceed. Note: this trick only works because our server rewrites
     * URLs like http://foo.com/bar to http://foo.com/bar/. We used to check
     * whether fn was blank or null, but that fails in IE.
     */
    if (location.href.charAt(location.href.length - 1) == "/") {
      fn = INDEX_PAGE;
    }
    else {
      splitHref = location.href.split(/\//);
      fn = splitHref[splitHref.length - 1];
    }

    n = tree.getNodeByProperty("href", fn);

    // Was the request for an anchor that is *not* a valid node?
    // We had to try to get a node first, because anchors are valid.
    if (n == null) {
        splitHref = fn.split(/#/);
        fn = splitHref[0];
        n = tree.getNodeByProperty("href", fn);
    }

    // And now let us pray.
    return n;
}

/*
 * Highlights the pageNode with the custom CSS class "expanded", then calls 
 * expandTo() in order to open the tree to the pageNode.  
 */
function expandAndHighlightPageNode(pageNode) {
    pageNode.labelStyle = "expanded";
    expandTo(pageNode);
}

/*
 * Given a node, recursively expand up through the tree. We use this to 
 * expand to the pageNode. This function is important if the user first 
 * enters the site via a deep link. The user hasn't manually expanded the 
 * nodes, and the state is therefore empty, but the tree can still expand 
 * to the selected node on its own.
 */
function expandTo(node) {
    if (node.parent != null) {
        node.parent.expand();
        expandTo(node.parent);
    }
}

/*
 * Finally, let's launch this sucker! 
 */
YAHOO.util.Event.onDOMReady(treeInit);
// JavaScript used to adjust ydoc-generated pages

function byClassName(arr,tag)
{
    var results=new Array();
    var len = arr.length;
    for(var i=0;i<len;i++)
        if (arr[i].className == tag)
            results.push(arr[i]);
    return results;
}

function fixHeader()
{
    var it = byClassName(document.getElementsByTagName('div'),'doctitle')[0];
    //IE requires these to be removed from the DOM
    it.removeChild(it.getElementsByTagName('form')[0]);
    it.removeChild(it.getElementsByTagName('img')[0]);
    it.style.cursor="pointer";
    it.title = "return to developer.yahoo.com";
    it.onMouseover=function() {window.status="http://developer.yahoo.com";}
    it.onMouseout=function() {window.status="";}
    it.onclick = function () { document.location="http://developer.yahoo.com"; };
}

YAHOO.util.Event.onDOMReady(fixHeader);
// JavaScript used to adjust ydoc-generated pages

function byClassName(arr,tag)
{
    var results=new Array();
    var len = arr.length;
    for(var i=0;i<len;i++)
        if (arr[i].className == tag)
            results.push(arr[i]);
    return results;
}

function fixHeader()
{
    var it = byClassName(document.getElementsByTagName('div'),'doctitle')[0];
    //IE requires these to be removed from the DOM
    it.removeChild(it.getElementsByTagName('form')[0]);
    it.removeChild(it.getElementsByTagName('img')[0]);
    it.style.cursor="pointer";
    it.title = "return to developer.yahoo.com";
    it.onMouseover=function() {window.status="http://developer.yahoo.com";}
    it.onMouseout=function() {window.status="";}
    it.onclick = function () { document.location="http://developer.yahoo.com"; };
}

YAHOO.util.Event.onDOMReady(fixHeader);
// JavaScript used to adjust ydoc-generated pages

function byClassName(arr,tag)
{
    var results=new Array();
    var len = arr.length;
    for(var i=0;i<len;i++)
        if (arr[i].className == tag)
            results.push(arr[i]);
    return results;
}

function fixHeader()
{
    var it = byClassName(document.getElementsByTagName('div'),'doctitle')[0];
    //IE requires these to be removed from the DOM
    it.removeChild(it.getElementsByTagName('form')[0]);
    it.removeChild(it.getElementsByTagName('img')[0]);
    it.style.cursor="pointer";
    it.title = "return to developer.yahoo.com";
    it.onMouseover=function() {window.status="http://developer.yahoo.com";}
    it.onMouseout=function() {window.status="";}
    it.onclick = function () { document.location="http://developer.yahoo.com"; };
}

YAHOO.util.Event.onDOMReady(fixHeader);
