﻿/**
 * @author pop webdev [tw]
 * @version 0.1
 * @classDescription Handles Pagination of an inline collection. The collection should the form of a <ul> nested inside a master <ul>
 * @return {Object}	Returns a new  object.
 * The class depends on Prototype v1.6.
 */
var Paginator = Class.create({
	initialize: function(elMasterList, options){
		// set options
		this.options = Object.extend({
			initialPageIndex: 0,
			itemsPerPage: 4,
			disableClassName: 'disabled',
			selectedClassName: 'selected'
		}, options || {});
		
		// element check
		if($(elMasterList)){	this.masterList = $(elMasterList);}	else{	return;}
		
		// get dom references and set properties based on original list.
		// get the li count of the nested ul (performance items)
		var firstLI = this.masterList.down('li').addClassName('paginator_page').writeAttribute('id', 'paginator_page_0');
		this.items = firstLI.select('ul li');
		this.itemCount = this.items.size();
		
		// split first li.paginator_page ul into separeate ul's and insert into generated li.paginator_page nodes
		var aPages = this.items.eachSlice(this.options.itemsPerPage);//, function(listItem){});
		this.pageCount = aPages.size();
		
		if(this.pageCount > 1){			
			/* 
				for all pages except the first, create a node like
				<li class="paginator_page" id="paginator_page_i">
					<ul class="[className from original nested ul]">
						list items in aPage[i]	
					</ul>
				</li>
			*/
			var sInnerUlClassName = firstLI.down('ul').className; // get any css classnames from inner UL
			for(var i=1, len = this.pageCount; i < len; ++i){
				var elPageLi = new Element('li', {'class': 'paginator_page', 'id': 'paginator_page_' + i});
				var elInnerUL = new Element('ul', {'class': sInnerUlClassName});
				for(var j=0; j < aPages[i].size(); j++){
					elInnerUL.insert(aPages[i][j]);
				}
				elPageLi.insert(elInnerUL);
				this.masterList.insert(elPageLi);
			}
		}
		else{			
			return;// there's only one page, no pagination needed.
		}

		// add li.paginav controls via dom
		var elTopControls = new Element('li', {'class': 'paginav', id: 'paginav_top'});
		this._addControlList(elTopControls);
		this.masterList.insert({top: elTopControls});
		this.paginavTop = elTopControls;

		var elBottomControls = new Element('li', {'class': 'paginav', id: 'paginav_bottom'});
		this._addControlList(elBottomControls);
		this.masterList.insert({bottom: elBottomControls});
		this.paginavBottom = elBottomControls;
		
		this.viewPage(this.options.initialPageIndex);

	},
	
	// creates a ul filled with pagination links, 
	// attaches an event listener, 
	// and appends the node to supplied element.
	_addControlList: function(elLi){
		var elControlList = new Element('ul');
			var elPrevNavItem = new Element('li', {'class': 'prev'});
				var elPrevNavLink = new Element('a', {'href': '#prev'}).update('<img src="/_img/_ui/arrow_prev.gif" alt="Previous" />');
				elPrevNavItem.insert(elPrevNavLink);
			elControlList.insert(elPrevNavItem);
			
			for(var i=0; i < this.pageCount; i++){
				//<li class="individual"><a href="#paginator_page_0">1</a></li>
				var pageNum = i+1;
				var elPageItem = new Element('li', {'class': 'individual'});
					var elPageLink = new Element('a', {'href': '#paginator_page_' + i}).update(pageNum);
					elPageItem.insert(elPageLink);
				elControlList.insert(elPageItem);
			}
			
			var elNextNavItem = new Element('li', {'class': 'next'});
				var elNextNavLink = new Element('a', {'href': '#next'}).update('<img src="/_img/_ui/arrow_next.gif" alt="Next" />');
				elNextNavItem.insert(elNextNavLink);
			elControlList.insert(elNextNavItem);
		
		// add event handler
		elControlList.observe('click', this.__paginavListClick.bindAsEventListener(this));
		// add new nodes to provide li		
		elLi.insert(elControlList);
	},
	
	// calls updatePaginav on both top and bottom nav
	updatePaginavs: function(){
		this.updatePaginav(this.paginavTop);
		this.updatePaginav(this.paginavBottom);
	},

	// sets disabled and selected classes
	updatePaginav: function(elPaginav){
		// adjust next/previous
		var elPrevNavItem = elPaginav.down('li.prev');
		(this.currentPageIndex > 0) ? elPrevNavItem.removeClassName(this.options.disableClassName) : elPrevNavItem.addClassName(this.options.disableClassName);

		var elNextNavItem = elPaginav.down('li.next');
		(this.currentPageIndex < (this.pageCount-1)) ? elNextNavItem.removeClassName(this.options.disableClassName) : elNextNavItem.addClassName(this.options.disableClassName);

		var elNavItems = elPaginav.select('li.individual');
		
		//var elNavItems = elPaginav.childElements();
		for(var i = 0, len = elNavItems.size(); i < len;i++){
			//var pageIndex = /\d+$/.exec(dest)[0];
			(i == this.currentPageIndex) ? elNavItems[i].addClassName('selected') : elNavItems[i].removeClassName('selected');
		}
		
	},
	
	__paginavListClick: function(e){
		
		var el = e.element();
		var elLi, elLnk;
		if(el.nodeName == 'UL'){return;}
		e.stop();
		
		if(el.nodeName != 'LI'){elLi = $(el).up('li');}
		else{elLi = $(el);}
		elLnk = elLi.down('a');
		
		var dest = elLnk.readAttribute('href').replace('#', '');
		//console.log(dest);
		switch(dest){
			case 'prev':
				this.viewPreviousPage();
				break;
			case 'next':
				this.viewNextPage();
				break;
			default:
				var pageIndex = /\d+$/.exec(dest)[0];	
				this.viewPage(parseInt(pageIndex));
				break;
		}
	},
	
	// methods
	viewPage: function(pageIndex){
		this.currentPageIndex = pageIndex;
		// hide all but given page	
		var pageLIs = this.masterList.select('li.paginator_page');
		for(var i=0, len = pageLIs.size(); i < len ;i++){
			// all that for this.
			(i == pageIndex) ? pageLIs[i].show() : pageLIs[i].hide();
		}
		this.updatePaginavs()
		$('top').scrollTo();
	},
		
	viewNextPage: function(){
		if(this.currentPageIndex < (this.pageCount-1)){
			this.viewPage(this.currentPageIndex + 1);
		}
	},

	viewPreviousPage: function(){
		if (this.currentPageIndex > 0) {
			this.viewPage(this.currentPageIndex - 1);
		}
	}
});
/*
document.observe('dom:loaded', function(){
	myPaginator = new Paginator($('paginator'),{initialPageIndex: 0, itemsPerPage: 4, disableClassName: 'disabled', selectedClassName: 'selected'});
});
*/

// prevent errors from console calls to browsers that don't provide firebug's debugging console.
if (!window.console || !console.firebug) {
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}