var arrLinkedLists = [];

function LinkedList(page,name,childName,isParent,isRequired,popAllChild,selItems,AnyOption,NoRecords,searchProc,catType){
	ShowDebug("New LinkedList name = "+ name + " child = "+ childName + " catType = "+ catType);
	this.Page		= page;
	this.Name		= name;
	this.ChildName	= childName;
	this.IsParent	= isParent;
	this.Required	= isRequired;
	this.SelItems	= selItems;
	this.AnyOption	= AnyOption;
	this.NoRecords	= NoRecords;
	this.PopAllChild= popAllChild;
	this.SearchProc	= searchProc;
	this.CatType	= catType;
	this.ChangeCount= 0;
	if(this.ChildName!=""){
		this.InChain = true;
		ShowDebug("InChain set onPopulate");
		var self = this;
		ShowDebug("We have a child that needs attention = " + childName + " so set this fields values and then the onPopulate should fire to fill the kid up");
		setField(self.Name,self.SelItems);
		ShowDebug("(self.PopAllChild&&self.IsParent) === " + (self.PopAllChild&&self.IsParent));
		this.OnPopulate	= function(){selectField(self.Name,self.Page,(self.PopAllChild&&self.IsParent)?true:false,self.Required);}
	}else{
		this.InChain = false;
	}
	ShowDebug("Should be in array");
}


function setField(name,sel){
	ShowDebug("In setField for " + name + ", sel = " + sel);
	if(Trim(sel)==""){
		ShowDebug("After TRIM sel = '' so return");
		return; //no need for anything as nothing to be selected
	}
	var el = getEl(name);
	if(!el){
		ShowDebug("element not found so set ONLOAD function so that once it is we select these values");
		addLoadEvent(function(){setField(name,sel);});
		return;
	}
	ShowDebug("got REF to el = " + name + " - " + el + " - " + el.tagName + " - " + el.id)
	if(el&&el.options&&el.value==""){ //if options have already been set (server side) then ignore
		var x,i,arr=sel.split(",");
		ShowDebug("do loop to " + el.options.length)
		for(x=0;x<el.options.length;x++){
			for(i=0;i<arr.length;i++){
				ShowDebug("DOES " + Trim(arr[i]) + " == " + el.options[x].value + " ??");
				if(Trim(arr[i])==el.options[x].value){
					ShowDebug("YES SELECT THIS VALUE!!!!");
					el.options[x].selected = true;
				}
			}
		}
	}
	ShowDebug("All values should be selected now");
	return;
}


