HistoryManager = new Class({
 
    Implements: Events,
 
    initialize: function(){
        this._currentLocation = this._getHash();
 
        if (Browser.Engine.trident) {
            this.addState = this._addStateIE;
            this._iframe = new Element('iframe', {
                src: "javascript:'<html></html>'",
                styles: {
                    'position': 'absolute',
                    'top': '-1000px'
                }
            }).inject(document.body).contentWindow;
 
            $justForIE = function(hash){
                this._getHash = function(){
                    return hash;
                }
                this._monitorDefault.call(this);
                location.hash = hash;
            }.bind(this);
 
            var waitForLoad = function waitForIframeLoad(){
                if (this._iframe && this._iframe.document && this._iframe.document.body) {
                    if (!this._iframe.document.body.innerHTML) 
                        this.addState(this._currentLocation, true);
                    $clear(waitForLoad);
                }
            }.periodical(50, this);
        }
        else 
            if (Browser.Engine.webkit419) {
                this._form = new Element("form", {
                    method: 'get'
                }).inject(document.body);
                this._historyCounter = history.length;
                this._stateHistory = [];
                this._stateHistory[history.length] = this._getHash();
 
                this.addState = this._addStateSafari;
                this._monitorSafari.periodical(250, this);
            }
            else 
                if (window.opera && !Browser.Engine.presto950) {
                    this.addState = this._addStateDefault;
 
                    $justForOpera = this._monitorDefault.bind(this);
                    new Element('img', {
                        src: "javascript:location.href='javascript:$justForOpera();';",
                        style: "position: absolute; top: -1000px;"
                    }).inject(document.body);
                }
                else {
                    Logger.debug('init default');
                    this.addState = this._addStateDefault;
                    this._monitorDefault.periodical(250, this);
                }
    },
 
    getCurrentLocation: function(){
        return this._currentLocation;
    },
 
    _getHash: function(){
        return location.href.split('#')[1] || '';
    },
 
    _addStateIE: function(hash, override){
        if (this._currentLocation == hash && !override) 
            return;
 
        this._currentLocation = hash;
        this._iframe.document.write('<html><body onload="top.$justForIE(\'', hash.replace("'", "\\'"), '\');">Loaded</body></html>');
        this._iframe.document.close();
    },
 
    _addStateSafari: function(hash){
        if (this._currentLocation == hash) 
            return;
 
        this._form.setProperty('action', '#' + hash).submit()
        this._currentLocation = hash;
        this._stateHistory[history.length] = this._getHash();
        this._historyCounter = history.length;
    },
 
    _monitorSafari: function(){
        if (history.length != this._historyCounter) {
            this._historyCounter = history.length;
            this._currentLocation = this._stateHistory[history.length];
            this.fireEvent('historyChange', [this._currentLocation]);
        }
    },
 
    _addStateDefault: function(hash){
        if (this._currentLocation == hash) 
            return;
        location.hash = '#' + hash;
        this._currentLocation = hash;
    },
 
    _monitorDefault: function(){
        var hash = this._getHash();
 
        if (hash != this._currentLocation) {
            this._currentLocation = hash;
            this.fireEvent('historyChange', [hash]);
        }
    }
});
