/**
 * Page Slider
 *
 * Allows for multiple divs sliding on and off screen (or just within an element)
 * whilst loading in any relevant content using AJAX. It also keeps track of the
 * user's history, allowing them to bookmark certain pages or email links to a
 * friend without losing the state of the page.
 *
 * To use with AJAX, the response must be in the JSON format with the following
 * components:
 *
 *  'id'        Int     The Page ID
 *  'html'      String  HTML to load into the div.
 *  'nav'       String  HTML to load into the nav div ('#nav')
 *  'hasNext'   Boolean Whether there is another page after this one
 *  'hasPrev'   Boolean Whether there was a page before this one.
 *  'lastPage'  Int     Last Page ID
 *
 *  Each div should have an ID comprised of the 'Identifier', followed by the
 *  seperator, followed by the 'Page' ID. If the divs don't exist, they will be
 *  created, but your initial div (rendered in HTML) should follow this format.
 *
 *  This isn't perfect, but hopefully it should be a nice starting point.
 *  
 * @author Oliver Byford <o.byford@thrusites.com>
 * @requires jQuery (1.3.2 or later)
 * @requires History (jquery.history.js)
 */

jQuery.fn.pageslide = function(arrOptions) {
    
    var strDivContainer = this;
    
    /* Identifier of divs that slide */
    var strDivIdentifier = (arrOptions['identifier']) ? arrOptions['identifier'] : 'psdiv';
    
    /* URL to load from in case a div is called that doesn't exist, to load the
      div content using AJAX */
    var strLoadURL = (arrOptions['url']) ? arrOptions['url'] : null;
    
    var strPage0LoadURL = (arrOptions['page0url']) ? arrOptions['page0url'] : strLoadURL;
    
    /* Initial ID we had when the page loaded. Needed in case the user goes back to before
      their state was stored with a hash tag - where should we go? */
    var intInitialId = (arrOptions['current']) ? arrOptions['current'] : 1;
    
    /* What div we are currently displaying */
    var intCurrentlyShownDivId = intInitialId;
    
    /* What div we are currently loading */
    var intLoadingId = 0;
    
    /* Site ID. Not really important except to ensure that we cache the right site! */
    var intSiteId = (arrOptions['siteid']) ? arrOptions['siteid'] : 0;
    
    /* Number of the last page we can visit, to prevent us trying to load pages off the end of the scale */
    var intLastPage = (arrOptions['lastpage']) ? arrOptions['lastpage'] : 0;
    
    /* Use a dark tag cloud? */
    var blnDarkTagCloud = (arrOptions['darktagcloud'] == 1) ? true : false;
    
    /* Store light colour to revert to */
    var arrLightBGColour = null;
    
    /* STATE */
    /* Are we in the middle of doing a change? */
    var boolChangeInProgress = false;
    
    var strSearchTerm = '';
    
    /* Seperator between identifier and ID */
    var SEPERATOR = '-';
    
    $('.ps-next').click(function() {
        showDiv(intCurrentlyShownDivId + 1, false, true, strSearchTerm);
        return false;
    });
    
    $('.ps-prev').click(function() {
        showDiv(intCurrentlyShownDivId - 1, false, true, strSearchTerm);
        return false;
    });
    
    $('#site-logo').click(function(){
        showDiv(1, false, true, strSearchTerm);
        return false;
    });
    
    $('a.tag').live('click', function() {
        
        showDiv(1, false, true, $(this).html().replace('#',''));
        return false;
    });
    
    $('.tag-reset').live('click', function() {
        
        showDiv(1, false, true, '');
        return false;
    });

    updateHandlers();
    
    if(window.location.hash) {
        arrHashBits = window.location.hash.replace('#','').split(":");
        
        if (arrHashBits.length > 1) {
            var strHashSearchTerm = arrHashBits[0];
            var intHashId = parseInt(arrHashBits[1]);

            if (intHashId != intCurrentlyShownDivId || strHashSearchTerm != strSearchTerm) {
                showDiv(((intHashId >= 0) ? intHashId : intInitialId), false, true, strHashSearchTerm);
            }
        } else {
            
            strSearchTerm = '';
            var intHashId = parseInt(arrHashBits[0]);
            
            if (intHashId != intCurrentlyShownDivId) {
                showDiv(((intHashId >= 0) ? intHashId : intInitialId), false, true, '');
            }
        }
        
    }
    
    $(window).hashchange(function() {
        if (location.hash) {
            arrHashBits = window.location.hash.replace('#','').split(":");
        
            if (arrHashBits.length > 1) {
                var strSearchTerm = arrHashBits[0];
                var intHashId = parseInt(arrHashBits[1]);

                if (intHashId != intCurrentlyShownDivId) {
                    showDiv(((intHashId >= 0) ? intHashId : intInitialId), false, true, strSearchTerm);
                }
            } else {
                
                var intHashId = parseInt(arrHashBits[0]);
                
                if (intHashId != intCurrentlyShownDivId) {
                    showDiv(((intHashId >= 0) ? intHashId : intInitialId), false, true, '');
                }
            }
            
        } else {
            if (intCurrentlyShownDivId != intInitialId) {
                showDiv(intInitialId, true, false, '');
            }
        }    
    });

    function updateHandlers() {
        
        $('.nav .numbers a.search').click(function(){
            showDiv(0, false, true, strSearchTerm);
            return false;
        });

        $('.nav .numbers span a').click(function(){
            showDiv($(this).html(), false, true, strSearchTerm);
            return false;
        });
        
        $('img').error(function() {
            $(this).src = '/img/default.png';
        });
        
        $('.nw').attr('target','_blank');
        $('img.nw').parent().attr('target','_blank');
    }
    
    this.reload = function() {
        showDiv(intCurrentlyShownDivId, false, false, strSearchTerm);
    };
    
    function showDiv(intDivIdLocal, boolIgnoreExistingChange, boolRecordInHistory, strSearchTermLocal) {
        
        var intDivId = parseInt(intDivIdLocal);
        
        if (!intDivId) {
            strSearchTermLocal = false;
        }

        if (intDivId < 0 || intDivId > intLastPage || (boolChangeInProgress && !boolIgnoreExistingChange)) {
            return false;
        }
        
        boolChangeInProgress = true;
 
        if (!($('#' + strDivIdentifier + SEPERATOR + intDivId).length)) {
            var newDiv = $('<div class="'+ strDivIdentifier + '" id="' + strDivIdentifier + SEPERATOR + intDivId + '"></div>');
            
            newDiv.css("margin-left", (intDivId > intCurrentlyShownDivId) ? "965px" : "-965px");
            newDiv.css("opacity", 0);
            
            $(strDivContainer).append(newDiv);
        } else {
            if (intDivId != intCurrentlyShownDivId) {
                $('#' + strDivIdentifier + SEPERATOR + intDivId).css("margin-left", ((intDivId > intCurrentlyShownDivId) ? "965px" : "-965px"));
            }
        }
        
        if (strLoadURL) {
            intLoadingId = intDivId;
            
            $.getJSON(((intDivId == 0) ? strPage0LoadURL : strLoadURL) + intSiteId + '/' + intDivId + (strSearchTermLocal ? '/' + strSearchTermLocal : ''),null,function(data) {
                
                if (data.html != "") {
                    $('#' + strDivIdentifier + SEPERATOR + intDivId).html(data.html);
                } else {
                    boolChangeInProgress = false;
                    showDiv(intDivId - 1, false, false);
                }
 
                $('.nav').html(data.nav);
                
                if (!data.hasPrev) {
                    $('.ps-prev').fadeTo(1000, 0.0);
                
                    setTimeout(function() {
                        $('.ps-prev').hide();
                    },1000);
                } else {
                    if (intDivId > 1) {
                        $('.ps-prev').html('<a href="#prev">previous</a>');
                        $('.ps-prev').removeClass('search');                        
                    } else {
                        $('.ps-prev').html('<a href="/search">search</a>');
                        $('.ps-prev').addClass('search');
                    }
                    $('.ps-prev').show();
                    $('.ps-prev').fadeTo(1000, 1.0);
                }
                
                if (!data.hasNext) {
                    $('.ps-next').fadeTo(1000, 0.0);
                
                    setTimeout(function() {
                        $('.ps-next').hide();
                    },1000);
                } else {
                    if (intDivId == 0) {
                        $('.ps-next').html('<a href="/">return</a>');
                        $('.ps-next').addClass('return');
                    } else {
                        $('.ps-next').html('<a href="#next">next</a>');
                        $('.ps-next').removeClass('return');                        
                    }
                    $('.ps-next').show();
                    $('.ps-next').fadeTo(1000, 1.0);
                }
                
                intLastPage = parseInt(data.lastPage);
                
                if (intDivId != intCurrentlyShownDivId) {
                    animate();
                } else {
                    boolChangeInProgress = false;
                }
                
                intCurrentlyShownDivId = intLoadingId;
                strSearchTerm = strSearchTermLocal;
                
                updateHandlers();
                
                if (boolRecordInHistory) {
                    window.location.hash = ((strSearchTerm) ? strSearchTerm + ':' : '') + intCurrentlyShownDivId;
                }
        
            });
            
        }
        
        return true;
         
    }
    
    function animate() {
        
        
        
        if (blnDarkTagCloud) {
            if (intLoadingId == 0) {
                arrLightBGColour = $('#content').css('background-color');
                $('#content').animate({backgroundColor : '#000000'},800).addClass('dark');
            } else if (intCurrentlyShownDivId == 0) {
                $('#content').animate({backgroundColor : arrLightBGColour},800).removeClass('dark');
            }
        }
        
        if (intLoadingId > intCurrentlyShownDivId) {
            $('#' + strDivIdentifier + SEPERATOR + intCurrentlyShownDivId).animate({
            marginLeft: "-970px",
            opacity: 0.0}, 1000, 'swing');
        } else {
            $('#' + strDivIdentifier + SEPERATOR + intCurrentlyShownDivId).animate({
            marginLeft: "970px",
            opacity: 0.0}, 1000, 'swing');
        }
        
        setTimeout(function() {
            if (strLoadURL) {
                $('.' + strDivIdentifier).each(function(i){
                    if (this.id != strDivIdentifier + SEPERATOR + intCurrentlyShownDivId) {
                        $(this).empty();
                    }
                });
            }
            boolChangeInProgress = false;
        },1000);        
    
        $('#' + strDivIdentifier + SEPERATOR + intLoadingId).animate({
            marginLeft: "0px",
            opacity: 1.0}, 1000, 'swing').show();

    }
    
    return this;
    
};