/*
 * history 1.0 - Plugin for jQuery
 *
 *
 * IE8 is supporting onhashchange event
 * http://msdn.microsoft.com/en-us/library/cc288209(VS.85).aspx
 *
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Depends:
 *   jquery.js
 *
 *  Copyright (c) 2008 Oleg Slobodskoi (ajaxsoft.de)
 */

;(function($){


$.fn.history = function( option ) {
	var	args = Array.prototype.slice.call(arguments, 1);
	return this.each(function() {
		var instance = $.data(window, 'history') || $.data( window, 'history', new hist()).init();
		
		typeof option == 'string' ? instance[option].apply( this, args ) : instance.bind(this, option);
	});

};

function hist() {
	var self = this,
		IE67 = $.browser.msie && parseInt($.browser.version) < 8 ? true : false,
		IE8 = $.browser.msie && parseInt($.browser.version) >= 8 ? true : false,
		$iframe,
		$listeners,
		interval;
		
	this.init = function() {
		if ( IE67 ) $iframe = $('<iframe style="display: none;" class="x-history-iframe"/>').appendTo(document.body);

		self.value = top.location.hash.replace('#','');

		if ( IE67 ) {
			checkIFrame();
		} else  if ( !IE8 ){
			var hash = top.location.hash;
			interval = setInterval(function() {
				var newHash = top.location.hash;
				if (newHash !== hash) {
					hash = newHash;
					change(hash);
				};
			}, 50);
		};
		return self;
	};

	this.bind = function(elem, callback) {
		$listeners = !$listeners ?  $(elem) : $listeners.add(elem);
		$(elem).bind('hashchange', IE8 ? function(e){
			change(top.location.hash);
			callback.apply(elem, [$.Event(e), self]);
		} : callback );				
	};
    
    this.unbind = function() {
    	delete $listeners[$listeners.index(this)];
        $(this).unbind('hashchange');        
    };
	
    this.add = function( value, params ) {
        self.params = params;
		top.location.hash = value;
		IE67 && updateIFrame(value)
        change(value);
        return false;
	};
	
	this.forward = function() {
		history.go(1);
	};

	this.back = function() {
		history.go(-1);
	};
	

	this.destroy = function() {
		clearInterval(interval);
		$iframe && $iframe.remove();
		$listeners.unbind('hashchange');
		$.removeData(window, 'history');
	};
	

    function checkIFrame() 
    {
        var iHash = iDoc().location.hash,
        	hash = top.location.hash;

        interval = setInterval(function () {
            var newiHash = iDoc().location.hash,
            	newHash = top.location.hash;

            if (newiHash !== iHash) {
                iHash = newiHash;
                change(iHash);
                top.location.hash = iHash;
                hash = iHash;
            } else if (newHash !== hash) {
                hash = newHash;
                updateIFrame(newHash);
            }

        }, 50);

    };    
    
    function change(value) {
        self.value = value.replace('#','');
        !IE8 && $.event.trigger('hashchange', [self]);
    };

    function updateIFrame(value) {
		iDoc().open();
		iDoc().close();
		iDoc().location.hash = value;
    };
    
    function iDoc() {
    	return $iframe[0].contentWindow.document;
    };
    
};


})(jQuery);		
