/*
Title:      jQuery.loadmore
Description:
            
Developer:  Antenna Praxis (http://theantenna.net)
Date:       January 2010 (From an earlier concept)
Version:    0.0.1

Usage:      
            
Notes:      
            
To Do:      
            
License:    Dual licensed under the MIT and GPL licenses:
            http://www.opensource.org/licenses/mit-license.php,
            http://www.gnu.org/licenses/gpl.html
*/

(function($) {
	
	$.loadmore = function(){}
	
	// defaults
	$.loadmore.defaults = {
		ajaxConfig: {}, // extra params for $.ajax
		getURL: function(data){ return false }, // find the next page url inside of data & return it
		preload: function(){}, // attach a preloader
		timeout: function(){}, // taking a long time
		nomore: function(){} // no extra page found
	};

	$.fn.loadmore = function( options )
	{

		var opts = $.extend($.loadmore.defaults, options), // defaults
			
			getURL = opts.getURL,
			preload = opts.preload,
			timeout = opts.timeout,
			callback = opts.callback,
			nomore = opts.nomore,
			
			isLoading = false,
			to, // timeout
			url = getURL(),
			
			$this = this; // instance
		
		var initialize = function()
		{
			// remove any previous - TODO : make func specific to this instance
			$(window).unbind('scroll.loadmore');
			
			$(window).bind('scroll.loadmore',function(e)
			{
				if(!isLoading && !$this.loadmore.disabled )
				{
					if( isAtBottom() )
					{
						if(url)
						{
						//	log('getting', url);
						
							isLoading = true;
							
							preload();
							
							// slow loading msg after 10 secs
							to = setTimeout(timeout, 10000);
							
							$.ajax($.extend({
								url: url,
								//dataType:'html',
								//data:{},
								type:'GET',
								success: function(data)
								{	
									clearTimeout(to);
									isLoading = false;
									
									url = getURL( data );
									//log('next url', url);
									
									//log('ajax.success',data);
									$this.trigger('callback', [data] );
									
									if(!url)
									{
										$(window).unbind('scroll.loadmore');
										nomore();
									}
									
									//else $(window).trigger('scroll.loadmore');
								},
								error: function (XMLHttpRequest, textStatus, errorThrown) {
									log('loadmore error',arguments);
									isLoading = false; // try again
								},
								xhr: function()
								{
									var xhr = jQuery.ajaxSettings.xhr(),
										that = this;
									
									xhr.onprogress = function()
									{
										// hacky way of getting XHR to accept flushed responses
										if(this.readyState>=2 && this.responseText.slice(-1)==="}")
										{
											try{
												var json = jQuery.parseJSON( this.responseText );
												that.success(json);
												this.abort(); // abort early
											}
											catch(e){
												// .. wasn't well formed ie finished yet
											}
										}
									}
									
									return xhr;
								}
							}, opts.ajaxConfig));
							
						}
						
					}
						
				}
				
			
			});
			
			// check first time
			bump();
			
			return $this;
		};
		
		var isAtBottom = function()
		{
			// doc/win height miscalculates in IE
			return !$.browser.msie?
			 	$(window).scrollTop() == $(document).height() - $(window).height()
				: Math.abs( $(window).scrollTop() - ( $(document).height() - $(window).height() ) ) <10;
		}
		
		// PUBLIC ________________________
		
		$this.loadmore.disabled = false;
		$this.loadmore.isLoading = function(){
			return isLoading;
		}
		
		var bump = $this.loadmore.bump = function(){
			//log('bump!');
			$(window).trigger('scroll.loadmore');
		}
		
		return initialize();
	};
	
})(jQuery);
