var VHistory = {
	currentHash: undefined,
	callback: undefined,
	initialize :function (callback) {
		this.callback = callback;
		this.currentHash = location.hash;
		if (Prototype.Browser.IE) {
			if (this.currentHash == '') {
				this.currentHash = '#';
			}
			new Insertion.Top(document.body, '<iframe id="history_iframe" style="display: none;"></iframe>');
			this.updateIframeHash(this.currentHash);
		} else if (Prototype.Browser.WebKit) {
			this.webKitHistoryBack = [];
			this.webKitHistoryBack.length = history.length;
			this.webKitHistoryFoward = [];
			this.isWebKitFirst = true;
		}
		if (this.callback) {
			this.callback(this.currentHash.replace(/^#/, ''));
		}
		setInterval(this.checkHistory.bind(this), 100);
	},
	updateIframeHash: function (value) {
		var ihistory = $('history_iframe');
		var iframe = ihistory.contentWindow.document;
		iframe.open();
		iframe.close();
		iframe.location.hash = value;
	},
	setHistory: function (hash) {
		var newhash = hash;
		if (!Prototype.Browser.WebKit) {
			newhash = '#' + hash;
			location.hash = newhash;
		}
		this.currentHash = newhash;
		if (Prototype.Browser.IE) {
			this.updateIframeHash(this.currentHash);
		} else if (Prototype.Browser.WebKit) {
			this.webKitDontCheck = true;
			this.webKitHistoryBack.push(hash);
			this.webKitHistoryFoward.length = 0;
			this.isWebKitFirst = true;
			var fn = function() {this.webKitDontCheck = false;};
			window.setTimeout(fn.bind(this), 200);
		}
		if (this.callback) {
			this.callback(this.currentHash.replace(/^#/, ''));
		}
		if (Prototype.Browser.WebKit) {
			location.hash = newhash;
		}
	},
	getHistory: function () {
		this.checkHistory();
		return this.currentHash.replace(/^#/, '');
	},
	checkHistory: function () {
		if (Prototype.Browser.IE) {
			var ihistory = $('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 (Prototype.Browser.WebKit) {
			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(/^#/, ''));
				}
			}
		}
	}
};
