/**
 * jquery.limePaginate- Pagination thought deeply
 * 
 * Copyright (c) 2009 Christopher Pietsch
 * http://www.chrispie.com
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Revision: 3 
 */



(function($) {
	
	$.fn.addActiveClass = function(current,target) {
		if(current==target) { return this.addClass('active'); }
		else {return this;}
	}
	
		
	// static constructs
	$.tools = $.tools || {version: {}};
	
	$.tools.version.limePaginate = '0.3';
				
	var current = null;		

	
	// constructor
	function limePaginate(root, conf) {   

		// current instance
		var self = this;  
		if (!current) { current = self; }		
		
		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args)  {
				if (fn && fn.call(this, args.index) === false && args) {
					args.proceed = false;	
				}	
			});	
			
			return self;
		}
		
		// bind all callbacks from configuration
		$.each(conf, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});   
		
		
		var index = 0;
		var id=$(root).attr('id');
		var ajaxData=null;
		var template=null;
		
		function find(query, ctx) {
			return query.indexOf("#") != -1 ? $(query).eq(0) : ctx.siblings(query).eq(0);	
		}
		
		// get handle to navigational elements
		var $pager = $(conf.pager, root);
		var $items = $(conf.items, root);
		var $nextPage = $(conf.nextPage,root);
		var $prevPage = $(conf.prevPage,root);
		/*
		var navi = find(conf.navi, root);
		var prev = find(conf.prev, root);
		var next = find(conf.next, root);
		var prevPage = find(conf.prevPage, root);
		var nextPage = find(conf.nextPage, root);
		*/
		
		// methods
		$.extend(self, {
			getIndex: function() {
				return index;	
			},
			getPageIndex: function() {
				return Math.ceil(index / conf.itemsPerPage);	
			},
			getSize: function() {
				if(conf.ajax){
					return ajaxData.length;
				} else {
					return self.getItems().size();
				}
			},
			getPagerSize: function(){
				return Math.ceil(this.getSize()/conf.itemsPerPage);
			},
			getItems: function() {
				return $items;
			},
			getItemsPerPage: function(page){
				return $items.slice(this.getIndex() * conf.itemsPerPage,(this.getIndex() + 1) * conf.itemsPerPage);
			},
			nextPage: function(fn) {
				return this.setPage(this.getIndex() + 1, fn);
			},
			prevPage: function(fn) {
				return this.setPage(this.getIndex() - 1, fn);
			},
			setPage: function(page, fn) {
				//console.log(page);
				index=page;
				if(conf.ajax){
					this.repaginateAjax(page, fn);
				} else {
					this.repaginateNormal(page, fn);
				}
				//console.log()
				this.buildPager();
				if($.isFunction(conf.afterPaginate)){
					conf.afterPaginate(self);
				}
			},
			getCleanUrl: function(){
				return document.location.toString().split('#')[0];
			},
			buildPager: function(fn){
				var lastPage=0;
				
				//empty the pager
				$pager.find(conf.pagerLinks).empty();
				
				//set up the range of pagerlinks around the active page
				var pageStart = (this.getIndex() - conf.pagerNumDisplay);
				var pageEnd = (this.getIndex() + conf.pagerNumDisplay);				
				if(pageStart<0){pageEnd=pageEnd+(-1*pageStart);}
				if(pageEnd>this.getPagerSize()-1){pageStart=pageStart-(-1*((this.getPagerSize()-1)-pageEnd))}
				
				//build the pager
				for (var page = 0; page < this.getPagerSize(); page++)
				{
					if(page==0 || page == this.getPagerSize()-1 || ((page >= pageStart) && (page <= pageEnd))){
						
						if((page-lastPage)>1){ $(conf.pagerDotText).appendTo($(conf.pagerLinks,$pager)); }
					
						var pagerItem = ($.isFunction(conf.pagerAnchorBuilder))
							? conf.pagerAnchorBuilder(page, id)
							: '<span class="page"><a href="#page-'+(page+1)+'">' + (page + 1) + '</a></span>';
						if (!pagerItem)
							return;
						var $pagerItem = $(pagerItem);
							
						$pagerItem
						.bind('click', {'newPage': page}, function(event) {
							//self.setPage(event.data['newPage'],fn);
							var hash = $('a',this).attr('href').replace(/^.*#/, '');
							$.historyLoad(hash);
							return false;
							
						})
						.appendTo($(conf.pagerLinks,$pager))
						.addActiveClass(page,this.getIndex())

						lastPage=page;
					}
				}
				
				// prev buttons disabled flag
				if (this.getIndex() === 0) {
					$prevPage.addClass(conf.disabledClass);					
				} else {
					$prevPage
					.removeClass(conf.disabledClass)
					.find("a").attr("href","#page-"+(this.getIndex()));

				}

				// next buttons disabled flag
				if (this.getIndex() >= this.getPagerSize()-1) {
					$nextPage.addClass(conf.disabledClass);
				} else {
					$nextPage
					.removeClass(conf.disabledClass)
					.find("a").attr("href","#page-"+(this.getIndex()+2));
				}
				
				//current Page
				if(conf.pagerCurrentPage){
					$(conf.pagerCurrentPage,root).html(this.getIndex()+1);
				
				}
				
				//total Entries
				if(conf.pagerTotalEntries){
					$(conf.pagerTotalEntries,root).html(this.getSize());
				}
				//total Pages
				if(conf.pagerTotalPages){
					$(conf.pagerTotalPages,root).html(this.getPagerSize());
				}
				
			},
			repaginateNormal: function(i, fn) {
 
				/* Fehler abfangen
				var maxPage=this.getPagerSize();
				if(i>=maxPage){	i=maxPage-1; }
				if(i<0){ i=0; } */
				
				// Show or Hide
		
				this.getItems()
				.hide()
				.slice(this.getIndex() * conf.itemsPerPage,(this.getIndex() + 1) * conf.itemsPerPage).show()
								
				return self; 
			},
			repaginateAjax: function(i, fn) {
 				$(conf.itemBox,root).empty();
				
				var test = $(ajaxData).slice(this.getIndex() * conf.itemsPerPage,(this.getIndex() + 1) * conf.itemsPerPage)
								
				test.each(function(i,item){
					$(conf.itemBox,root).append(self.replaceTemplateVariables(template, item, ""));				
			    });
							
				return self; 
			},
			initialiseAjax: function(callback){
				template=$(conf.ajax.template, root).html();
				
				$.getJSON(conf.ajax.url, conf.ajax.params,
					function(data){
						ajaxData=data;
						callback();
			 	});
			},
			_history: function(hash) {
				var page=0;
						
				if(conf.pagerAnchorJump){
					window.scroll(0,0);
				}
				
				if(hash) {
					var argv = hash.split("-");
					switch(argv[0]) {
						case "page":
							self.setPage(hash.split("-")[1]-1);
						break;
						default:
							self.setPage(conf.startPage);							
						break;
					}
				} else {
					self.setPage(conf.startPage);
				} 
							
			},
			replaceTemplateVariables : function(template, jsonBranch, currentPosition) {
				for(var node in jsonBranch) {
					var regex = new RegExp("%" + currentPosition + node + "%", "g");
					template = template.replace(regex, jsonBranch[node]);
					if(typeof jsonBranch[node] == 'object')
					template = self.replaceTemplateVariables(template, jsonBranch[node], currentPosition + node + ".")
				}
				return template;
			}		
	
		});
		
		
		if(conf.ajax){
			self.initialiseAjax(function(){ $.historyInit(self._history) });
		} else {
			if(conf.useHistroy){
				$.historyInit(self._history);
			} else {
				self._history();
			}		
		}
		
		if(self.getSize()>conf.itemsPerPage){
			$pager.removeClass('hidden');
		}
		
		$nextPage.add($prevPage).click(function(){
			var hash = $('a',this).attr('href').replace(/^.*#/, '');
			if(conf.useHistroy){
				$.historyLoad(hash);
			} else {
				self._history(hash);
			}

			return false;
		})
		
		
		
		

	}	
		
	// jQuery plugin implementation
	$.fn.limePaginate = function(conf) { 
			
		// already constructed --> return API
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("limePaginate");
		if (el) { return el; }		
		
 
		var opts = {
			
			// basics
			startPage: 0,
			pagerNumDisplay:2,
			pagerDotText:"<span>...</span>",
			itemsPerPage:4,
			
			lastPage:0,
			pager:'.paginationBox',
			items:'.teaserBox',
			itemBox: '.itemsBox',
			api:false,
			disabledClass: 'disabled',
			nextPage:'.next',
			prevPage:'.prev',
			pagerLinks: '.pages',
			pagerCurrentPage: '.currentPage',
			pagerTotalEntries: '.totalEntries',
			pagerTotalPages:'.totalPages',
			pagerAnchorBuilder:null,
			pagerAnchorJump:true,
			
			afterPaginate:null
			//ajax:{url:'http://delux/LIMECMS/WALL/index.php', params:{ page: 7, modid: 10, modaction: 'productlistAX'}, template:'.template'}
		}; 
	
		
		$.extend(opts, conf);		
		
		this.each(function() {			
			el = new limePaginate($(this), opts);
			$(this).data("limePaginate", el);	
		});
		
		return opts.api ? el: this; 
		
	};
			
	
})(jQuery);
