/*
 * 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._callback = function(hash){};
    };
    
    $.extend(History.prototype, {
	
	init: function(callback) {
	    this._callback = callback;
	    this._curHash = decodeURI(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 = encodeURI(this._curHash);
	    }
	    this._callback(this._curHash.replace(/^#/, ''));
	    setInterval(this._check, 100);
	},
	
	_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 = decodeURI(iframe.location.hash);

		if(current_hash != $.history._curHash) {
		    location.hash = encodeURI(current_hash);
		    $.history._curHash = current_hash;
		    $.history._callback(current_hash.replace(/^#/, ''));
		}

	    } else {
		// otherwise, check for location.hash
		var current_hash = decodeURI(location.hash);
		if(current_hash != $.history._curHash) {
		    $.history._curHash = current_hash;
		    $.history._callback(current_hash.replace(/^#/, ''));
		}
	    }
	},
	
	load: function(hash) {
	    var newhash;
	    
	    this._curHash = '#'+hash;

	    location.hash = encodeURI(this._curHash);
	    
	    if ($.browser.msie) {
		var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument?
		var iframe = ihistory.contentWindow.document;
		iframe.open();
		iframe.close();
		iframe.location.hash = encodeURI(this._curHash);
		this._callback(hash);
	    }
	    else {
		this._callback(hash);
	    }
	}
    });
    

    // define safari history
    function SafariHistory() {
        this._callback         = null;
        this._hash           = 0;
        this._intervalID       = 0;
        this._loading          = {};
        this._queue            = [];
        this._callback_queue   = [];
    }


    SafariHistory.prototype.init = function(callback){
	var self = this;

	self._callback = callback;

        // remove the hash from the load queue
        var hash = document.location.toString().split('#')[1];

        if (hash) {
            var qPos = $.inArray( hash, self._queue );
            if ( qPos > -1 ) self._queue.splice( qPos, 1 );
            self._loading[ hash ] = false; // set loading flag
        }

        // setup interval function to check for changes in "history" via changes to anchor hashes
        self._intervalID = self._intervalID || window.setInterval(function(){
            // if any hashs in queue - load first hash
            if ( self._queue.length > 0 && !self._loading[ self._queue[0] ] ) {
                // get hash, set loading flag
                var hash = self._queue[0];
                self._loading[ hash ] = true;

                // update url
                document.location.href = document.location.toString().split('#')[0] + '#' + encodeURI(hash);
	
		// execute callback
		self._callback(hash);
		self._hash = hash;

		// remove from queue
		delete self._loading[hash];
		self._queue.splice(0,1);

            } else if (self._queue.length == 0) {
                // check if iframe hash is different from history hash
                var hash = document.location.toString().split('#')[1];

		if (hash) hash = decodeURI(hash)
		else hash = '';

		if (hash != self._hash) {
                    self._hash = hash;
		    self._callback(hash);
                }
            }

        }, 150);

    }


    SafariHistory.prototype.load = function(hash) {
	// add hash to url
	this._queue.push(hash);
    }


    // initialize plugin
    $(document).ready(function() {
	// singleton instance
	if ($.browser.safari) $.history = new SafariHistory();
	else $.history = new History(); 
    });
    
})(jQuery);
