
// Our namespace, for convenience
YAHOO.namespace("concur08");

/*
 * Implementation of the left-hand side navigation tree menu
 */
YAHOO.concur08.navtree = {

    // the init function hooks up the toggle listener, and collapses the tree menu
    init:function(){
        // hook up the click listener
        YAHOO.util.Event.addListener(this, "click", YAHOO.concur08.navtree.click);
        // make everything collapsed, and disable selection
        var children = YAHOO.util.Dom.getChildren(this);
        for (var i = 0; i < children.length; i++) {
            children[i].className = "collapsed";
            if (children[i].tagName.toLowerCase() == "h3") {
                YAHOO.concur08.util.disableSelection(children[i]);
                // if last, or no submenus, make it unexpandable
                if ((i == children.length - 1) || (children[i+1].tagName.toLowerCase() == "h3"))
                    children[i].className = "unexpandable";
            }
        }
    },
    
    // called when someone clicks inside the navigation div element; this function
    // acts as a dispatcher for the rest
    click:function(e) {
        // figure out who was clicked 
        var t = YAHOO.util.Event.getTarget(e);
        // if it's not h3, get out
        if (t.tagName.toLowerCase() != "h3")
            return;
        // otherwise, get the dl sibling, and if there, toggle its display
        var dl = YAHOO.util.Dom.getNextSibling(t);
        if (dl.tagName.toLowerCase() == "dl") {
            t.className = (t.className == "collapsed") ? "expanded" : "collapsed";
            dl.className = (dl.className == "collapsed") ? "expanded" : "collapsed";
        }
    }
}

/*
 * Implementation of AJAX-based links and other interesting actions; this 
 * is basically, a dispatcher for all interesting clicks, except the clicks
 * that take care of navigation menu (TBD: combine these)
 */
YAHOO.concur08.links = {

    // the init function hooks up the listener
    init:function(){
        // hook up the click listener
        YAHOO.util.Event.addListener(document.getElementById("container"),"click", YAHOO.concur08.links.click);
    },
    
    // called when someone clicks in the document; if the source is the anchor with 
    // no class set this function loads the requested document via AJAX, i.e. 
    // every anchor is by default loaded into the content page via AJAX; external
    // anchors should have class "external"; if the source is INPUT tag with class
    // submit, we call appropriate form handler
    click:function(e) {
        // figure out who was clicked, if not "a" (or for images its parent is not "a")
        // get out right away
        var t = YAHOO.util.Event.getTarget(e);
        switch(t.tagName.toLowerCase()) {
        case "img":
            t = t.parentNode;
            // fall through
        case "a":
            if (t.className == "external")
                break;
            // extract the content string from the URL - content is everything after
            // "content=" or "" if its home
            var content = "";
            var idx = t.href.indexOf("?content=");         
            if (idx >= 0)
                content = content + t.href.substring(idx + 9); // 9 = length("?content=")
               try {
                   // try the history navigation - this will end up calling 
                   // YAHOO.concur08.ajax.stateChangeHanlder because I've registered it
                   // as a history handler
                  YAHOO.util.History.navigate("content", content);
               } catch ( e ) {
                   // this will happen if its not an A-grade browser, just go via
                   // the regular AJAX route
                   YAHOO.concur08.ajax.loadContent(content);
               }
            // prevent default behaviour
            YAHOO.util.Event.preventDefault(e);
            break;
        case "input":
            if (t.className != "submit")
                break;
            var form = YAHOO.util.Dom.getAncestorByTagName(t, "form");
            if (form.id == "contact-form") {
                YAHOO.concur08.contactForm.handle();
                YAHOO.util.Event.preventDefault(e);
            }        
            break;
        }
        return;
    }
}

/*
 * AJAX-based local navigation and history management 
 */
