/* --------------------------------------------------------------------------------------
 * history.js
 * version 1.01
 * @20090324
 * Required common.js ver1.40 later
-------------------------------------------------------------------------------------- */

VCOMN.History = function () {
  this.initialize.apply(this, arguments);
}

VCOMN.History.prototype = {
  initialize :function (callback) {
    this.callback = callback;
    this.currentHash = location.hash;
    if (VCOMN.env.isIE) {
      if (this.currentHash == '') {
        this.currentHash = '#';
      }
      var elem = document.createElement('div');
      elem.innerHTML = '<iframe id="history_iframe" style="display: none;"></iframe>';
      document.body.insertBefore(elem.firstChild, document.body.firstChild);
      this._updateIframeHash(this.currentHash);
    } else if (VCOMN.env.isSafari) {
      this.webKitHistoryBack = [];
      this.webKitHistoryBack.length = history.length;
      this.webKitHistoryFoward = [];
      this.isWebKitFirst = true;
    }
    setInterval(VCOMN.bindFunc(this._checkHistory, this), 100);
  },
  setHistory: function (hash, isCallback) {
    var newhash = hash;
    if (!VCOMN.env.isSafari) {
      newhash = '#' + hash;
      location.hash = newhash;
    }
    this.currentHash = newhash;
    if (VCOMN.env.isIE) {
      this._updateIframeHash(this.currentHash);
    } else if (VCOMN.env.isSafari) {
      this.webKitDontCheck = true;
      this.webKitHistoryBack.push(hash);
      this.webKitHistoryFoward.length = 0;
      this.isWebKitFirst = true;
      var fn = function() {this.webKitDontCheck = false;};
      window.setTimeout(VCOMN.bindFunc(fn, this), 200);
    }
    if (this.callback && isCallback) {
      this.callback(this.currentHash.replace(/^#/, ''));
    }
    if (VCOMN.env.isSafari) {
      location.hash = newhash;
    }
  },
  getHistory: function () {
    this._checkHistory();
    return this.currentHash.replace(/^#/, '');
  },
  _updateIframeHash: function (value) {
    var ihistory = document.getElementById('history_iframe');
    var iframe = ihistory.contentWindow.document;
    iframe.open();
    iframe.close();
    iframe.location.hash = value;
  },
  _checkHistory: function () {
    if (VCOMN.env.isIE) {
      if (location.hash != this.currentHash && location.hash != '' && this.currentHash != '#') {
        this.setHistory(location.hash.replace(/^#/, ''), true);
        return;
      }
      var ihistory = document.getElementById('history_iframe');
      if (!ihistory) {
        return;
      }
      var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
      if (this.currentHash != iframe.location.hash) {
        var current_hash = iframe.location.hash;
        location.hash = current_hash;
        this.currentHash = current_hash;
        if (this.callback) {
          this.callback(this.currentHash.replace(/^#/, ''));
        }
      }
    } else if (VCOMN.env.isSafari) {
      if (!this.webKitDontCheck) {
        var historyDelta = history.length - this.webKitHistoryBack.length;
        if (historyDelta) {
          this.isWebKitFirst = false;
          if (historyDelta < 0) {
            for (var i = 0; i < Math.abs(historyDelta); i++) {
              this.webKitHistoryFoward.unshift(this.webKitHistoryBack.pop());
            }
          } else {
            for (var i = 0; i < historyDelta; i++) {
              this.webKitHistoryBack.push(this.webKitHistoryFoward.shift());
            }
          }
          var cachedHash = this.webKitHistoryBack[this.webKitHistoryBack.length - 1];
          if (cachedHash == undefined) {
            cachedHash = location.hash;
            cachedHash = cachedHash.replace(/^#/, '');
            this.webKitHistoryBack[this.webKitHistoryBack.length - 1] = cachedHash;
          }
          this.currentHash = cachedHash;
          if (this.callback) {
            this.callback(cachedHash);
          }
        } else if (this.webKitHistoryBack[this.webKitHistoryBack.length - 1] == undefined && !this.isWebKitFirst) {
          var param = '';
          if (document.URL.indexOf('#') >= 0) {
            param = document.URL.split('#')[1];
          }
          if (this.callback) {
            this.callback(param);
          }
          this.isWebKitFirst = true;
        }
      }
    } else {
      if (this.currentHash != location.hash) {
        this.currentHash = location.hash;
        if (this.callback) {
          this.callback(this.currentHash.replace(/^#/, ''));
        }
      }
    }
  }
};
