/*
**	history for ajax/javascript history
**		0.3 history events now setup in queue to ensure all entries reside in the history stack
**		0.2 no more FORM GET submission, straight location.href instead + hold time for iframe load
**		0.1 hidden frame + not bookmarkable + stores data for state change + allows reinstating data on forw/back hit
**	authored by Jim Palmer - released under MIT license
**  collage of ideas from Taku Sano, Mikage Sawatari, david bloom and Klaus Hartl
*/
(function($) {

	$.history = function ( store ) {

		// (initialize) create the hidden iframe if not on the root window.document.body
		if ( $(".__historyFrame").length == 0 ) {

			// set the history cursor to (-1) - this will be populated with current unix timestamp or 0 for the first screen
			$.history.cursor = $.history.intervalId = 0;
			// initialize the stack of history stored entries
			$.history.stack = {};
			// initialize the stack of loading hold flags
			$.history._loading = {};
			// initialize the queue for loading history fragments in sequence
			$.history._queue = [];

			// append to the root window.document.body without the src - uses class for toggleClass debugging - display:none doesn't work
			$("body").append('<iframe class="__historyFrame" src="blank.html" style="border:0px; width:0px; height:0px; visibility:hidden;" />');

			// set the src (safari doesnt load the src if set in the append above)  + set the onLoad event for the iframe
			$('.__historyFrame').load(function () {

					// parse out the current cursor from the location/URL
					var cursor = $(this).contents().attr( $.browser.msie ? 'URL' : 'location' ).toString().split('#')[1];
					if ( cursor ) {
						// remove the cursor from the load queue
						var qPos = $.inArray( cursor, $.history._queue );
						if ( qPos > -1 )
							$.history._queue.splice( qPos, 1 );
						// flag that the iframe is done loading the new fragment id
						$.history._loading[ cursor ] = false;
					}

					// setup interval function to check for changes in "history" via iframe hash and call appropriate callback function to handle it
					$.history.intervalId = $.history.intervalId || window.setInterval(function () {
							// if any cursors in queue - load first cursor (FIFO)
							if ( $.history._queue.length > 0 && !$.history._loading[ $.history._queue[0] ] ) {
								// flag this queued cursor as loading so this interval will not load more than once
								$.history._loading[ $.history._queue[0] ] = true;
								// move the history cursor in the hidden iframe to the newest fragment identifier
								$('.__historyFrame').contents()[0].location.href = 
									$('.__historyFrame').contents().attr( $.browser.msie ? 'URL' : 'location' ).toString().replace(/[\?|#]{1}(.*)$/gi, '') + 
									'?' + $.history._queue[0] + '#' + $.history._queue[0];
							} else if ( $.history._queue.length == 0 ) {
								// fetch current cursor from the iframe document.URL or document.location depending on browser support
								var cursor = $(".__historyFrame").contents().attr( $.browser.msie ? 'URL' : 'location' ).toString().split('#')[1];
								// display debugging information if block id exists
								$('#__historyDebug').html('"' + $.history.cursor + '" vs "' + cursor + '" - ' + (new Date()).toString());
								// if cursors are different (forw/back hit) then reinstate data only when iframe is done loading
								if ( parseFloat($.history.cursor) >= 0 && parseFloat($.history.cursor) != ( parseFloat(cursor) || 0 ) ) {
									// set the history cursor to the current cursor
									$.history.cursor = parseFloat(cursor) || 0;
									// reinstate the current cursor data through the callback
									if ( typeof($.history.callback) == 'function' )
										$.history.callback( $.history.stack[ cursor ], cursor );
								}
							}
						}, 150);

				});

		} else {			// handle new history entries apre-initialization

			// set the current unix timestamp for our history
			$.history.cursor = (new Date()).getTime().toString();
			// add this cursor fragment id into the queue to be loaded by the checking function interval
			$.history._queue.push( $.history.cursor );
			// insert into the stack with current cursor
			$.history.stack[ $.history.cursor ] = store;

		}
			
	}

	// pre-initialize the history functionality - if you include this plugin this will be loaded as a singleton at time of the root window.onLoad
	$(document).ready( function () { $.history(); } );

})(jQuery);

