/**
 * History Management Class
 * 
 * Manages history and forward/backward navigations
 * @class history
 * @namespace VZT.appcore
 */
VZT.appcore.history = new Class({
    Implements: [VZT.Base, Events, Chain],

    _actions: [],
    _iframe: null,
    _previoustag: "",

    /**
    * Process
    * Process' the current url and determins the inital state
    */
    Process: function () {

        if (document.location.hash !== null && document.location.hash !== "") {

            this.addHistory(document.location.hash);
            this._previoustag = document.location.hash;
            this._runEvent(document.location.hash);

        } else {
            this._previoustag = document.location.hash;
            this.addHistory("");
        }

        this._checkbrowser();
    },

    /**
    * goBackwards
    * go back one page
    */
    goBackwards: function () {
        history.go(-1);
        VZT.AppCore.Events.Notify("history_backwards");
    },

    /**
    * goForwards
    * go forward one page
    */
    goForwards: function () {
        history.go(1);
        VZT.AppCore.Events.Notify("history_forwads");
    },

    /**
    * - _runEvent
    * runs the event associated with a given hash tag
    */
    _runEvent: function (tag) {

        if (tag == "#" || tag == "")
            return;

        var tracer = this._findActions(tag);
        if (tracer !== null && tracer.action != null) {
            tracer.action();

        }
    },

    /**
    * - _updateURL
    * Updates the url with the new tag
    */
    _updateUrl: function (tag) {
        window.location.hash = tag;
        if (Browser.Engine.trident) {
            location.replace(window.location);
        } else {
            window.location.hash = tag;
        }
    },

    /**
    * addHistory
    * Adds a historical event
    */
    addHistory: function (tag) {
        if (tag == VZT.AppCore.History._previoustag)
            return;

        VZT.AppCore.History._previoustag = tag;

        if (Browser.Engine.trident)
            this._addHistoryIE(tag);

        this._updateUrl(tag);

    },

    /**
    * - _addHistoryIE
    * Add a historical event via our IE iframe hack
    */
    _addHistoryIE: function (tag) {
        var doc = $('myHistoryFrame').contentDocument;
        if (doc == undefined || doc == null) {
            doc = $('myHistoryFrame').contentWindow.document;
        }
        doc.open();
        doc.write("<div id='tag'>" + tag + "</div>");
        doc.close();
    },


    /**
    * Add action for a tag
    */
    addAction: function (tag, action) {
        var len = this._actions.length;
        this._actions[len] = {
            "tag": tag,
            "action": action
        };
    },

    /**
    * - _findActions
    * find an action for a given tag
    */
    _findActions: function (tag) {
        for (i = 0; i < this._actions.length; i++)
            if (this._actions[i].tag === tag)
                return this._actions[i];
        return null;
    },

    /**
    * - _checkbrowser
    * cheks the browser to see if the history state has changed
    */
    _checkbrowser: function () {
        //if (Browser.Engine.trident &&)
        //VZT.AppCore.History._checkIE();


        if (VZT.AppCore.History._previoustag != document.location.hash) {
      
            VZT.AppCore.Events.Notify("history_change", document.location.hash);

            VZT.AppCore.History._runEvent(document.location.hash);
            VZT.AppCore.History._previoustag = document.location.hash;
        }

        //VZT.AppCore.History._runEvent(document.location.tag);


        setTimeout(VZT.AppCore.History._checkbrowser, 500);

    },

    /**
    * _checkIE
    * Checks IE to see if the browser has changed, via the iframe hidden method
    */
    _checkIE: function () {

        try {
            var doc = $('myHistoryFrame').contentDocument;
            if (doc == undefined || doc == null)
                doc = $('myHistoryFrame').contentWindow.document;

            if (doc.getElementById('tag') == null) {
                if (!VZT.AppCore.hasPageState("init"))
                //history.go(-1);

                    return;
            }


            var new_tag = doc.getElementById('tag').innerHTML;

            if (VZT.AppCore.History._previoustag != new_tag) {
                VZT.AppCore.Events.Notify("history_change", new_tag);

                VZT.AppCore.History._previoustag = new_tag;
                VZT.AppCore.History._runEvent(new_tag);
                VZT.AppCore.History._updateUrl(new_tag);
            }
        } catch (e) {
            // history.go(-1);
        }


    },

    /**
    * setup IE workaround
    */
    _makeIE: function () {
        this._iframe = new Element('iframe', { id: 'myHistoryFrame' });
        this._iframe.setStyle('display', 'none');
        this._iframe.set('src', 'about:blank');

        $(document.body).grab(this._iframe);

        //this._addHistoryIE("#");
    },

    /**
    * generic iframe loaded callback
    */
    _iframeLoaded: function () { },

    initialize: function (o) {

        this.setProperties(o);

        if (Browser.Engine.trident)
            this._makeIE();
    }
});