YAHOO.concur08.ajax = {

    // this function is used to load the content and the info section
    // whenever the connection manager has processed the connection request
    // successfully; obj is YAHOO.util.connection
    requestSuccess:function(obj) {
        // get the response
        var response = obj.responseText;
        // extract the pieces that we need
        var content_start = response.indexOf("<div id=\"content\"");
        content_start = response.indexOf(">", content_start) + 1;
        var content_end = response.indexOf("<\/div>", content_start);
        var info_start = response.indexOf("<div id=\"info-section\"");
        info_start = response.indexOf(">", info_start) + 1;
        var info_end = response.indexOf("<\/div>", info_start);
        // and now, plug in in where it belongs
        document.getElementById("content").innerHTML = response.substring(content_start, content_end);
        document.getElementById("info-section").innerHTML = response.substring(info_start, info_end);
        document.body.style.cursor = "default";
    },

    // this function is used to load the content and the info section
    // whenever the connection manager has failed to process the connection 
    // request; obj is YAHOO.util.connection
    requestFailure:function(obj) {
        var error = "<h1>Sorry</h1>";
        error += "<p>An error occured trying to fetch the document. "; 
        if (obj.status == -1) {    
            error += "The connection has timed out.";
        } else if (obj.status == 404) {
            error += "The document was not found.";
        } else {
            error += obj.statusText;
        }
        error += "</p>" +
                  "<p>We would really appreciate it if you could tell us about this problem " +
                  "by sending an email to webmaster at concur08" + 
                  "@" + "cse.yorku.ca</p><p>Thank you very much in advance !</p>";
        // plug in the error text where it belongs
        document.getElementById("content").innerHTML = error;
        document.body.style.cursor = "default";
    },

    // This function is responsible for making an asynch request to 
    // the server and fetching the appropriate content via AJAX. The
    // content is the name of the content, which is everything after
    // the "content=" string, or "" if we need to go home
    loadContent:function(content) {
        // hookup the handlers
        var handlers = {
            success: YAHOO.concur08.ajax.requestSuccess,  // handler for success
            failure: YAHOO.concur08.ajax.requestFailure,  // handler for error
            timeout: 10000     // timeout in ms before declaring failure
        }

        // make up the URL
        var url = "index.php?";
        if (content != "")
            url += "content=" + content + "&";
        url += "xml";
        // define a new asych connector request to load the URL
        var conn = YAHOO.util.Connect.asyncRequest("GET", url, handlers);
        // indicate that we're waiting
        document.body.style.cursor = "wait";
    },
    
    // This is the handler called by the history manager whenever it thinks
    // that the app state has changed. I've registered this function with the
    // history manager, and so it will be called whenever someone calls 
    // YAHOO.util.History.navigate (which for us happends inside YAHOO.concur08.links.click)
    // or when the user walks around using back/forward buttons
    // All we need to do is to load the appropriate content
    stateChangeHanlder:function(state) {
        YAHOO.concur08.ajax.loadContent(state);
    },
    
    initializeNavigationBar:function() {
        // This is the tricky part... The window's onload handler is called when the
          // user comes back to your page using the back button. In this case, the
          // actual section that needs to be loaded corresponds to the last section
          // visited before leaving the page, and not the initial section. This can
          // be retrieved using getCurrentState:
          var currentContent = YAHOO.util.History.getCurrentState("content");
          if ( location.hash.substr(1).length > 0 ) {
               // If the section requested in the URL fragment is different from
               // the section loaded in index.php, we have an unpleasant refresh
               // effect because we do an asynchronous XHR call. Instead of doing
               // a synchronous XHR call, we can fix this by erasing the initial
               // content of bd:
               if (currentContent != queryContent)
                   YAHOO.util.Dom.get("content").innerHTML = "";
               YAHOO.concur08.ajax.loadContent(currentContent);
          }
    }
}

/*
 * AJAX-based contact form implementation
 */
