/*
 * 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 Bukšis-Haberkorns
 */

(function($) {

function History()
{
	this._curHash = '';
	this._running = false;
	this._callback = function(hash, callback){};
};

$.extend(History.prototype, {

	init: function(callback) {
		this._callback = callback;
		this._curHash = location.hash;
						
		if (this._curHash == '' && location.hash != "") {
			this._curHash = location.hash;
		} 
		
		if($.browser.msie) {
			// To stop the callback firing twice during initilization if no hash present
			if (this._curHash == '') {
				this._curHash = '#home_page';
			}

			// 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.replace("?","%1;").replace("&","%2;").replace("=","%3;");
		}
		else if ($.browser.safari) {
			// etablish back/forward stacks
			this._historyBackStack = [];
			this._historyBackStack.length = history.length;
			this._historyForwardStack = [];
			this._isFirst = true;
			this._dontCheck = false;
		}
		/* TODO: REMOVE COMMENT IF YOU WANT THE ANIMATION TO RUN WHEN REFRESH */
		//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;
	},
	
	running: function() {
		if (this._running)
			this._running = false;
		else
			this._running = 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.replace("%1;","?").replace("%2;","&").replace("%3;","=");
			if(current_hash != $.history._curHash && !$.history._running) {
				$.history.running();
			
				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._running) {
						$.history.running();
						$.history._curHash = location.hash;
						$.history._callback(cachedHash);
					}
				} else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst && !$.history._running) {
					// back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
					// document.URL doesn't change in Safari
					$.history.running();
					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._running) {
				$.history.running();
				$.history._curHash = current_hash;
				$.history._callback(current_hash.replace(/^#/, ''));

			}
		}
	},

        isKonqueror: function() {
		return /KHTML|Konqueror/.test(navigator.userAgent);
	},

	load: function(hash) {
		
		/* EXCLUDE IF PAGE ALREADY DISPLAYED */
		if (document.location.hash.replace(/^#/, '') != hash) {
			$.history.running();
			
			
			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();
				/* SPECIAL CHAR FOR IE6 !!I HATE THAT BROWSER!!!!!! */
				iframe.location.hash = newhash.replace("?","%1;").replace("&","%2;").replace("=","%3;");
				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);
