
function SearchFilterController(d, m, n) {

	var List = function(header, ul){
		var oUL = ul;
		var sHeader = header;
		var expanded = false;
		var oThis = this;
		//alert(sHeader + ": " + sHeader.length);
		//sHeader = sHeader.replace(/[^\w ]/g, "");
		var createMoreLI = function(){
			var oLI = document.createElement("LI");
			var aHREF = document.createElement("A");
			aHREF.innerHTML = "MORE &raquo;";
			aHREF.href = "#";
			aHREF.onclick = function() {
				oThis.expand(oThis);
				return false;
			}
			oLI.appendChild(aHREF);
			return oLI;
		}

		var createBackLI = function(){
			var oLI = document.createElement("LI");
			var aHREF = document.createElement("A");
			aHREF.innerHTML = "&laquo; BACK";
			aHREF.href = "#";
			aHREF.onclick = function() {
				oThis.collapse();
				return false;
			}
			oLI.appendChild(aHREF);
			return oLI;
		}
				
		this.expand = function(){
			//alert(arguments.length);
			//alert(arguments[0]);			
			expanded = true;
			expandList(this);
		}
		
		this.collapse = function(){
			expanded = false;
			collapseList();
		}
	 		
		var displayExpanded = function(aTD, nSize){
			if(nSize == null){
				nSize = nRowMax;
			}
			nSize = Math.min(nSize, oUL.childNodes.length);
			
			var oColUL = document.createElement("UL");
			var oCopyLI = null;			
			for(var i=0;i<oUL.childNodes.length;i++){
				//alert("size: " + nSize + " i: " + i + " % " + i % nSize);
				if(i != 0 && i % nSize == 0){

					//new UL, not at the beginning, and not at the end
					//aTD.appendChild(oColUL);									
					//var oColUL = document.createElement("UL");		
					//alert("new ul");			
				}

				if(i != 0 && i % nSize == 0){
					//oColUL.appendChild(createMoreLI());
					aTD.appendChild(oColUL);
					oColUL = document.createElement("UL");
				}
				oCopyLI = document.createElement("LI");
				//oCopyLI.innerHTML = oUL.childNodes[i].innerHTML + " " + i + " " + nSize + " " + (i % nSize);
				oCopyLI.innerHTML = oUL.childNodes[i].innerHTML;
				if(oUL.childNodes[i].childNodes.length > 0){
					oCopyLI.childNodes[0].onclick = oUL.childNodes[i].childNodes[0].onclick
				}
				oColUL.appendChild(oCopyLI);
				if(i==nSize-1){
					oColUL.appendChild(createBackLI());
					//alert("i: " + i + " nSize: " + nSize);
				}


			}
			aTD.appendChild(oColUL);	
			//alert(nSize);
		}
		
		var displayCollapsed = function(aTD, nSize){
			if(nSize == null){
				nSize = nRowMax;
			}
			nSize = Math.min(nSize, oUL.childNodes.length);
			var oColUL = document.createElement("UL");
			var oCopyLI = null;			
			for(var i=0;i<nSize;i++){
				oCopyLI = document.createElement("LI");
				oCopyLI.innerHTML = oUL.childNodes[i].innerHTML;
				if(oUL.childNodes[i].childNodes.length > 0){
					//alert(oUL.childNodes[i].childNodes[0].onclick);
					oCopyLI.childNodes[0].onclick = oUL.childNodes[i].childNodes[0].onclick
				}
				oColUL.appendChild(oCopyLI);
			
			}
			if(oUL.childNodes.length > nSize){
				oColUL.appendChild(createMoreLI());
			}
			aTD.appendChild(oColUL);	
			
		}
		
		this.displayWithin = function(oTable){
			//alert(this.getHeader());
			//oTable has two rows, a header row, and a data row... fill it in
			var headerCell = document.createElement("TH");
			var mainCell = document.createElement("TD");

			headerCell.innerHTML = sHeader;
			
			//are we expanded??
			if(expanded){
				//var lists = splitUpList();
				//for(var i=0;i<lists.length;i++){
					//mainCell.appendChild(lists[i]);
				//}
				displayExpanded(mainCell);
			}else{
				displayCollapsed(mainCell);
				//mainCell.appendChild(shortenList());
			}			
			oTable.childNodes[0].childNodes[0].appendChild(headerCell);
			oTable.childNodes[0].childNodes[1].appendChild(mainCell);			
		}

		this.getHeader = function(){
			return sHeader;
		}
	}	
	
	var nColMax = 0;
	var nRowMax = 0;
	var oLists = new Array();
	var oDiv = null;
	var oRefiner = null;
	var oExpandedList = null;
	var notWhitespace = /\S/;
	var oThis = this;
	
	//private functions
	var initSearchFilterController = function(args){
		oDiv = args[0];
		nColMax = args[1];
		nRowMax = args[2];
		parseContentDiv();
	}	
	
	//helper method to remopve WHITE SPACE nodes move to HBI??
	var removeWhiteSpaceNodes = function(oNode){
		for(var i=0;i<oNode.childNodes.length;i++){
			if(oNode.childNodes[i].nodeType == 3 && !notWhitespace.test(oNode.childNodes[i].nodeValue)){
				oNode.removeChild(oNode.childNodes[i]);
				i--;
			}else if(oNode.childNodes[i].nodeType == 1){
				removeWhiteSpaceNodes(oNode.childNodes[i]);
			}
		}
	}
	
	//helper method to merge the children of a node move to HBI??
	//used to merge two UL's within a TD
	var mergeChildren = function(oNode){
		for(var i=1;i<oNode.childNodes.length;i++){
			while(oNode.childNodes[i].childNodes.length > 0){
				oNode.childNodes[0].appendChild(oNode.childNodes[i].childNodes[0]);
			}
		}
	}
	
	var parseContentDiv = function(){
		removeWhiteSpaceNodes(oDiv);
		var headerRow = oDiv.childNodes[0].childNodes[0].childNodes[0];
		var listRow = oDiv.childNodes[0].childNodes[0].childNodes[1];
				
		//loop over the table and create headers array and lists array
		var headerArray = new Array(headerRow.childNodes.length);
		var listArray = new Array(listRow.childNodes.length);		
		
		if(headerArray.length != listArray.length){
			alert("not the same size!!");
		}	
		for(var i=0;i<headerArray.length;i++){
			//regex...
			//alert(":" + headerRow.childNodes[i].childNodes[0].nodeValue + ":");
			//headerArray[i] = headerRow.childNodes[i].childNodes[0].nodeValue.replace(/[^\w ]/g, "");
			headerArray[i] = headerRow.childNodes[i].childNodes[0].nodeValue;
			//alert(":" + headerArray[i] + ":");
			if(listRow.childNodes[i].childNodes.length > 1){
				//we have a MORE row as there is more than one UL element!!
				mergeChildren(listRow.childNodes[i]);
			}
			listArray[i] = listRow.childNodes[i].childNodes[0];			
			
			addList(new List(headerArray[i], listArray[i]));			
		}
		
		buildRefiner();
	}

	var buildRefiner = function(){
		//build up the UL first using entries in the oList from 
		//nColMax to oLists.length
		//var oThis = this;
		var oUL = document.createElement("UL");
/*
		for(var j=nColMax;j<oLists.length;j++){
			alert(oLists[j].getHeader());
		}
*/		
		for(var i=nColMax;i<oLists.length;i++){
			var oList = oLists[i];
			var oLI = document.createElement("LI");
			var aLink = document.createElement("A");
			aLink.href = "#";
			aLink.innerHTML = oList.getHeader();
			var test = oList.getHeader();
			aLink.onclick = function() {
				//alert(this.innerHTML);
				//oList.expand();
				//var test = oList.getHeader();
				expandListByHeader(this.innerHTML);
				//expandListByHeader(oList.getHeader());
			}
			oLI.appendChild(aLink);
			oUL.appendChild(oLI);

		}
		oRefiner = new List("Or refine by...", oUL);
	}
	
	var clearDisplay = function(){
		while(oDiv.childNodes.length > 0){
			oDiv.removeChild(oDiv.childNodes[0]);
		}
	}

	var addList = function(oList){
		oLists[oLists.length] = oList;
	}
	
	var createEmptyTable = function(){
		var oTable = document.createElement("TABLE");
		//oTable.border = 1;
		var oTBody = document.createElement("TBODY");
		oTBody.appendChild(document.createElement("TR"));
		oTBody.appendChild(document.createElement("TR"));
		oTable.appendChild(oTBody);
		oDiv.appendChild(oTable);
	}
	
	var expandList = function(oList){
		oExpandedList = oList;
		//alert('expand' + oList);
		oThis.update();
	}

	var getListByHeader = function(sHeader){
		for(var i=0;i<oLists.length;i++){
			if(sHeader == oLists[i].getHeader()){
				return oLists[i];
			} 
		}
		return null;
	}
	
	var expandListByHeader = function(sHeader){
		var oList = getListByHeader(sHeader);
		if(oList != null){
			oList.expand();
		}
	}
	
	var collapseList = function(){
		oExpandedList = null;
		oThis.update();
	}
	
	initSearchFilterController(arguments);
	
	//privalledged methods
	this.display = function(){
		//do we have an expanded list??
		if(oExpandedList != null){
			oExpandedList.displayWithin(oDiv.childNodes[0]);
		}else{
			//display main columns...
			for(var i=0;i<nColMax;i++){
				oLists[i].displayWithin(oDiv.childNodes[0]);
			}
			//if we need the refiner, display the refine list
			if(oLists.length > nColMax){
				oRefiner.displayWithin(oDiv.childNodes[0]);
			}
		}
		//alert("update: " + oExpandedList);		
	}
	
	this.update = function(){
		clearDisplay();
		createEmptyTable();
		this.display();
		//alert("done update");
	}
	
}




