/*
* multi column pagination
*@author Robert Dixon
*@do not reuse or redistribute
* to use:
	<script language="javascript">
							newColumnPagination("textCol");
							textCol.init("storyText",464,254,1,16);
					</script>
*
*/
function ColumnPagination(name){
	this._name=name;	//name of this object

	this._w=0;			//target width
	this._h=0;			//target height
	
	this._nN=null;		//name of node with text
	this._n=null;		//reference to text node
	
	this._nC;			//the div we create which contains all the text
	
	this._colNum=1;		//number of columns
	this._colMrgn=0;	//width between columns
	
	this._sizer=null;	//sizerdiv
	this._nClass="";	//class of text column
	this._pgH=0;		//page height
	this._pgTtl=0;		//
	this._pgC=0;		//
	this._trgtPos=0;	//this is the x pos of the div, determines which column is viewable
	this.LnH=0;			//line height per character
	this._interval="";
	this.orphans=0;		//how many orhpaned lines to bring over. (if it is 2, then any two orhpaned lined will be brough back to the first)
	this.animate=true;	//animate the page changes
	this.navAlign="right";	//where to align the page nav
	this.navStyle="numbers"; //options are numbers, text
	this.navClass="txtLink";
	this.initCallBack=null;
	this.paginateCallBack=null;
	var self;
	
	
	/*
	*@param string node	name of node with the text to paginate
	*@param number w 	width
	*@param number h	height can be in pixels or number of lines. to use number of lines, add a "c" at the end of the number. Example: "4c" would make the pagination area 4 lines in height.
	*@param number cn 	number of columns
	*@param number cw	width between columns
	**/
		
	//need to add some error checking routines!
	
	this.init=function(node,w,h,cn,cw){
		this._nN=node;
		this._n=document.getElementById(node);
		this._nClass=this._n.className;
		this._w=w-(cw);
		

		this._colNum=cn;
		this._colMrgn=cw;
		this._sizer=this.createTestDiv();
		this._sizer.style.display="block";	//incase we're using someone elses sizer.
		this._totalCols=0;
			
		this.LnH=this._sizer.offsetHeight/2; 					
		
		h=h+'';
		if(h.charAt(h.length-1)=="c") {
			//we want to use character height, not pixel height
			this._h = this.LnH*parseInt(h); 
		} else {
			this._h=parseInt(h);
		}
		
		//lines per column and page height
		var LPC = Math.ceil(this._h/this.LnH);
		this._pgH = LPC*this.LnH;				
		
		//if the div is larger than the given area, then we are going to paginate, otherwise...
		if(this._n.offsetHeight >= this._h) {
			this._n.style.height=this._h+"px";	
			this.flowText();
		} else {
			if(this.initCallBack!=null) this.initCallBack();
		}
		
		this._sizer.style.display="none";										//hide sizer div
		//this._n.parentNode.style.height = this._pgH+"px";				//resize parent to fit page height
		
		this._n.style.overflow="hidden";							//makesure we hide all overflow
		this._n.style.position = "relative";
		this._n.style.width=w+"px";
		//this._n.parentNode.style.position = "relative";
		
	}
	
	/**
	* flow text creates the initial layout of the columns
	*/
	this.flowText=function(){
		
		var text = this._n.innerHTML;
		this._n.innerHTML="";
		var colWidth = (  this._w-( (this._colNum)*this._colMrgn )  )/this._colNum;
		
		//create container div
		this._nC = this.createDiv(this._nN+"columns",this._n,"","",0);
		this._nC.style.left="0px";
		
		//create first div
		var c1 = this.createDiv(this._nN+"_col1",this._nC,text,colWidth,this._colMrgn);
		c1.style.left = this._colMrgn+"px";


		//now that that is all done, let's rest the total columns and height of our div for cropping
		this._totalCols = Math.ceil(c1.offsetHeight/this._pgH);
		this._n.style.height = this._pgH+"px";
			
		if(!this.checkForOrphans(c1)){ //true means we moved orphans over and therefore don't need to paginate	
			var count=1;
			for(var i = 2; i <= this._totalCols; ++i){
				var c = this.createDiv(this._nN+"_col"+i,this._nC,text,colWidth,this._colMrgn);
				c.style.left = ( ( this._colMrgn*(i) )+colWidth*(i-1) )+"px";
				c.style.top  = (-1*(this._pgH*(i-1) ) )+"px";
				count++;
			}
			
			this._pgTtl = Math.ceil(count/this._colNum);
			this.createNav();
		}
		if(this.initCallBack!=null) this.initCallBack();
	}

	this.createDiv=function(id,parent,content,w,margin){
		var d = document.createElement("div");
		d.id=id;
		if(w!="")d.style.width = w+"px";
		d.style.position = "absolute";
		d.style.textAlign="left";
		d.style.display="block";
		d.innerHTML=content;
		parent.appendChild(d);
		return document.getElementById(id);
	}
	
	/**
	* this function is now a hack..needs to be updated to work in all occurances
	*/
	this.checkForOrphans=function(cDiv){
			if(this.orphans > 0){
				//check div height
				if(cDiv.offsetHeight <= this._h+(this.LnH*this.orphans) ){
					
					this._n.style.height = this._h+(this.LnH*this.orphans)+"px";
					return true;
				} 
				return false;
			}
	}
	
	function anim(first){
		if(self.animate==true && first !== true){
			var cleft = parseInt(self._nC.style.left);
		    var nleft = (self._trgtPos > cleft) ? cleft + 40 : cleft - 40;
		    self._nC.style.left = nleft+"px";
		    if(Math.abs(nleft - self._trgtPos) < 30 ) {
		    		self._nC.style.left = self._trgtPos+"px";
		    		clearInterval(self._interval);
		    		self._interval="";
		    }
		} else {
			self._nC.style.left = self._trgtPos+"px";
		    clearInterval(self._interval);
		    self._interval="";
		}
		if (this.paginateCallBack != null) this.paginateCallBack();
	}

	/**
	* shows a page, call by the text nav links
	*@param number num 		the number of the page to view
	*
	*/
	this.showPage=function(num,first){
		if(this._interval != "") clearInterval(this._interval);
		
		
		this._trgtPos = -( (( num-1)*this._w));		//render top position
		//this._nC.style.left = this._trgtPos+"px";
		self = this;
		
		if(first ===true || this.animate==false) { 
			anim(true);
		} else {
  			this._interval = setInterval(anim, 30);
		}
		//change all nav  link number colors
		try{
			for (var i=1; i<= this._pgTtl; ++i){
				document.getElementById(this._nN+"pnavlnk"+i).style.color="#000000";
				document.getElementById(this._nN+"pnavlnk"+i).style.textDecoration="underline";
			}
			//change selected nav link color
			document.getElementById(this._nN+"pnavlnk"+num).style.color="#015AC2";
			document.getElementById(this._nN+"pnavlnk"+num).style.textDecoration="none";
			/*
			document.getElementById(this._nN+"pnavlnkPrev").style.color= (num==1) ? "#015AC2" : "#000000";
			document.getElementById(this._nN+"pnavlnkNext").style.color= (num==this._pgTtl) ? "#015AC2" : "#000000";
			//*/
		} catch(e){}
		
		try{
			var pa = document.getElementById(this._nN+'pnavlnkPrev').style;
			var na = document.getElementById(this._nN+'pnavlnkNext').style;
			
			//pa.textDecoration = (num==1) ? "none" : "none";
			//na.textDecoration= (num==this._pgTtl) ? "none" : "none";
			
			na.display= (num==this._pgTtl) ? "none" : "block";
			pa.display= (num==1) ? "none" : "block";

		} catch(e){}
		this._pgC=num;
		
	}
	
	this.nextPage=function (){
		if(this._pgC < this._pgTtl) this.showPage(this._pgC+1);
	}
	
	this.prevPage=function (){
		if(this._pgC > 1) this.showPage(this._pgC-1);
	}

	/**
	* creates the test div we can get the height for calculating all the stuff we need
	*/
	this.createTestDiv=function(){
		var f = document.getElementById(this._nClass+"__sizer");
		if(!f){
			var d = document.createElement("div");
			d.id=this._nClass+"__sizer";
			d.className=this._nClass;
			d.style.display="block";
			d.style.backgroundColor="#FFFFFF";
			d.innerHTML="W<br>W";
			var p = this._n.parentNode.parentNode;
			p.appendChild(d);
			var f = document.getElementById(this._nClass+"__sizer"); 
		}
		return document.getElementById(this._nClass+"__sizer");
	}
	
		/**
	* creates a div containing the nav links.
	* the div is nodeName+"paginateNav"
	*/
	this.createNav=function(){
		if(this._pgTtl <=1) return;
		
		switch (this.navStyle.toLowerCase()){
			case "arrows":
				var msg='<a id="'+this._nN+'pnavlnkNext" href="" style="padding-left:10px; float: '+this.navAlign+'" class="'+this.navClass+'" onclick="'+this._name+'.nextPage();return false;">&raquo;</a>';
					
				msg +='<span class="'+this.navClass+'" style="float:'+this.navAlign+';"> more </span>';
				
				msg+='<a id="'+this._nN+'pnavlnkPrev" href="" style="padding-'+this.navAlign+':10px; float:'+this.navAlign+';" class="'+this.navClass+'" onclick="'+this._name+'.prevPage();return false;">&laquo;</a>';
			
				break;
			default:
				var msg='<a id="'+this._nN+'pnavlnkPrev" href="" style="padding-'+this.navAlign+':10px; float:" class="'+this.navClass+'" onclick="'+this._name+'.prevPage();return false;">&laquo;</a>';
				
				for (var i=1; i<= this._pgTtl; ++i){
					var lsty = "";
					//if (i<this._pgTtl) lsty = 'style="padding-right:10px"';
					lsty = 'style="padding-right:10px; "';
					msg +=' <a id="'+this._nN+'pnavlnk'+i+'" href="" '+lsty+' class="'+this.navClass+'" onclick="'+this._name+'.showPage('+i+');return false;">'+i+'</a>';
				}
				
				msg+='<a id="'+this._nN+'pnavlnkNext" href="" class="'+this.navClass+'" onclick="'+this._name+'.nextPage();return false;">&raquo;</a>';
				//create pagination div and attach it
				//msg+='<div class="clear"></div>';
				break;
		}
		var d = document.createElement("div");
		d.id=this._nN+"paginateNav";
		d.style.textAlign=this.navAlign;
		if (this.navAlign == "right"){
			d.style.marginRight=this._colMrgn+"px";
		} else {
			d.style.marginLeft=this._colMrgn+"px";
		}
		d.innerHTML=msg+'<div style="clear:both;"></div>';
		var p = this._n.parentNode;
		f = p.appendChild(d);
		//all done, now do it!
		this.showPage(1,true);

	}
	
	
	
} // end object definition

function newColumnPagination(name){
	window[name] = new ColumnPagination(name);
}