/* MULTI-COLUMN LIST

*** NOTES ***
[2005-09-20 bsweeney]
Please refer to the documentation at http://www.project2061.org/includes/CodeLibrary/MultiColumnList/multiColumnList.manual.htm
*/

function mcl_bwcheck(){
	this.ver=navigator.appVersion
	this.agent=navigator.userAgent
	this.dom=document.getElementById?1:0
	this.opera5=this.agent.indexOf("Opera 5")>-1
	this.safari=this.agent.indexOf("Safari")>-1
	this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
	this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
	this.ie7=(this.ver.indexOf("MSIE 7")>-1 && this.dom && !this.opera5)?1:0;
	this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
	this.ie=this.ie4||this.ie5||this.ie6||this.ie7
	this.mac=this.agent.indexOf("Mac")>-1
	this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
	this.ns4=(document.layers && !this.dom)?1:0;
	this.bw=(this.ie7 || this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
	return this;
}

function mcl_addEvent(obj, evType, fn, useCapture){
	if (obj.addEventListener){
		obj.addEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	}
}

function mcl_init (e) {
	var i, j, k
	var araListNodes = new Array();
	
	/* Add references to an array of list nodes that are to be styled for multiple columns. */
	var objCollection = document.getElementsByTagName('ul');
	for (i = 0; i < objCollection.length; i++) {
		objCollection[i].className.search(/\bmultiColumnList\b/ig) != -1 ? araListNodes.push(objCollection[i]) : null;
	}
	objCollection = document.getElementsByTagName('ol');
	for (i = 0; i < objCollection.length; i++) {
		objCollection[i].className.search(/\bmultiColumnList\b/ig) != -1 ? araListNodes.push(objCollection[i]) : null;
	}
	objCollection = null;
	
	/* For each list, parse the list items for layout */
	for (i = 0; i < araListNodes.length; i++) {
		if (araListNodes[i].className.indexOf(/\bmultiColumnList\b/ig)) {
			araListNodes[i].className += (araListNodes[i].className.length > 0 ? ' ' : '') + 'mclList';
			var intWidth = parseInt(araListNodes[i].offsetWidth);
			var intHeight = 0;
			var intColumnHeight = 0;
			var objCollection = araListNodes[i].getElementsByTagName('li');
			j = 0;
			
			/* Set the width of the list items then determine the total height of all list items. */
			while (j < objCollection.length) {
				objCollection[j].style.width = 100/mcl_columnCount + '%';
				intHeight += parseInt(objCollection[j].offsetHeight);
				j++;
			}
			var j = 0;
			
			/* Set up the first column based on the number of columns and the list height. */
			while (intColumnHeight < (intHeight/mcl_columnCount)) {
				intColumnHeight += parseInt(objCollection[j].offsetHeight);
				objCollection[j].style.marginLeft = '0px';
				j++;
			}
			
			/* Set up subsequent columns. */
			for (k=2; k <= mcl_columnCount; k++) {
				/* Sometime more columns are specified than can be filled (based on the height calculations).
				When this happens check to see if the current item has already been positioned. If so, we have 
				reached the end of the list and don't need to process the list items any further. */
				if (isNaN(parseInt(objCollection[j].style.marginTop))) {
					/* Set the top margin on the first list item of the column based on its current position and 
					the position of the first list item. */
					objCollection[j].style.marginTop = -1 * (parseInt(objCollection[j].offsetTop) - parseInt(objCollection[0].offsetTop)) + 'px';
					objCollection[j].mclColumnTop = true;
					var intCurrentHeight = 0;
					/* Set the width of each list item and determine the column height (which should be less then 
					or equal to the height of the first column). */
					while (intCurrentHeight <= (intColumnHeight) && j < objCollection.length) {
						intCurrentHeight += parseInt(objCollection[j].offsetHeight);
						objCollection[j].style.marginLeft = ((k-1)*(100/mcl_columnCount)) + '%';
						/* IE weirdness. For some reason IE does not always assign a margin when % is used. We'll 
						set the margin using pixels if the current offset is zero. */
						parseInt(objCollection[j].offsetLeft) == 0 ? objCollection[j].style.marginLeft = ((k-1)*(araListNodes[i].offsetWidth/mcl_columnCount)) + 'px' : null;
						/* IE weirdness. In quirks mode the width includes the margin so we need to take that 
						value into mind when determining the width of the list item. */
						(mcl_browser.ie6 || mcl_browser.ie7) && document.compatMode && document.compatMode == "BackCompat" ? objCollection[j].style.width = ((1/(mcl_columnCount+1-k))*100) + '%' : null;
						j++;
					}
					j-=1;
				}
			}
			/* Set the height of the last list item so that it fills in the empty space at the end of the 
			column its in. This will prevent following nodes from overlapping the list. */
			objCollection[j].style.height = (parseInt(objCollection[j].offsetHeight) + intColumnHeight - intCurrentHeight) + 'px';
		}
		/* Record the current height of the list. */
		araListNodes[i].mclHeight = parseInt(araListNodes[i].offsetHeight);
		/* Push the list reference onto the global array. */
		araMCLLists.push(araListNodes[i]);
	}
	setTimeout('mcl_correct()', 100);
}

function mcl_correct (intColumnHeight) {
	/* Since we have to specify the margin-top absolutely (in pixels) we need to constantly check to 
	make sure the height of the list hasn't changed through a font size change or list width change. This 
	function doesn't take into account the addition or removal of list items. We're assuming the list item 
	distribution is remaining static so we'll just correct the placement of each column. */
	var i, j, k
	var intColumnHeight = 0;
	var intCurrentHeight = 0;
	for (i = 0; i < araMCLLists.length; i++) {
		/* If the recorded height doesn't match the current height correct the list layout. */
		if (araMCLLists[i].mclHeight != parseInt(araMCLLists[i].offsetHeight)) {
			objListNodes = araMCLLists[i].getElementsByTagName('li');
			for (j = 0; j < objListNodes.length; j++) {
				/* If the current list item's mclColumnTop JS property is true it's the top of a column. 
				Reset the margin and calculate a new value. Also reset the column height calculation. */
				if (objListNodes[j].mclColumnTop == true) {
					objListNodes[j].style.marginTop = '0px';
					objListNodes[j].style.marginTop = -1 * (parseInt(objListNodes[j].offsetTop) - parseInt(objListNodes[0].offsetTop)) + 'px';
					intColumnHeight < intCurrentHeight ? intColumnHeight = intCurrentHeight : null;
					intCurrentHeight = 0;
				}
				/* Add the current list item's height to the column height. */
				intCurrentHeight += parseInt(objListNodes[j].offsetHeight);
				/* If a height is assigned to the list item we're assuming it's the last item in the list. 
				Recalculate the height necessary to fill in the empty space. */
				if (!isNaN(parseInt(objListNodes[j].style.height))) {
					objListNodes[j].style.height = (parseInt(objListNodes[j].offsetHeight) + intColumnHeight - intCurrentHeight) + 'px';
				}
			}
		}
		/* Record the current height of the list. */
		araMCLLists[i].mclHeight = parseInt(araMCLLists[i].offsetHeight);
	}
	setTimeout('mcl_correct()', 100);
}

/* Global variable and event initialization */
var araStoryList = new Array();
var araStoryDetail = new Array();
var araMCLLists = new Array();
var mcl_browser = new mcl_bwcheck();
mcl_addEvent(window, 'load', mcl_init, true);


/* BEGIN USER-DEFINED VARIABLES */
var mcl_columnCount = 3;
/* END USER-DEFINED VARIABLES */
