/*
**  history for ajax/javascript history
**      0.4 easier to configure cache control iframe POST handler
**      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($) {

    /*
    ** pre-initialize the history functionality - once you include this plugin this will be instantiated as a singleton onLoad
    ** IMPORTANT - replace the 'cache.php' with the appropriate cache handler URL string
    **             this is what the iframe submits its POSTS to and is required for this plugin to work
    */
    $(document).ready( function () { $.history( '/cache.php' ); } );

    // core history plugin functionality - handles singleton instantiation and individual calls
    $.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="' + store + '" 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);

                });

        /* handle calls to store entries in the history after the history plugin has been initialized */
        } else {

            // 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 copy into the stack with current cursor
            $.history.stack[ $.history.cursor ] = $.extend( true, {}, store );
						//alert('setting new entry:'+$.history.cursor+' - ' + store);
        }

    }

})(jQuery);

