/* 
  ------------------------------------------------
  						Cellera
			Equal CSS Cells script
	by Arjay Enterprises www.arjayenterprises.com 
			Version 1.0 2007 02 21
	Keep a row of DIV cells the same height

  There are lots of scripts like this around the net that we mined for ideas.  
  Some code and logic was modified and corrected from one bearing the notice:
    Version: 2.1.0
    Copyright (c) 2005 Project Seven Development
    www.projectseven.com
 
  However, only scraps remain of the original, no we offer a nod and thanks to them for ideas.
  
  No copyright claimed by Arjay and no warantees offered. Use it or change it as you please at your own risk.

  This script allows multiple rows of cells to be maintained at equal heights so that a developer
  	can have a row-column effect on a site page without using tables for things they weren't intended for.

  Call by: equCellHeight(rowNum,triples of {celldiv id, style element, effect)
  	rowNums are integers. Start at one or the code will waste time.
  	effect Add the following:
  	  animation 0=no 1=yes (I've borrowed this from the P7 version, but it's of little use.)
  	  pad bottom 0=no 2=yes
  	  pad top 0=no 4=yes
  	If only the top or only the bottom is set, all the pad goes there, if both it is split to centre the element
  	if, say, for a 'cell' div to be equalized, the style element is 'P' then
  		the extra padding will be added to the last P element inside (child of) that cell.
  	if the element passed is empty or there is no element of the kind specified, the padding will be added to the bottom
  	    of the div container itself
  	Padding in the original block element that is being manipulated need not be zero
  	   because we compute it here and take it into account except for rows startin g out with display set to none.
  	
  ------------------------------------------------
*/

	//init array to hold data objects for each set of cell divs to equalize
var rows = new Array();
var intervalSet = false; // so we dont waste time setting up more than once
var idcount = 0; oldHeight=0, oldWidth=0;

	//adjust the padding on the style element designated for that cell
function cellAdj(rowNum)
{ 
	var i,oh,maxHt=0,tg,el,newCellPad,oldCellBPad,newCellBPad,oldCellTPad,newCellTPad,effectFlags;
	var celldata=rows[rowNum].celldata, done=rows[rowNum].done, padData = rows[rowNum].padData;
	if(celldata&&celldata.length) // check for valid
	{	
		for(i=0;i<celldata.length;i+=3) 
			{effectFlags = celldata[i+2];
			if (effectFlags >= 4) // top flag set on this element?
				{celldata[i+1].style.paddingTop='0'}; //then init top padding to zero
			celldata[i+1].style.paddingBottom='0';} //init the bottom pad to zero
		for(i=0;i<celldata.length;i+=3)  //and start computing a new pad amount
			{oh=(celldata[i].offsetHeight)? celldata[i].offsetHeight:0; //look at each current cells offset height
			oldCellTPad = (effectFlags >= 4? padData[(i)]:0); 
			oldCellBPad = padData[(i+1)];
			oh = oh + oldCellBPad+oldCellTPad; 
			maxHt=(oh>maxHt)?oh:maxHt;//collect the largest one in maxHt
			rows[rowNum].height=maxHt;
			}//for

		for(i=0;i<celldata.length;i+=3) // and compute a pad to apply to each cell
			{newCellTPad=0;newCellBPad=0;
			oh=celldata[i].offsetHeight; 
			effectFlags = celldata[i+2]; 
			if(oh<maxHt)
				{newCellPad=maxHt-oh; // compute total pad for the element where it goes
				if (effectFlags >= 4) //top flag set?
					{newCellTPad = newCellPad-oldCellBPad; // put whole pad but old Bottom in top for now in case no bottom
					if (effectFlags >= 6) //both top and bottom flags set
						{newCellTPad = Math.floor((oldCellTPad+newCellTPad)/2)}; // so split the pad up and no decimal places wanted
					} //if (effectFlags >= 4)
				 effectFlags = effectFlags % 4; // chop down so only two bits left
				 newCellBPad=newCellPad-newCellTPad; // take whatever is left from the top for the bottom; will include original pad
				 effectFlags = effectFlags % 2; // and chop down to the least bit for animation
				 if(newCellTPad>0) {celldata[i+1].style.paddingTop=newCellTPad+"px"}; //else leaves it as it was
				 if(!done&&effectFlags==1){adjCellAnim(celldata[i+1].id,0,newCellBPad);} //pad the items bottom the animated way
				 else{ celldata[i+1].style.paddingBottom=newCellBPad+"px";} //the static way
				 //if (rowNum == 1) debug ("oh = "+ oh +"newCellBPad = " + newCellBPad + "NEWcelldata[i].offsetHeight = " +celldata[i].offsetHeight);
				}//if(oh)
			}//for
		rows[rowNum].done=1;
		

	} //if	
} //cellAdj	//timed function that is set to do adjustments
function eqCellHtTimed()
{	
	var celldata, oh, needAdj;
	{for (rowNum=1;rowNum<rows.length;rowNum++) //run through the array of rows
		{if(rows[rowNum]) //check if a valid row and need to do an adjust
			// in any case, adjust the row if whole doc height changed
			{	//needAdj = (oldHeight!=document.body.offsetHeight||oldWidth!=document.body.offsetWidth)
				if (!needAdj) //if so, no need to check row heights, so save some time
					{celldata=rows[rowNum].celldata;
					oh= rows[rowNum].height;
						for(i=0;i<celldata.length;i+=3)  //look at each cell height in the  row
							{ //to see if changed since old height set on this row
								if (oh != celldata[i].offsetHeight) {needAdj = true;}//
								//debug ("i = " + i +"   oh="+oh+"    "+celldata[i].Id+"="+celldata[i].offsetHeight)
							}
						
					}// if (!needAdj)
			} //if(rows[rowNum])
		if (needAdj) {cellAdj(rowNum); }//debug (rowNum+"adjusted");
		}
	}//for rowNum
	//now stash the document body height and width after doing a complete adjust
	//so that when we next trigger this on the timer, it will execute if
	//one of the two has changed since the last time we were here.
	oldHeight=document.body.offsetHeight;
	oldWidth=document.body.offsetWidth;

}//eqCellHtTimed

