// Infinite Scroll
(function($) {
    $.fn.infinitescroll = function(options) {
        return $(this).each(function() {
            var el = $(this);
            this.settings = $.extend({
                    url: null,
                    triggerAt: 50,
                    page: 1,
                    getNextPage: function(curPage){ return curPage+1; },
                    pageToString: function(page){ return ''+page; },
                    processData: function(data){ return $(data.html);},
                    insertAfter: 'body',
                    noAutoScroll: false,
                    fadeInSpeed: 50,
                    container: $(document),
					delay: 1000
                }, options);
            var req = null;
            var maxReached = false;
            var loading = false;
            var infiniteScroller = this;
            var infinityRunner = function() {
            	if (this.settings.url !== null) {
            		if(this.settings.force || (!this.settings.noAutoScroll && (this.settings.triggerAt >= (this.settings.container.height() - el.height() - el.scrollTop())))) {
                    	if(loading) return;
                    	loading=true;
                        this.settings.force = false;
                        // if the request is in progress, exit and wait for it to finish
                        if (req && req.readyState < 4 && req.readyState > 0) return;
                        $(this.settings.insertAfter).parent().trigger('infinitescroll.beforesend');
						setTimeout(
							function(){
								var nextPage = this.settings.getNextPage.call(infiniteScroller, this.settings.page);
								var nextPageStr = this.settings.pageToString.call(infiniteScroller, nextPage);
								var nextUrl = this.settings.url.replace('##PAGE##',nextPageStr);
								infiniteScroller.settings.page = nextPage;
								req = $.get(nextUrl, null, function(html) {
									var $content = infiniteScroller.settings.processData.call(infiniteScroller,{ "page":nextPage, "html":html} );
									if ($content.length>0) {
										$content.hide();
										$(infiniteScroller.settings.insertAfter).after($content);
										var lastIndex = $content.length-1;
										$content.each(function(index,contentElem){
											$(contentElem).fadeIn(infiniteScroller.settings.fadeInSpeed,(index<lastIndex ? null :function(){
												if(infiniteScroller.triggerMaxReached!=null && infiniteScroller.triggerMaxReached==true){
													maxReached = true;
													$(infiniteScroller.settings.insertAfter).parent().trigger('infinitescroll.maxreached');
												}else{
													$(infiniteScroller.settings.insertAfter).parent().trigger('infinitescroll.finish');
												}
												loading=false;
											}));
										});
									}else{
										maxReached = true;
										$(infiniteScroller.settings.insertAfter).parent().trigger('infinitescroll.maxreached');
										loading=false;
									} 

								}, 'html');}
							,this.settings.delay);
                    }
                }else{
                	loading=false;
                }
            };
            
            el.bind('infinitescroll.scrollpage', function(e) {
                this.settings.force = true;
                if (!maxReached) {
					infinityRunner();	
                }
            });

            el.scroll(function(e) {
                if (!maxReached) {
					infinityRunner();	
                }
            });

            // Test initial page layout for trigger
            infinityRunner();
        });
    };
})(jQuery);
