/*
 * jQuery history plugin
 *
 * Copyright (c) 2006 Taku Sano (Mikage Sawatari)
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization
 * for msie when no initial hash supplied.
 * API rewrite by Lauris Bukois-Haberkorns
 */

( function ( $ ) {

	function History() {
		this._curHash = '';
		this._callback = function(hash){};
	};

	$.extend(History.prototype, {
	
		init: function(callback) {
			this._callback = callback;
			this._curHash = location.hash;
	
			if($.browser.msie) {
				// To stop the callback firing twice during initilization if no hash present
				if (this._curHash == '') {
					this._curHash = '#';
				}
	
				// add hidden iframe for IE
				$("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>');
				var iframe = $("#jQuery_history")[0].contentWindow.document;
				iframe.open();
				iframe.close();
				iframe.location.hash = this._curHash;
			}
			else if ($.browser.safari) {
				// etablish back/forward stacks
				this._historyBackStack = [];
				this._historyBackStack.length = history.length;
				this._historyForwardStack = [];
				this._isFirst = true;
				this._dontCheck = false;
			}
			this._callback(this._curHash.replace(/^#/, ''));
			setInterval(this._check, 100);
		},
	
		add: function(hash) {
			// This makes the looping function do something
			this._historyBackStack.push(hash);
			
			this._historyForwardStack.length = 0; // clear forwardStack (true click occured)
			this._isFirst = true;
		},
		
		_check: function() {
			if($.browser.msie) {
				// On IE, check for location.hash of iframe
				var ihistory = $("#jQuery_history")[0];
				var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
				var current_hash = iframe.location.hash;
				if(current_hash != $.history._curHash) {
				
					location.hash = current_hash;
					$.history._curHash = current_hash;
					$.history._callback(current_hash.replace(/^#/, ''));
					
				}
			} else if ($.browser.safari) {
				if (!$.history._dontCheck) {
					var historyDelta = history.length - $.history._historyBackStack.length;
					
					if (historyDelta) { // back or forward button has been pushed
						$.history._isFirst = false;
						if (historyDelta < 0) { // back button has been pushed
							// move items to forward stack
							for (var i = 0; i < Math.abs(historyDelta); i++) $.history._historyForwardStack.unshift($.history._historyBackStack.pop());
						} else { // forward button has been pushed
							// move items to back stack
							for (var i = 0; i < historyDelta; i++) $.history._historyBackStack.push($.history._historyForwardStack.shift());
						}
						var cachedHash = $.history._historyBackStack[$.history._historyBackStack.length - 1];
						if (cachedHash != undefined) {
							$.history._curHash = location.hash;
							$.history._callback(cachedHash);
						}
					} else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst) {
						// back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
						// document.URL doesn't change in Safari
						if (location.hash.indexOf('#') >= 0) {
							$.history._callback(location.hash.split('#')[1]);
						} else {
							$.history._callback('');
						}
						$.history._isFirst = true;
					}
				}
			} else {
				// otherwise, check for location.hash
				var current_hash = location.hash;
				if(current_hash != $.history._curHash) {
					$.history._curHash = current_hash;
					$.history._callback(current_hash.replace(/^#/, ''));
				}
			}
		},
	
			isKonqueror: function() {
			return /KHTML|Konqueror/.test(navigator.userAgent);
		},
	
		load: function(hash) {
			var newhash;
	
			if ($.browser.safari) {
				newhash = hash;
			} else {
				newhash = (this.isKonqueror() ? '' : '#') + hash;
				location.hash = newhash;
			}
	
			this._curHash = newhash;
			
			if ($.browser.msie) {
				var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument?
				var iframe = ihistory.contentWindow.document;
				iframe.open();
				iframe.close();
				iframe.location.hash = newhash;
				this._callback(hash);
			}
			else if ($.browser.safari) {
				this._dontCheck = true;
				// Manually keep track of the history values for Safari
				this.add(hash);
				
				// Wait a while before allowing checking so that Safari has time to update the "history" object
				// correctly (otherwise the check loop would detect a false change in hash).
				var fn = function() {$.history._dontCheck = false;};
				window.setTimeout(fn, 200);
				this._callback(hash);
				// N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards.
				//      By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the
				//      URL in the browser and the "history" object are both updated correctly.
				location.hash = newhash;
			}
			else {
			  this._callback(hash);
			}
		}
	});

	$(document).ready(function() {
		$.history = new History(); // singleton instance
	});

} )( jQuery );