function selectField(name,page,popAll,req)
{
	ShowDebug("IN selectField = " + name + ", " + page + ", " + popAll + ", " + req + " bAllowAjax = " + Browser.AJAXEnabled);	
	if(Browser.AJAXEnabled==false){ ShowDebug("Browser is not AJAXEnabled so EXIT FUNCTION!!");return;}
	//if this list has no child no need to collect values to pas to xmlHTTP to populate child with results
	var objList = getListObject(name,page,false);
	if(!objList){ShowDebug("No objList so EXIT FUNCTION!!");return;}
	ShowDebug("got object lets look")
	//enumObj(objList);
	//ShowAllObjects(page);
	ShowDebug("DO WE POPULATE ALL = " + popAll + " SEL ITEMS LEN = " + objList.SelItems.length);
	if(popAll && (objList.ChangeCount>0 || (objList.SelItems.length>0&&objList.SelItems!='0'))){popAll=false;}
	if(objList.InChain){
		var childName = objList.ChildName;
		ShowDebug("selectField; childName for " + name + " is "  + objList.ChildName);
	}
	if(objList.ChildName==""){
		ShowDebug("selectField; " + objList.Name + " has no child so no need to call ajax to populate any other lists. EXIT FUNCTION!!")
		return;
	}else{
		ShowDebug("selectField; " + name + " has a child '" + childName + "' so call ajax to populate");	
	}
	var catID="";
	ShowDebug("get element for '"+name+"'");
	var el = getEl(name);
	ShowDebug("typeof = " + typeof(el));
	for(var x=0;x<el.options.length;x++){
		if((popAll) || el.options[x].selected){
			catID+=el.options[x].value+",";
		}
	}
	ShowDebug("After concat selected values in " + name +" we have list of categories = " + catID);
	if(catID==""||catID==","){catID=0;}
	else{
		if(catID.substring(catID.length-1,catID.length)==",")
			catID=catID.substring(0,catID.length-1);
		if(catID.substring(0,1)==",")
			catID=catID.substring(1,catID.length);
	}
	objList.ChangeCount++;
	var qry = 'cat=' + enc(catID) + '&sp='+objList.SearchProc+'&ct='+objList.CatType;
	ShowDebug('selectField; qry is == \n' + '/jobboard/scripts/ajax/categories.asp' + ', ' + qry + ', "populateLinkedList", ' + childName + ', ' + page) 
	xmlhttpPost('/jobboard/scripts/ajax/categories.asp',qry,'populateLinkedList',childName,page); 	
//	ShowDebug("return from select func for " + name);
}
function ShowAllObjects(page){
	ShowDebug("IN ShowAllObjects for page = " + page);
	if(arrLinkedLists && arrLinkedLists.length>0){
		ShowDebug("There are " + arrLinkedLists.length + " stored linked list objects for this page = " + page);
		for(var x=0;x<arrLinkedLists.length;x++){
			if(arrLinkedLists[x].Page==page){				
				enumObj(arrLinkedLists[x]);
			}
		}
	}
	ShowDebug("Return from ShowAllObjects");
}
// function to return a reference to the linked list object either for an item or that items child
function getListObject(name,page,getChild)
{
	ShowDebug("IN getListObject " +name+", " +page+", " +getChild)
	var objList;
	if(arrLinkedLists.length>=0){
		for(var x=0;x<arrLinkedLists.length;x++){
			ShowDebug("does " + arrLinkedLists[x].Name + " == " + name +" && " + arrLinkedLists[x].Page + " == " + page + " ??");
			if(arrLinkedLists[x].Name==name && arrLinkedLists[x].Page==page){
				ShowDebug("MATCHES")
				if(getChild){
					ShowDebug("RETURN CHILD")
					return getListObject(arrLinkedLists[x].ChildName,page,false);

				}else{
					ShowDebug("RETURN OBJECT");
					return arrLinkedLists[x];					
				}
			}
		}
	}
	return objList;
}
function populateLinkedList(strIn,name,page) { 
	ShowDebug('IN populateLinkedList for = ' + name + ' page = ' + page + ' strIn=' + strIn) 
	var content = "";  
	var rowCount = 0; 
	var responseArray; 
	var contentArray; 
	var addNo = 0; 
	ShowDebug("get object for " + name + " " + page)
	var objList = getListObject(name,page,false); //get a reference to the object we need to populate by name	
	if(typeof objList!="object"){return;}
	ShowDebug("got object = " + name);
	// Split row count from main results 
	responseArray = strIn.split('\n\n'); 
	// Get row count
	rowCount = responseArray[0]; 
	ShowDebug(rowCount + ' row(s) returned.'); 
	// Actual records are in second array item  
	// Split them into the array of DB rows 
	contentArray = responseArray[1].split('\n'); 
	var elTarget=objList.Name;
	ShowDebug("populate child of "+ name + " which is " + objList.ChildName + " elTarget = "+elTarget);
	if(getEl(elTarget)){ 
		var elT = getEl(elTarget); 
		elT.options.length=0; 	
		ShowDebug("No of categories to populate = " + contentArray.length);
		if(contentArray.length-1>0){ 
			if(!objList.Required){ 
				elT.options[0]=new Option(); 
				elT.options[0].value="";
				elT.options[0].text=objList.AnyOption;
				addNo = 1; 
			} 
			var sel = objList.SelItems;
			if(sel&&sel.length){
				ShowDebug("typeof sel = " + typeof(sel))
				if(typeof(sel)=="string") sel=sel.split(",") //make sure we have array of values to select
				ShowDebug("selected items that need populating in this list = " + sel.toString());
			}/*else{
				ShowDebug("NO selected items to populate as sel = " + sel)
			}	*/
			ShowDebug("Now loop from 0 to " + (contentArray.length-1) + " populating list");
			for (var i = 0; i < contentArray.length-1; i++) { 
				//ShowDebug("do " + i + " of " + (contentArray.length-1))
				// Create new category object for each list item 
				objCategory = new categoryListing(contentArray[i]); 
				//ShowDebug("Add list item = " + objCategory.CategoryID + " - " + objCategory.Category + " to pos " + (i+addNo) + " in list");
				elT.options[i+addNo]=new Option(); 
				elT.options[i+addNo].value=objCategory.CategoryID; 
				elT.options[i+addNo].text=objCategory.Category;
				//ShowDebug("added ok")
				//ShowDebug("sel = " + sel)
				//ShowDebug("sel.length = "+ sel.length)
				if(sel.length>=0){
					//ShowDebug("check for items to select = " + sel.length)
					for(var s=0;s<sel.length;s++){
					/*	ShowDebug("in loop " + s + " of " + sel.length)
						ShowDebug("does " + objCategory.CategoryID)
						ShowDebug(" == " + sel[s])	*/
						if(objCategory.CategoryID==Trim(sel[s])){  //MUST BE ON PAGE INCLUDING FUNCTIONS.JS FOR TRIM TO WORK!!!!
							//ShowDebug("set selected item " + i + " which is " + sel[s]);
							elT.options[i+addNo].selected = true;
						}
						//ShowDebug("next sel loop")
					}
				}
				//ShowDebug("move to next item");
			} 
		}else{ 
			elT.options[0]=new Option(); 
			elT.options[0].value = "";
			elT.options[0].text = objList.NoRecords;
		} 
		ShowDebug("Do I have to call the OnPopulate for a kiddy?? objList.InChain = " + objList.InChain + " - objList.ChildName = " + objList.ChildName);
		if(objList.InChain){
			ShowDebug("populateLinkedList; object " + objList.Name + " is in chain so fire OnPopulate to populate its child which is " + objList.ChildName);
			objList.OnPopulate();
		}
	} 
} 

function categoryListing(category) {
	var categoryArray = category.split('|');    
    this.CategoryID = categoryArray[0];
    this.Category   = categoryArray[1];	    
}

function formatASCIItoHex(strIn) { 
	var un = strIn.toString(16); 
	while (un.length < 4) {un = '0' + un;} 
	return '\\u' + un; 
} 
function formatSpecial(strIn) { 
	var c,strOut = ''; 
	for (var i = 0; i < strIn.length; i++) { 
		c = strIn.charAt(i); 
		if (c < ' ' || c > '~') {c = '&#' + c.charCodeAt() + ';';} 
		strOut += c; 
	} 
	return strOut; 
} 