/* *********** main proc to call with syntax
		equCellHeight(rowNum,effectflag 0-6,pairs of row, style elements to put padding into)
		*/
function equCellHeight()
{    // does setup of the row data
   var cell,els,elToPad;
   var totalHeight,baseHeight, padStr, dispStr;
	if(document.getElementById)
		{rowNum = arguments[0];
		rows[rowNum]=new Array();
		rows[rowNum].celldata=new Array(); //to hold cell obj, pad element obj and effect flag triples
		rows[rowNum].padData=new Array(); // to hold old top and bottom pad data for each element
		for(i=1;i<arguments.length;i+=3) //count through the {cell, element} pairs
		 	{elToPad=null;
		 	cell=document.getElementById(arguments[i]); //get each cell to equalize by its id
		 	if(cell)
		 		{if (arguments[i+1].length >0) // was an element to pad supplied?
					{els=cell.getElementsByTagName(arguments[i+1]); //yes, get all instances of that  element
					 if(els.length>0&&els[els.length-1]) // is there one and is there a last one of that type
						{elToPad=els[els.length-1]; // get that last element 
						 if(!elToPad.id) {elToPad.id="eqcell"+idcount; idcount+=1;} //and give it an id if it lacks one
						} // if els
						else {elToPad = cell;} //if no elements of that kind, pad the cell
 					}
 				else // also if no pad element supplied pad the cell div itself
 					{elToPad = cell;}
 				}//if cell
 			if(cell&&elToPad) // then put both the cell, the element to pad, and the effects flags in the data array at the next three positions
 				{				
 				rows[rowNum].celldata[rows[rowNum].celldata.length]=cell;
 				rows[rowNum].celldata[rows[rowNum].celldata.length]=elToPad;
 				rows[rowNum].celldata[rows[rowNum].celldata.length]=arguments[i+2];
 				//debug ("  rowNum=  "+rowNum + "   "+"   i="+i+"eflag=   " +arguments[i+2]);				
 				// next compute and store the original bottom padding for each element subject to padding change
 				// has to be done this way because Javascript cannot directly read properties it has not set itself
 				dispStr= elToPad.style.display; // store this in case the item is not displayed
 				elToPad.style.display="block"; // and temporarily reset so it has a height
 				padStr = elToPad.style.paddingBottom;
 				totalHeight=elToPad.offsetHeight; // get the original height
 				elToPad.style.paddingBottom='0'; // drop bottom padding to zero
 				baseHeight=elToPad.offsetHeight; // and recompute height 
 				rows[rowNum].padData[i]=(totalHeight - baseHeight)? totalHeight - baseHeight:0; // recompute height and save difference for later
 				elToPad.style.paddingBottom=padStr; // put back pad string

					// compute the original top pad the same way
  				padStr = elToPad.style.paddingTop;
 				totalHeight=elToPad.offsetHeight; // get the height with the bottom pad restored
 				elToPad.style.paddingTop='0'; // drop top padding to zero
 				baseHeight=elToPad.offsetHeight; // and recompute height 
 				rows[rowNum].padData[i-1]=(totalHeight - baseHeight)? totalHeight - baseHeight:0; // and save difference for later
 				elToPad.style.paddingTop=padStr; // put back pad string
 				elToPad.style.display=dispStr; // and restore the original display 
					// note that we stored them in the order top, bottom
 				}
 			}//for(i=2)
		if (intervalSet) {} // no need to set this up every time we have a new row
		else
			{setInterval("eqCellHtTimed()",100);
			intervalSet = true; 
			}
		}//if (document)
}//equCellHeight

	//animated adjust function for element elid
function adjCellAnim(elid,p,totalPad)
{ //on first call p=0; adjusted for subsequent calls
	var sp=10,inc=20, adjItem=document.getElementById(elid);
	padDone=(p>=totalPad)?totalPad:p;
	adjItem.style.paddingBottom=padDone+"px";
	if(padDone<totalPad) // finished yet?
		{padDone+=inc; //no, so go around again
 		setTimeout("adjCellAnim('"+elid+"',"+padDone+","+totalPad+")",sp);
 		}//if
}//adjCellAnim

/////////////////////////

/* auxiliary functions below this */
/* function for  debugging */function debug (message)
{	 window.alert (message)
}

//call this way, with whatever items are needed:
//debug ("rowNum=  "+rowNum + "   ");
