/**
 * manage history, deep linking and bookmarking through use of the
 * anchor hash
 *
 * NOTE:
 * - IE will honor the anchor, but it wont create a new entry in the browser history
 * list, so we need to create an iframe and changes its page, which *will* create a history entry
 * - iframe must be fully loaded and set to the same subdomain as the current page,
 * to prevent any access / permission exceptions
 */
billboard.history = new ( function($){
{
    // scopin'
    var me = this;

    /**
     * array of hashes prior to current one
     */
    me.links = [];
    me.intervalId = null;
    me.interval = 200;
    me.defaultHash = "";
    me.hash = "";
    me.newhash  = "";
    me.inited = false;
    me.frameLoaded = false;
    me.managed = true;

    /**
     *
     */
    me.init = function()
    {
        billboard.info("History.init()");

        // set up initial hashes
        var href = window.location.href;
        me.defaultHash = window.location.pathname + window.location.search;
        billboard.info( "-> defaultHash: "+me.defaultHash);
        billboard.info( "-> hash: "+window.location.hash );
        billboard.info( "=====" );
        href = href.replace(/#\.[\w\d-]+\.(linkedin|delicious|twitter|google|digg|facebook|myspace|live)/,"");
        if ( href.indexOf("#") >= 0 && window.location.hash.length > 1 ) {
            billboard.info(" HASH EXISTS: "+window.location.hash );

            me.hash = href.substr( href.indexOf("#") + 1 );
        }
        else {
            billboard.info(" NO HASH EXISTS" );
            me.hash = me.defaultHash;

            // TODO: lame hack - should figure out why IE is adding a trailing #
            if ( me.defaultHash.charAt( me.defaultHash.length - 1 ) == "#" )
                me.defaultHash = me.defaultHash.substr( 0, me.defaultHash.length - 1 );
            
            if ( me.hash.charAt( me.hash.length - 1 ) == "#" )
                me.hash = me.hash.substr( 0, me.hash.length - 1 );

            // Q. does this add a history entry?
            window.location.hash = me.defaultHash;
        }

        billboard.info ( "-> defaultHash: "+me.defaultHash);
        billboard.info ( "-> hash: "+me.hash);
        
        // builds 418 and 419 of Safari have problems and history cannot be managed
        if ($.browser["safari"] == true && 
            ($.browser.version.indexOf("418")!= -1 || $.browser.version.indexOf("419")!= -1) ) {
            me.managed = false;
        }

        // check for a query param that would force history management off
        var loc = self.location.search;
        if ( loc.indexOf("unmanaged=") > -1 ) {
            me.managed = false;
        }

        me.inited = true;

        if ($.browser.msie && parseInt($.browser.version) == 7) {
            $("#historyFrame").contents()[0].location.replace("/html/history-frame.html?/HASH/"+me.hash);
        }


        // start the interval to check on a given interval
        me.intervalId = setInterval( "billboard.history.checkHash()", me.interval );
    };

    /**
     * pulls everything after '#/' from the current location
     */
    me.checkHash = function()
    {
        var loc = window.location.href;
        var newhash;
        if ( loc.indexOf("#") != -1 ) {
            newhash = (loc.substr(loc.indexOf("#")).substr(1));
        }
        newhash = (newhash)?(newhash):(me.defaultHash);
        //billboard.info( "comparing hashes: "+ newhash.toLowerCase() +" : "+ me.hash.toLowerCase() );
        if ( newhash.toLowerCase() != me.hash.toLowerCase() ) {
            me.hash = newhash;
            me.links.push( newhash );
            billboard.broadcaster.dispatchEvent( "hashChanged", me.hash );
        }
    };

    /**
     * this is called by the iframe created for IE browsers, it passes the 
     * hash when it is loaded, so that it can be placed in the browsers location bar
     * (IE wont add a history event for this, hence using the IFrame)
     */
    me.onFrameLoaded = function( hash )
    {
billboard.info("onFrameLoaded = " + hash);
        //billboard.info("onFrameLoaded");
        if ( billboard.history.inited && $.browser["msie"] == true && $.browser.version >= 7  ) {
            //billboard.info(" iframe setting hash: "+hash);
            if (hash.indexOf("/HASH/") > -1){
                hash = hash.replace("/HASH/","#");
            }
            window.location.hash = hash;
        }
        else {
            //billboard.info(" not updating");
        }
    };

    me.clearHash = function()
    {
        me.setHash("");
    };

    me.setHash = function( hash )
    {
        billboard.info("History.setHash("+hash+")");
        if ( hash.charAt(0) != "/" ) { hash = "/" + hash; }
        if ( me.managed ) {
            // strip of hash from existing location
            var loc = window.location.href;
            if ( loc.indexOf("#") != -1 ) {
                loc = loc.substr( 0, loc.indexOf("#") );
            }
            loc = loc + "#" + hash;

            billboard.info(" applying hash: ["+hash+"]");

            // apply new hash
            if ( ($.browser["msie"] == true && $.browser.version >= 7) || $.browser["safari"] == true  ) {
                if (hash.indexOf("#") > -1){
                    hash = hash.replace("#","/HASH/");
                }
                billboard.info("Stripped # and replaced with /HASH/: " + hash);
                if ( $.browser["msie"] == true && $.browser.version >= 7) {
                    billboard.info("setting IE history frame with: "+hash);
                    $("#historyFrame").attr("src", "/html/history-frame.html?"+hash);
                } else {
                    window.location.hash = hash;
                }
            }
            else {
                window.location.hash = hash;
            }
        }
        else {
            me.hash = hash;
            billboard.broadcaster.dispatchEvent( "hashChanged", me.hash );
        }
    };

    me.getHash = function()
    {
        return me.hash;
    };

    me.hasBack = function()
    {
        // there is always one (current one)
        if ( me.links.length > 1 ) {
            return true;
        }
        return false;
    };

    me.back = function()
    {
        if ( me.hasBack() ) {
            // pop hash of list
            me.links.pop();
            var link = me.links.pop();
            me.setHash( link );
        }
    };
}

})(jQuery);

function onFrameLoaded( hash ) {
    if ( $.browser["msie"] == true ) {
        billboard.history.onFrameLoaded(hash);
    }
}

