/*@FILE INFORMATION
----------------------------------------
Author:		Mark Wise 
File:		Pagination_1.0.2.js 
Created:	6/15/09 12:13 PM
Updated:	3/2/10 5:23 PM

/*@END--------------------------------*/

var Pagination = new Class({
	//CONSTRUCTOR
	initialize: function(mask, length, hash){
		//Required parameter; Paging will not initialize without this element
		this.mask = $(mask);
		//Required parameter; The total number of paging items; Defaults to zero
		this.length = length || 0;
		//Optional parameter; If display is not defined or it is greater than the length, it will
		//be equal to the length
		this.display = (hash.display && hash.display < length)? hash.display : length;
		//Optional parameter; Sets space between paging items
		this.margin = hash.margin || 0;
		//Optional parameter; Defaults to horizontal if not defined; When defining a vertical direction
		//the value must begin with a 'v', so the word can be anything, such as 'Vagina' 
		this.direction = (hash.direction && /^v/i.test(hash.direction))? "v" : "h";
		//Optional parameter; Additional events to add
		this.events = hash.events || null;
		//The width or height depending on the direction value; Value is set when paging items are added
		this.size = 0;
		//The currently selected index; Defaults to zero
		this.selectedIndex = 0;
		//The first index within the mask; Defaults to zero
		this.firstDisplayIndex = 0;
		//The middle index in relation to the mask; Will be zero if display or length is not defined
		this.midPointIndex = Math.floor(this.display / 2);
			
		
		//Don't initialize paging unless 'this.mask' is defined
		if($defined(this.mask)){
			//Create an unordered list for the background
			var ulBackground = new Element('ul').addClass('background').inject(this.mask);
			//Create an unordered list for the foreground
			var ulForeground = new Element('ul').addClass('foreground').inject(this.mask);
			//Use event delegation to add optional events if defined to the foreground ul
			if(this.events) ulForeground.addEvents(this.events);
			
			
			//Add paging elements
			for(var i=0; i<this.length; i++){
				//Add new paging item and remove margins if they are set to the background 'ul'
				var liBackground = new Element('li').inject(ulBackground).setStyle('margin', 0);
				//Add new paging item and remove margins if they are set to the foreground 'ul'
				var liForeground = new Element("li", {text:i+1}).inject(ulForeground).setStyle('margin', 0);
				//Set the first paging item as the selected item
				if(i == 0){
					liBackground.addClass('selected_index');
					liForeground.addClass('selected_index');
					
				}
				//Paging direction is vertical	
				if(this.direction == 'v'){
					//The size will be dynamically set to the paging items offset height, which 
					//includes borders, padding and height values; All paging items should have
					//the same height, so the value of size only needs to be set once on the first
					//iteration
					if(!this.size) this.size = liBackground.getSize().y;
					//Set the paging items top position
					liBackground.setStyle('top', (this.size + this.margin) * i);
					liForeground.setStyle('top', (this.size + this.margin) * i);
				
				//Paging direction is horizontal	
				}else{
					//The size will be dynamically set to the paging items offset width, which 
					//includes borders, padding and width values; All paging items should have
					//the same width, so the value of size only needs to be set once on the first
					//iteration
					if(!this.size) this.size = liBackground.getSize().x;
					//Set the paging items left position
					liBackground.setStyle('left', (this.size + this.margin) * i);
					liForeground.setStyle('left', (this.size + this.margin) * i);
											
				}
						
			}
		
		
			//Set mask size
			//Paging direction is vertical
			if(this.direction == 'v'){
				//Set the mask's height
				this.mask.setStyle('height', this.getMaskOffsetSize());
			
			//Paging direction is horizontal
			}else{
				//Set the mask's width
				this.mask.setStyle('width', this.getMaskOffsetSize());
			
			}
					
		}
						
	},
	//PRIVATE
	getMaskOffsetSize:function(){
		//Get the mask size; This could be the width or height depending on 'this.direction'
		return (this.margin + this.size) * this.display - this.margin;
		
	},
	//PRIVATE
	getItemsOffsetPosition:function(){
		//Is there more paging items than the display;
		if(this.length > this.display){
			if(this.selectedIndex > this.midPointIndex){
				this.firstDisplayIndex = this.selectedIndex - this.midPointIndex;
			
			}else{
				this.firstDisplayIndex = 0;
			
			}
			//Will the selected paging item tween out of range; For example, if the length is '10'
			//and the display is '5' and you click on '10' it would try to shift two places to the left
			//if the direction is horizontal or two places up if the direction is vertical, which would
			//create a gap on the right or bottom;
			if(this.length - this.firstDisplayIndex < this.display){
				this.firstDisplayIndex = this.length - this.display;
				
			}
							
		}
		//Will return zero as a default
		return this.firstDisplayIndex * -(this.size + this.margin);
			
	},
	//PUBLIC
	update:function(index){
		//Is the new selected index and the old selected index equal
		if(index != this.selectedIndex){
			//Get reference to the background and foreground 'ul'elements
			var ulBackground, ulForeground;
			ulBackground = this.mask.getElement('.background');
			ulForeground = this.mask.getElement('.foreground');
			//Remove the selected state from the old selected index
			ulBackground.getElements("li")[this.selectedIndex].removeClass("selected_index");
			ulForeground.getElements("li")[this.selectedIndex].removeClass("selected_index");
			//Set the new selected index
			this.selectedIndex = index;
			//Set the selected state on the new selected index
			ulBackground.getElements("li")[this.selectedIndex].addClass('selected_index');
			ulForeground.getElements("li")[this.selectedIndex].addClass('selected_index');
			//Paging direction is vertical
			if(this.direction == 'v'){
				//Get new top position and tween to it
				ulBackground.tween('top', this.getItemsOffsetPosition());
				ulForeground.tween('top', this.getItemsOffsetPosition());
						
			//Paging direction is horizontal
			}else{
				//Get new left position and tween to it
				ulBackground.tween('left', this.getItemsOffsetPosition());
				ulForeground.tween('left', this.getItemsOffsetPosition());
			
			}
			
		}
				
	}

});
