/*!
// Infinite Scroll jQuery plugin
// copyright Paul Irish, licensed GPL & MIT
// version 1.5.101116

// home and docs: http://www.infinite-scroll.com
*/
 
;(function($){
    
  $.fn.infinitescroll = function(options,callback){
    
    // console log wrapper.
    function debug(){
      if (opts.debug) { window.console && console.log.call(console,arguments)}
    }
    
    // grab each selector option and see if any fail.
    function areSelectorsValid(opts){
      for (var key in opts){
        if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0){
            debug('Your ' + key + ' found no elements.');
            return false;
        }
        return true;
      }
    }


    // find the number to increment in the path.
    function determinePath(path){

     if ( path.match(/^(.*?)\b2\b(.*?$)/) ){
          path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
          
      // if there is any 2 in the url at all.
      } else if (path.match(/^(.*?)2(.*?$)/)){
        
          // page= is used in django:
          // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
          if ( path.match(/^(.*?page=)2(\/.*|$)/) ){
            path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
            return path;
          }
          
          debug('Trying backup next selector parse technique. Treacherous waters here, matey.');
          path = path.match(/^(.*?)2(.*?$)/).slice(1);
      } else {
          
        // page= is used in drupal too but second page is page=1 not page=2:
        // thx Jerod Fritz, vladikoff
        if (path.match(/^(.*?page=)1(\/.*|$)/)) {
          path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
          return path;
        }

        if ($.isFunction(opts.pathParse)){
          return [path];
        } else {
          debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.');
          props.isInvalidPage = true; //prevent it from running on this page.
        }
      }
      
      return path;
    }
    
    // determine filtering nav for multiple instances
    function filterNav() {
    
     // make sure filterSelector is valid
     if ($(opts.filterSelector).length <= 0) {
     debug('Can\'t find filtering selector.');
     opts.isInvalidPage = true; //prevent it from running on this page.
     } else {
     $(opts.filterSelector).click(function(e) {
     e.preventDefault();
     opts.isFiltered = true;
     return $.event.trigger( "ajaxError", [{status:302}] );
     })
     }
    
    }
    
    function isNearBottom(){
      
      // distance remaining in the scroll
      // computed as: document height - distance already scroll - viewport height - buffer
      var pixelsFromWindowBottomToBottom = 0
                + $(document).height()
                // have to do this bs because safari doesnt report a scrollTop on the html element
                - ($(props.container).scrollTop() || $(props.container.ownerDocument.body).scrollTop())
                - $(window).height();
      
      debug('math:', pixelsFromWindowBottomToBottom, props.pixelsFromNavToBottom);
      
      // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
      return (pixelsFromWindowBottomToBottom - opts.bufferPx < props.pixelsFromNavToBottom);
    }
    
    function showDoneMsg()
    {
      $('#infscr-loading').html('<div class="clr"></div><div class="loading_text">' + opts.donetext + '</div>');
      
      // user provided callback when done
      opts.errorCallback();
    }
    
    function infscrSetup(){
        
        if (opts.isDuringAjax || opts.isInvalidPage || opts.isDone) return;
        
        if ( !isNearBottom(opts,props) ) return;
        
        $(document).trigger('retrieve.infscr.'+opts.infid);
                
                
    } // end of infscrSetup()
          
  
      
    function kickOffAjax(){
        
        // we dont want to fire the ajax multiple times
        opts.isDuringAjax = true;
        
        // show the loading message quickly
        // then hide the previous/next links after we're
        // sure the loading message was visible
        props.loadingMsg.appendTo( opts.loadMsgSelector ).show(opts.loadingMsgRevealSpeed, function(){
$( opts.navSelector ).slideUp();

// increment the URL bit. e.g. /page/3/
opts.currPage++;

debug('heading into ajax',path);

// if we're dealing with a table we can't use DIVs
box = $(opts.contentSelector).is('table') ? $('<tbody/>') : $('<div/>');
frag = document.createDocumentFragment();


if ($.isFunction(opts.pathParse)){
// if we got a custom path parsing function, pass in our path guess and page iteration
desturl = opts.pathParse(path.join('2'), opts.currPage);
} else {
desturl = path.join( opts.currPage );
}

box.load( desturl + ' ' + opts.itemSelector,null,loadCallback);
});
        
    }
    
    function loadCallback(){
        // if we've hit the last page...
        if (opts.isDone)
        {
            showDoneMsg();
            return false;
              
        } else {
          
            var children = box.children();
            
            // if it didn't return anything
            if (children.length == 0 || children.hasClass('error404')){
              // fake an ajaxError so we can quit.
              return $.event.trigger( "ajaxError", [{status:404}] );
            }
            
            // use a documentFragment because it works when content is going into a table or UL
            while (box[0].firstChild){
              frag.appendChild( box[0].firstChild );
            }

            $(opts.contentSelector)[0].appendChild(frag);
            
            // fadeout currently makes the <em>'d text ugly in IE6
            props.loadingMsg.fadeOut( );

            // smooth scroll to ease in the new content
            if (opts.animate){
                var scrollTo = $(window).scrollTop() + $('#infscr-loading').height() + opts.extraScrollPx + 'px';
                $('html,body').animate({scrollTop: scrollTo}, 800,function(){ opts.isDuringAjax = false; });
            }
        
            // previously, we would pass in the new DOM element as context for the callback
            // however we're now using a documentfragment, which doesnt havent parents or children,
            // so the context is the contentContainer guy, and we pass in an array
            // of the elements collected as the first argument.
            callback.call( $(opts.contentSelector)[0], children.get() );
        
            if (!opts.animate) opts.isDuringAjax = false; // once the call is done, we can allow it again.
        }
    }
    
      
    // lets get started.
    $.browser.ie6 = $.browser.msie && $.browser.version < 7;
    
    var opts = $.extend({}, $.infinitescroll.defaults, options),
        props = $.infinitescroll, // shorthand
        box, frag, desturl;
                
    callback = callback || function(){};
    
    if (!areSelectorsValid(opts)){ return false; }
    
    props.container = document.documentElement;
    
    // if using filtering, determine nav
    if (opts.filtering) { filterNav(); }
                          
    // contentSelector we'll use for our .load()
    opts.contentSelector = opts.contentSelector || this;
    
    // loadMsgSelector - if we want to place the load message in a specific selector, defaulted to the contentSelector
    opts.loadMsgSelector = opts.loadMsgSelector || opts.contentSelector;
    
    
    // get the relative URL - everything past the domain name.
    var relurl = /(.*?\/\/).*?(\/.*)/,
        path = $(opts.nextSelector).attr('href');
    
    
    if (!path) { debug('Navigation selector not found'); return; }
    
    // set the path to be a relative URL from root.
    path = determinePath(path);

    // distance from nav links to bottom
    // computed as: height of the document + top offset of container - top offset of nav link
    props.pixelsFromNavToBottom = $(document).height() +
                                     (props.container == document.documentElement ? 0 : $(props.container).offset().top )-
                                     $(opts.navSelector).offset().top;
    
    // define loading msg
    props.loadingMsg = $('<div id="infscr-loading"><div class="clr"></div><div class="loading_text">' + opts.loadingText + '</div></div>');
                                 
     // preload the image
    (new Image()).src = opts.loadingImg;
              

  
    // set up our bindings
    $(document).ajaxError(function(e,xhr,opt){
     if (!opts.isDone && xhr.status == 404) {
// die if we're out of pages.
debug('Page not found. Self-destructing...');
showDoneMsg();
opts.isDone = true;
opts.currPage = 1; // if you need to go back to this instance
$(window).unbind('scroll.infscr', infscrSetup);
$(document).unbind('retrieve.infscr.'+opts.infid,kickOffAjax);
     }
     if (opts.isFiltered && xhr.status == 302) {
     // die if filtered.
debug('Filtered. Going to next instance...');
opts.currPage = 1; // if you need to go back to this instance
$(window).unbind('scroll.infscr', infscrSetup);
$(document).unbind('retrieve.infscr.'+opts.infid,kickOffAjax);
}
    });
        
    // bind scroll handler to element (if its a local scroll) or window
    $(window)
      .bind('scroll.infscr', infscrSetup)
      .trigger('scroll.infscr'); // trigger the event, in case it's a short page
    
    $(document).bind('retrieve.infscr.'+opts.infid,kickOffAjax);
    
    return this;
  
  } // end of $.fn.infinitescroll()
  

  
  // options and read-only properties object
  
  $.infinitescroll = {
        defaults : {
                          debug : false,
                          preload : false,
                          nextSelector : ".pagination .nc a",
                          filtering : false,
                          filterSelector : null,
                          filterClass : 'current',
                          loadingImg : "http://www.infinite-scroll.com/loading.gif",
                          loadingText : "<em>Loading the next set of posts...</em>",
                          donetext : "<em>Congratulations, you've reached the end of the internet.</em>",
                          navSelector : ".pagination",
                          contentSelector : null, // not really a selector. :) it's whatever the method was called on..
                          loadMsgSelector : null,
                          loadingMsgRevealSpeed : 'slow', // controls how fast you want the loading message to come in, ex: 'fast', 'slow', 200 (milliseconds)
                          extraScrollPx : 150,
                          itemSelector : "div.post",
                          animate : false,
                          pathParse : undefined,
                          bufferPx : 350,
                          errorCallback : function(){},
                          infid : 1, //Sam addition
                          currPage : 1,
                          isDuringAjax : false,
isInvalidPage : false,
isFiltered : false,
isDone : false // for when it goes all the way through the archive.
                        },
        loadingImg : undefined,
        loadingMsg : undefined,
        container : undefined,
        currDOMChunk : null, // defined in setup()'s load()
  };
  


})(jQuery);