YAHOO.concur08.contactForm = {

    // handles the validation and submission of the contact form;
    handle:function() {
        // extract and validate parameters
        var to = document.getElementById("to").value;
        var from_email = document.getElementById("from-email").value;
        var from_name = document.getElementById("from-name").value;
        var subject = document.getElementById("subject").value;
        var message = document.getElementById("message").value;
        var error = 0;
        var error_text;
        if (from_email == "") {
            error_text = "required";
            error = 1;
        } else if ((from_email.indexOf("@") <= 0) || 
                  (from_email.indexOf("@") >= from_email.lastIndexOf("."))) {
            error_text = "misformatted email";
            error = 1;
        } else {
            error_text = "";
        }
        document.getElementById("from-email-error").innerHTML = error_text;
        if (from_name == "") {
            error_text = "required";
            error = 1;
        } else {
            error_text = "";
        }
        document.getElementById("from-name-error").innerHTML = error_text;        
        if (message == "") {
            error_text = "required";
            error = 1;
        } else {
            error_text = "";
        }
        document.getElementById("message-error").innerHTML = error_text;
        if (error)
            return;
        // form validated, submit
        poststr = "to=" + escape(encodeURI(to)) +
                  "&from_email=" + escape(encodeURI(from_email)) +
                  "&from_name=" + escape(encodeURI(from_name)) +
                  "&subject=" + escape(encodeURI(subject)) +
                  "&message=" + escape(encodeURI(message)) +
                  "&xml";
        // hookup the handlers
        var handlers = {
            success: YAHOO.concur08.ajax.requestSuccess,  // handler for success
            failure: YAHOO.concur08.ajax.requestFailure,  // handler for error
            timeout: 10000     // timeout in ms before declaring failure
        }
        // make up the URL
        var url = document.getElementById("contact-form").getAttribute("action");
        // define a new asych connector request to load the URL
        url += "&xml";
        var conn = YAHOO.util.Connect.asyncRequest("POST", url, handlers, poststr);
        // indicate that we're waiting
                document.getElementById("content").innerHTML = "<h1>Sending ...</h1>";
        document.body.style.cursor = "wait";
    }
}
 
/*
 * Various extremely useful utility functions
 */
YAHOO.concur08.util = {

    // Disables text selection on the specified element
    disableSelection:function (e) {
         e.onselectstart = function() {
            return false;
        };
        e.unselectable = "on";
        e.style.MozUserSelect = "none";
        // uncomment this to make sure that the cursor doesn't change over text
        // e.style.cursor = "default";
    }
}

/* Hook up all the listeners ...
 */

// as soon as the element with ID "navigation-left" is available, initialize 
// the navigation tree
YAHOO.util.Event.onAvailable("navigation-left", YAHOO.concur08.navtree.init);

// as soon as the document's DOM is ready, initialize the link handler
YAHOO.util.Event.on(window, "load", YAHOO.concur08.links.init);


// decide which content do we start from, the options are:
// 1. URL fragment identifier (it will be there if the user previously
// bookmarked the application in a specific state)
// 2. "content" URL parameter (it will be there if the user accessed
// the site from a search engine result, or did not have scripting
// enabled when the application was bookmarked in a specific state)
// 3. or "" (home page, this is the default)
var bookmarkedContent = YAHOO.util.History.getBookmarkedState("content");
var queryContent = YAHOO.util.History.getQueryStringParameter("content");
var initContent = bookmarkedContent || queryContent || "";

// register our module with the history manager; note that module registration 
// MUST take place before calling YAHOO.util.History.initialize.
YAHOO.util.History.register("content", initContent, YAHOO.concur08.ajax.stateChangeHanlder);
YAHOO.util.History.onLoadEvent.subscribe(YAHOO.concur08.ajax.initializeNavigationBar);
// The call to YAHOO.util.History.initialize should ALWAYS be from within
// a script block located RIGHT AFTER the opening body tag (this seems to prevent
// an edge case bug on IE - IE seems to sometimes forget the history when
// coming back to a page, and the back - or forward button depending on the
// situation - is disabled...)
try {
    YAHOO.util.History.initialize();
} catch ( e ) {
    // The only exception that gets thrown here is when the browser is not A-grade.
    // Since scripting is enabled, we still try to provide the user with a better
    // experience using AJAX. The only caveat is that the browser history will not work.
    YAHOO.concur08.ajax.initializeNavigationBar();
}

