/**
 * jQuery hash change event
 *
 * Copyright (c) 2009 Sergey Berezhnoy <veged mail ru>
 */
(function($)
{
    var $document = $(document),
        iframe,
        hash = window.location.hash,
        needHistoryAdd = /MSIE/.test(navigator.userAgent),
        afterHistoryRead = false,
        afterHistoryAdd = false;

    function check()
	{
        if (hash != (hash = document.location.hash))
		{
            if (!afterHistoryRead && needHistoryAdd) historyAdd(hash);
            afterHistoryRead = false;
            $document.trigger('hashChange', [hash]);
            //console.log('hashChange: ' + hash);
        }
        setTimeout(check, 42);
    }

    function historyAdd(hash)
	{
        if (!iframe) iframe = $('<iframe style="display:none" src="javascript:false;"></iframe>').appendTo('body')[0];
        var d = iframe.contentDocument || (iframe.contentWindow ? iframe.contentWindow.document : iframe.document);
        d.open();
        d.write('<html><head><title>' + document.title + '</title></head><body>');
        d.write($('<div/>').append($('<div id="hashdiv"></div>').text(hash)).html());
        d.write(
            '<script>' +
                'window._hash = document.getElementById("hashdiv").innerText;' +
                'window.onload = parent._historyRead;' +
            '</script>'
        );
        afterHistoryAdd = true;
        d.close();
        //console.log('historyAdd: ' + hash);
    }

    if ('onpropertychange' in document && 'attachEvent' in document)
	{
        document.attachEvent('onpropertychange', function()
		{
            if (event.propertyName == 'location')
			{
                check();
                //console.log('onpropertychange: ' + document.location.hash);
            }
        });
    }

    if (needHistoryAdd)
	{
        window._historyRead = function()
		{
            //console.log('try historyRead: ' + this._hash);
            if (!afterHistoryAdd)
			{
                var newHash = this._hash;
                //console.log('newHash: ' + newHash + ', currentHash: ' + document.location.hash);
                if (document.location.hash != newHash)
				{
                    afterHistoryRead = true;
                    document.location.hash = newHash;
                    //console.log('historyRead: ' + newHash);
                }
            }
            afterHistoryAdd = false;
        };
    }

    $(check);

})(jQuery);

