// Copyright 2010, Will Wagner.  All Rights Reserved.

var app = {
    init: function(){
        this.init_nav();
    },
    log: function(){
        if("console" in window){
            return console.log.apply(
                console,
                Array.prototype.slice.call(arguments)
            );
        } else {
            this.log = function(){};
        }
    },
    assert: function(){
        var args = Array.prototype.slice.call(arguments)
        var cond = args.shift();
        if(!cond){
            if(args.length == 0){
                args.push("Error on Assert");
            }
            this.log.apply(this, args);
        }
    },

        
    init_nav: function(){
        var nav = document.getElementById('nav');
        if(nav){
            var a = nav.getElementsByTagName('li');
            var len = a.length;
            var self = this;
            this.log("Connecting nav handlers (%d)", len);

            while(len--){
                a[len].addEventListener(
                    'click',
                    function(e){
                        self.handleNavClick(e);
                    }, 
                    false
                );
            }
        }

        var goback = document.getElementById("goback");
        if(goback){
            var self = this;
            goback.addEventListener(
                "click",
                function(e){
                    e.stopPropagation();
                    e.preventDefault();
                    self.goBack();
                },
                false
            );
        }

        if("onhashchange" in window){
            var self = this;
            this.log("browser has hash change");
            window.addEventListener(
                "hashchange",
                function(){
                    self.handleHash();
                },
                false
            );
        } else {
            this.log("browser does not have hash change");
            var self = this;
            window.setInterval(
                function(){
                    self.monitorHash();
                },
                500
            );
        }

        this.handleHash();
    },
    monitorHash: function(){
        var hash = document.location.hash;
        if(hash != this._hash){
            this.handleHash();
        }
    },
    handleHash: function(){
        var hash = document.location.hash;
        this.log("Hash Change: %s, currHash: %s", hash, this._hash);
        if(hash != this._hash){
            this.log("Back Button hash change");
            if(hash){
                var id = hash.substring(1);
                this.log("Switching to nav %s", id);
                var target = document.getElementById(id);
                if(target){
                    this.doNavClick(target);
                } else {
                    this.changeHash(hash);
                }
            } else {
                this.goBack();
            }
        }
    },
    changeHash: function(hash){
        this._hash = hash ? '#' + hash : '';
        document.location.hash = hash;
    },
    goBack: function(){
        var self = this;
        
        this.changeHash("");
        this.hideContent(
            function(){
                self.showNav();
            }
        );
    },
    hideNav: function(callback){
        var nav = document.getElementById('nav');
        var MAX_OFFSET = -512;
        var TIME_DELAY = 50;

        this.assert(nav, "hideNav: No nav found");
        
        var offset = -1;
        var func = function(){
            nav.style.left = offset + "px";
            if(offset > -512){
                offset *= 2;
                window.setTimeout(func, TIME_DELAY);
            } else {
                nav.style.display = "none";
                if(callback){
                    callback();
                }
            }
        };

        nav.style.display = "block";
        func();
    },

    showNav: function(callback){
        var nav = document.getElementById('nav');
        var MAX_OFFSET = 0;
        var TIME_DELAY = 50;
        
        this.assert(nav, "hideNav: No nav found");
        
        var offset = -512;  
        nav.style.display = "block";
        var func = function(){
            nav.style.left = offset + "px";
            if(offset < 0){
                offset /= 2;
                window.setTimeout(func, TIME_DELAY);
            } else {
                nav.style.left = "0px";
                if(callback){
                    callback();
                }
            }
        };

        func();
    },
    hideContent: function(callback){
        var TIME_DELAY = 20;
        var goback = document.getElementById("goback");
        var content = document.getElementById("embed_content");
        this.assert(goback, "hideContent: no goback");
        this.assert(content, "hideContent: no embed_content");

        var ctr = 10;
        var func = function() {
            if(ctr >= 0){
                goback.style.opacity = (ctr / 10);
                content.style.opacity = (ctr / 10);
                ctr--;
                window.setTimeout(func, TIME_DELAY);
            } else {
                goback.style.display = "none";
                content.style.display = "none";
                if(callback){
                    callback();
                }
            }
        };

        func();
    },
    showContent: function(){
        var TIME_DELAY = 50;
        var goback = document.getElementById("goback");
        var content = document.getElementById("embed_content");
        this.assert(goback, "no goback");
        this.assert(content, "no embed_content");
        
        var ctr = 0;
        var func = function() {
            if(ctr <= 10){
                goback.style.opacity = (ctr / 10);
                content.style.opacity = (ctr / 10);
                ctr++;
                window.setTimeout(func, TIME_DELAY);
            } else {
                goback.style.opacity = "1.0";
                content.style.opacity = "1.0";
            }
        };

        goback.style.display = "block";
        content.style.display = "block";
        func();
    },
    loadContent: function(src){
        var content = document.getElementById("embed_content");
        this.assert(content, "no embed_content");

        var req = new XMLHttpRequest();
        var self = this;
        var url = src;
        if(this.DEBUG){
            var d = new Date();
            src = src + "?cache="+d.getTime();
        }
        req.open('GET', src, true);
        req.onreadystatechange = function () {
            if (req.readyState == 4) {
                if(req.status == 200){
                    content.innerHTML = req.responseText;
                } else {
                    self.log("loadContent failed: (%d)", req.status);
                    content.innerHTML = "<p>Error:  The server is on a smoking break.  Please return later.</p>";
                }
            }
        };
        req.send(null);
    },
    handleNavClick: function(e){
        var target = e.target;
        e.preventDefault();
        e.stopPropagation();
        target.blur();
        while(target && target.tagName != "LI"){
            target = target.parentNode;
        }

        if(target){
            this.doNavClick(target);
        } else {
            this.log("handleNavClick: no target found");
        }
    },
    doNavClick: function(target){
        var children = target.childNodes;
        var len = children.length;
        for(var x = 0; x < len; x++){
            var atag = children[x];
            if(atag.tagName == 'A'){
                var href = atag.href;
                var self = this;
                this.log("click: %o", atag);
                if(href.match(/.*\.shtml$/)){
                    this.changeHash(target.id);
                    this.loadContent(href.replace(/\.shtml$/,'.html'));
                    this.hideNav(function(){
                        self.showContent();
                    });
                } else {
                    window.location.href = href;
                }
                break;
            }
        }
        this.assert(x < len, "handleNavClick: no atag found");
    }
};


