
/*------------------------ For ListRenderer ---------------------------*/

function showfull(text, title)
{
	var win = popupVolatileWindow("/CommonLib/lib/blank_wait.asp?nocontent=1", 500, 300, false);
	win.document.write("<html><head><LINK href='/CommonLib/Style/contacts_crm.css' rel=stylesheet><LINK href='/CommonLib/Style/Sphere.css' rel=stylesheet></head><body>");
	win.document.write("<table width=100% cellpadding=0>");
	if (title != null)
		win.document.write("<tr><td class=pageTitleQualifier>" + title + "</td></tr>");
	win.document.write("<tr height=200><td valign=top>" + text.replace(/\n/g, "<br>") + "</td></tr>");
	win.document.write("<tr><td align=center><input class=HtmlButton type=button value='Close Window' onclick='window.close()'></td></tr></table></body></html>\n");
}

function getUniqueWindowName(funcName)
{
	var curr_time = new Date();
	return funcName + curr_time.getHours() + curr_time.getMinutes() + curr_time.getSeconds();
}

function newContent(serverCtrlID, mainform, funcName)
{
	var newWin, winName = getUniqueWindowName(funcName);
	if (funcName == "choosecolumn")
	{
		//popupWinClosePopup();
		newWin = window.open("", winName, "scrollbars,resizable,width=680,height=450");
		//l_popup_win = newWin;
	}
	else if (funcName == "exportxls")
	{
		newWin = window.open("/CommonLib/lib/blank_wait.asp?prmt=MwQMS0XFR3SQQ2VJSPMVIeRJT5RSJ&noimg=1", winName, "menubar=yes,resizable,width=430,height=245");
	}
	else if (funcName == "exportcsv")
	{
		newWin = window.open("/CommonLib/lib/blank_wait.asp?prmt=MwQMS0XFR3SQQ2VJSPMVIeRJT5RSJ&noimg=1", winName, "menubar=yes,resizable,width=430,height=245");
	}
	else if (funcName == "offlinexls" || funcName == "offlinecsv")
	{
		newWin = window.open("", winName, "scrollbars,resizable,width=430,height=245");
	}
	else if (funcName == "printable")
	{
		newWin = window.open("/CommonLib/lib/blank_wait.asp", winName, "scrollbars,resizable,menubar=yes");
	}
	else if (funcName == "ReportExportHTMFormat" || funcName == "ReportExportXLSFormat" || funcName == "ReportExportCSVFormat")
	{
		winName = "NewEngineExportWin";
	}
	else
	{
		alert("Unknown funcName: " + funcName);
		return;
	}
	
	mainform.target = winName;
	__doPostBack(serverCtrlID, funcName);
	mainform.target = "_self";
	mainform.__EVENTTARGET.value = "";
	mainform.__EVENTARGUMENT.value = "";
}
	
function toggleAllChkboxes(boxName)
{
	var all, i, b_has_unchecked=false;
	all = document.getElementsByName(boxName);
	for (i=0; i<all.length; i++)
		if (!all[i].checked)
		{
			b_has_unchecked = true;
			break;
		}
			
	for (i=0; i<all.length; i++)
	{
		all[i].checked = b_has_unchecked;
		if (all[i].onclick != null)
			all[i].onclick();
	}
}

function check_AnyBoxChecked(boxName)
{
	var all;
	all = document.getElementsByName(boxName);
	for (var i = 0; i < all.length; i++)
		if (all[i].checked)
			return true;
					
	return false;
}

function tableCellClick(src)
{
	if(event.srcElement.tagName=='TD')
		src.children.tags('A')[0].click();
}

function actionMouseover(src, class_name)
{
	if (class_name == null)
	{
		src.style.borderTopColor = "#003C79";
		src.style.borderLeftColor = "#003C79";
		src.style.borderRightColor = "#003C79";
		src.style.borderBottomColor = "#003C79";
		src.style.backgroundColor = "#F0F9FF";
		src.style.borderTopWidth = 1;
		src.style.borderLeftWidth = 1;
		src.style.borderRightWidth = 1;
		src.style.borderBottomWidth = 1;
	}
	else
		src.className = class_name;
}

function actionMouseout(src, class_name)
{
	if (class_name == null)
	{
		src.style.borderTopColor = "#e0e0e0";
		src.style.borderLeftColor = "#e0e0e0";
		src.style.borderRightColor = "#e0e0e0";
		src.style.borderBottomColor = "#e0e0e0";
		src.style.backgroundColor = "#e0e0e0";
		src.style.borderTopWidth = 1;
		src.style.borderLeftWidth = 1;
		src.style.borderRightWidth = 1;
		src.style.borderBottomWidth = 1;
	}
	else
		src.className = class_name;
}

function lr_headerOver(src,class_name)
{ 
	src.className = class_name; 
	src.style.cursor = 'hand'; 
}

function lr_headerOut(src,class_name)
{ 
	src.className = class_name; 
	src.style.cursor = 'default'; 
}

function lr_highlightRow(check_ctrl, row_id, hilte_class)
{
	var row = document.getElementById(row_id);
	row.className = (check_ctrl.checked ? hilte_class : null);
}

function CSTabAction(elemTD, elemDIV, bActive, tabClr, bgClr)
{
	var sty = elemTD.style;
	if (bActive)
	{
		sty.backgroundColor = bgClr;
		sty.borderTopWidth = 0;
		sty.borderBottomWidth = 0;
		elemDIV.style.display = "block";
	}
	else
	{
		sty.backgroundColor = tabClr;
		sty.borderTopWidth = 1;
		sty.borderTopColor = "#ffffff";
		sty.borderBottomWidth = 1;
		sty.borderBottomColor = "#888888";
		elemDIV.style.display = "none";
	}
}

//given the nodes array, check (or uncheck) all and their children, unless the tag ends with "|Man".
//if a child is checked, it's expanded too.
function ktree_checkNodeAndChildren(node, bChecked)
{
	var tag = node.getTag();
	if (tag == null || (tag != null && tag.indexOf("|Man") < 0) )
	{
		node.setChecked(bChecked);
		if (bChecked && node.getParent() != null)
			node.getParent().setExpanded(true);	//if check it, then expand it's parent
	}
	
	var nodes = node.getChildNodes();
	for (var i = 0; i < nodes.length; i++)
		ktree_checkNodeAndChildren(nodes[i], bChecked);
}

function ktree_getTopAncestor(node)
{
	var parent = node.getParent();
	return (parent == null ? node : ktree_getTopAncestor(parent));
}

function ktree_onNodeChecked(treeId, nodeId, bChecked)
{
	var node = igtree_getNodeById(nodeId);
	ktree_checkNodeAndChildren(node, bChecked);
}

function ktree_onNodeClick(treeId, nodeId)
{
	var node = igtree_getNodeById(nodeId);
	node.setChecked(!node.getChecked());
}

//the function is:
//if the node is unchecked:
//	1. if none of children is checked, then the node and all children are checked
//	2. if any of the children is checked, then the node and all children are unchecked
function ktree_onNodeCheckedType2(treeId, nodeId, bChecked)
{
	var node = igtree_getNodeById(nodeId);
	var nodes = node.getChildNodes();
	var childChecked = false;
	for (var i = 0; i < nodes.length; i++)
	{
		if (nodes[i].hasCheckbox())
			childChecked |= nodes[i].getChecked();	//true if any child is checked
	}
	
	if (!bChecked && nodes.length > 0)
	{
		ktree_checkNodeAndChildren(node, !childChecked);
		return !childChecked;
	}
}

function ktree_checkAllAncestors(node)
{
	if (node != null)
	{
		node.setChecked(true);
		ktree_checkAllAncestors(node.getParent());
	}
}

//this is the same as type 2 except this additional function:
//if the node is checked, then all parents must be checked.
function ktree_onNodeCheckedType3(treeId, nodeId, bChecked)
{
	var node = igtree_getNodeById(nodeId);
	if (bChecked) ktree_checkAllAncestors(node.getParent());
	return ktree_onNodeCheckedType2(treeId, nodeId, bChecked);
}

function pickerClient(mode, orderListId, allColumnListId, clientId)
{
	this.sortMode = mode;
	this.orderList = document.getElementById(orderListId);
	this.allColumnsList = document.getElementById(allColumnListId);
	this.summaryText = document.getElementById(clientId);
	this.sortList1 = document.getElementById(clientId + "_sort1");
	this.ascList1 = document.getElementById(clientId + "_asc1");
	if (this.sortMode == "DROPDOWN_LIST_3")
	{
		this.sortList2 = document.getElementById(clientId + "_sort2");
		this.ascList2 = document.getElementById(clientId + "_asc2");
		this.sortList3 = document.getElementById(clientId + "_sort3");
		this.ascList3 = document.getElementById(clientId + "_asc3");
	}
	this.syncSortWithOrderlist = cp_syncSortWithOrderlist;
	this.moveToEnd = cp_moveToEnd;
	this.moveUp = cp_moveUp;
	this.moveDown = cp_moveDown;
	this.setSort = cp_setSort;
	this.onAdd = cp_onAdd;
	this.onRemove = cp_onRemove;
	this.onCheckAll = cp_onCheckAll;
	this.updateCheckAndList = cp_updateCheckAndList;
	this.updateList = cp_updateList;
	this.addSelectedColumn = cp_addSelectedColumn;
	this.updateListFromNodes = cp_updateListFromNodes;
	this.updateListsFromTree = cp_updateListsFromTree;
	this.summary = cp_summary;
	this.getFieldCounts = cp_getFieldCounts;
	
	//update counts
	this.getFieldCounts();
}

function cp_addSelectedColumn(listCtrl, text, value)
{
	if (this.sortMode == "BUTTON_SORTALL" && listCtrl == this.orderList)
		text += " (Sorted Asc)";
	listCtrl.options[listCtrl.options.length] = new Option(text, value);
}

function cp_updateListFromNodes(listCtrl, node)
{
	if (node.getTag() != null)
	{
		//check if the item is already in the list
		var idx = -1;
		for (var i=0; i<listCtrl.options.length; i++)
		{
			if (listCtrl.options[i].value == node.getTag())
			{
				idx = i; break;
			}
		}

		var bChecked = node.getChecked();
		if (bChecked && idx == -1)
		{
			var s = node.getText();
			var n = s.indexOf("&nbsp;(");
			if (n >= 0) s = s.substr(0, n);
			this.addSelectedColumn(listCtrl, s, node.getTag());
		}
		else if (!bChecked && idx != -1)
			listCtrl.options[idx] = null;
	}
	var nodes = node.getChildNodes();
	if (nodes.length > 0)
		for (i=0; i<nodes.length; i++)
			this.updateListFromNodes(listCtrl, nodes[i]);
}

function cp_updateListsFromTree(nodeId, bChecked)
{
	var node = igtree_getNodeById(nodeId);
	this.updateListFromNodes(this.orderList, node);
	this.summary();
}

function cp_getFieldCounts()
{
	this.fieldCount = this.orderList.options.length;
	this.customFieldCount = 0;
	for (i=0; i < this.fieldCount; i++)
	{
		if (this.orderList.options[i].value.substring(0, 8) == "CFAlias_")
			this.customFieldCount++;
	}
}

function cp_summary()
{
	//this function will sync sortList1 in "Button" mode, so next we don't have to check "Button" mode
	this.syncSortWithOrderlist();
	
	var i, s = "";

	//first get field counts
	this.getFieldCounts();
	
	if (this.sortMode == "BUTTON_SORTALL")
	{
		for (i=0; i < this.orderList.options.length; i++)
		{
			if (s.length > 0) s += ",";
			s += cp_getFieldNameNoSuffix(this.orderList.options[i].value);
			var txt = this.orderList.options[i].text;
			if (txt.substring(txt.length - 5, txt.length - 1) == "Desc")
				s += " DESC";
			else
				s += " ASC";
		}
		s = "C:" + s;
	}
	else
	{
		s = (this.sortMode == "DROPDOWN_LIST_3" ? "B:" : "A:");
		
		//this part can be empty if the user unselected all fields.
		if (this.sortList1.options.length > 0)
			s += cp_getFieldNameNoSuffix(this.sortList1.options[this.sortList1.selectedIndex].value);
		s += "," + this.ascList1.options[this.ascList1.selectedIndex].value;

		if (this.sortMode == "DROPDOWN_LIST_3")
		{
			s += ",";
			if (this.sortList2.options.length > 0)
				s += cp_getFieldNameNoSuffix(this.sortList2.options[this.sortList2.selectedIndex].value);
			s += "," + this.ascList2.options[this.ascList2.selectedIndex].value;
			s += ",";
			if (this.sortList3.options.length > 0)
				s += cp_getFieldNameNoSuffix(this.sortList3.options[this.sortList3.selectedIndex].value);
			s += "," + this.ascList3.options[this.ascList3.selectedIndex].value;
		}
		
		if (this.orderList.options.length == 0)
		{
			s += ",";	//a single comma to indicate fields (empty) should follow
		}
		else
		{
			for (i=0; i < this.orderList.options.length; i++)
				s += "," + cp_getFieldNameNoSuffix(this.orderList.options[i].value);
		}
	}
	
	this.summaryText.value = s;
}

function cp_syncSortWithOrderlist()
{
	var i, sel_field1, has_sort_sel = false, sel_field2, sel_field3, t, n;
	if (this.sortList1.selectedIndex >= 0)
		sel_field1 = this.sortList1.options[this.sortList1.selectedIndex].value;
	else
		sel_field1 = "sel_field1 dummy value";
		
	//clear sort1
	while(this.sortList1.options.length > 0) this.sortList1.options[0] = null;
	for (i=0; i<this.orderList.options.length; i++)
	{
		t = this.orderList.options[i].text;
		n = t.indexOf(" (Sorted ");
		if (n >= 0) t = t.substring(0, n);
		this.sortList1.options[this.sortList1.options.length] = new Option(t, this.orderList.options[i].value);
		if (this.sortList1.options[i].value == sel_field1)
			this.sortList1.selectedIndex = i;
	}
	
	if (this.sortMode == "DROPDOWN_LIST_3")
	{
		sel_field2 = this.sortList2.options[this.sortList2.selectedIndex].value;
		sel_field3 = this.sortList3.options[this.sortList3.selectedIndex].value;
		//clear sort2 and sort3
		while(this.sortList2.options.length > 0) this.sortList2.options[0] = null;
		while(this.sortList3.options.length > 0) this.sortList3.options[0] = null;
		this.sortList2.options[0] = new Option("", "");
		this.sortList3.options[0] = new Option("", "");

		for (i=0; i<this.sortList1.options.length; i++)
		{
			//add to sort2 if not selected by sort1
			if (this.sortList1.options[i].value != sel_field1)
			{
				var t = this.sortList2.options.length;
				this.sortList2.options[t] = new Option(
					this.sortList1.options[i].text, this.sortList1.options[i].value);

				if (this.sortList2.options[t].value == sel_field2)
					this.sortList2.selectedIndex = t;
				else if (sel_field2 != "")	//if not selected by sort2 and sort2 is not "not selected", add to sort3
				{
					t = this.sortList3.options.length;
					this.sortList3.options[t] = new Option(
						this.sortList1.options[i].text, this.sortList1.options[i].value);

					if (this.sortList3.options[t].value == sel_field3)
						this.sortList3.selectedIndex = t;
				}
			}
		}
	}			
}

function cp_moveToEnd(b_top)
{
	var i, vals, names, ss, index;
	index = 0;
	vals = new Array();
	names= new Array();
	ss = new Array();
		
	for (i=0; i<this.orderList.options.length; i++)
	{
		if ( (b_top && this.orderList.options[i].selected) || (!b_top && !this.orderList.options[i].selected) )
		{
			vals[index] = this.orderList.options[i].value;
			names[index] = this.orderList.options[i].text;
			ss[index] = this.orderList.options[i].selected;
			index++;
		}
	}

	for (i=0; i<this.orderList.options.length; i++)
	{
		if ( (b_top && !this.orderList.options[i].selected) || (!b_top && this.orderList.options[i].selected) )
		{
			vals[index] = this.orderList.options[i].value;
			names[index] = this.orderList.options[i].text;
			ss[index] = this.orderList.options[i].selected;
			index++;
		}
	}
		
	for (i=0; i<this.orderList.options.length; i++)
		if (this.orderList.options[i].value != vals[i])
		{
			this.orderList.options[i].value = vals[i];
			this.orderList.options[i].text = names[i];
			this.orderList.options[i].selected = ss[i];
		}
	
	this.summary();
}
	
function cp_moveUp()
{
	var i, t;
	for (i=0; i<this.orderList.options.length; i++)
		if (!this.orderList.options[i].selected) break;
		
	for (; i<this.orderList.options.length; i++)
		if (this.orderList.options[i].selected)
		{
			t = this.orderList.options[i-1].value;
			this.orderList.options[i-1].value = this.orderList.options[i].value;
			this.orderList.options[i].value = t;
			t = this.orderList.options[i-1].text;
			this.orderList.options[i-1].text = this.orderList.options[i].text;
			this.orderList.options[i].text = t;
			
			this.orderList.options[i-1].selected = true;
			this.orderList.options[i].selected = false;
		}

	this.summary();
}
	
function cp_moveDown()
{
	var i, t;
		
	for (i=this.orderList.options.length-1; i>=0; i--)
		if (!this.orderList.options[i].selected) break;
		
	for (; i>=0; i--)
		if (this.orderList.options[i].selected)
		{
			t = this.orderList.options[i+1].value;
			this.orderList.options[i+1].value = this.orderList.options[i].value;
			this.orderList.options[i].value = t;
			t = this.orderList.options[i+1].text;
			this.orderList.options[i+1].text = this.orderList.options[i].text;
			this.orderList.options[i].text = t;
			
			this.orderList.options[i+1].selected = true;
			this.orderList.options[i].selected = false;
		}

	this.summary();
}

function cp_setSort(b_asc)
{
	//if none is select, quit.
	for (i=0; i<this.orderList.options.length; i++)
		if (this.orderList.options[i].selected)
			break;
		
	if (i >= this.orderList.options.length) return;
	
	if (this.sortMode == "BUTTON")
	{
		//in this mode, clean previous sort field;
		var idx = this.sortList1.selectedIndex;
		this.orderList.options[idx].text = this.sortList1.options[idx].text;
		this.orderList.options[i].text += " (Sorted " + (b_asc ? "Asc" : "Desc") + ")";
		this.orderList.options[i].selected = true;
		this.sortList1.options[i].selected = true;
		this.sortList1.selectedIndex = i;
		this.ascList1.options[b_asc ? 0 : 1].selected = true;
		this.ascList1.selectedIndex = (b_asc ? 0 : 1);
	}
	else		//"BUTTON_SORTALL"
	{
		for (;i<this.orderList.options.length; i++)
			if (this.orderList.options[i].selected)
			{
				//get clean text without "(Sorted xxxx)"
				this.orderList.options[i].text = this.sortList1.options[i].text;
				this.orderList.options[i].text += " (Sorted " + (b_asc ? "Asc" : "Desc") + ")";
				this.orderList.options[i].selected = true;
			}
	}
	
	this.summary();
}

function cp_updateList(chkCtrl, listCtrl)
{
	if (chkCtrl.checked)
		this.addSelectedColumn(listCtrl, chkCtrl.value, chkCtrl.name);
	else
		for (var i=0; i<listCtrl.options.length; i++)
		{
			if (listCtrl.options[i].value == chkCtrl.name)
				listCtrl.options[i] = null;
		}
}

function cp_updateCheckAndList(chkCtrl)
{
	var checkboxes = document.getElementsByName(chkCtrl.name);
	for (var i=0; i<checkboxes.length; i++)
		checkboxes[i].checked = chkCtrl.checked;

	this.updateList(chkCtrl, this.orderList);
	this.summary();
}

function cp_getFieldNameNoSuffix(val)	//"event_name|Man" -> "event_name"
{
	var n = val.indexOf("|");
	if (n >= 0) val = val.substr(0, n);
	return val;
}

function cp_onAdd(b_all)
{
	for (var i=0; i<this.allColumnsList.options.length; i++)
	{
		var op = this.allColumnsList.options[i];
		//check if already in dest list
		var b_contains = false;
		for (var j=0; j<this.orderList.options.length; j++)
			if (cp_getFieldNameNoSuffix(orderList.options[j].value) == op.value)
			{
				b_contains = true;
				break;
			}
		
		//add selected items to the right list if not already there.
		if ( (op.selected || b_all) && !b_contains)
			this.addSelectedColumn(orderList, op.text, op.value);
	}
	this.summary();
}

function cp_onRemove(b_all)
{
	var i = 0, b_hasMan = false;
	while (i<this.orderList.options.length)
	{
		if (this.orderList.options[i].selected || b_all)
		{
			var fname = this.orderList.options[i].value;
			if (fname.indexOf("|Man") < 0)
			{
				this.orderList.options[i] = null;
			}
			else
			{
				b_hasMan = true;
				i++;
			}
		}
		else
			i++;
	}
	
	this.summary();
	if (b_hasMan) alert("Some field(s) cannot be removed.");
}

function cp_onCheckAll(ctrlIdPrefix)
{
	var all_boxes = document.getElementsByTagName("input");
	var b_allChecked = true;
	for (var i=0; i < all_boxes.length; i++)
	{
		if (all_boxes[i].id.substr(0, ctrlIdPrefix.length) == ctrlIdPrefix)
			if (!all_boxes[i].disabled)
				if (!all_boxes[i].checked)
				{
					b_allChecked = false;
					break;
				}
	}

	for (var i=0; i<all_boxes.length; i++)
	{
		if (all_boxes[i].id.substring(0, ctrlIdPrefix.length) == ctrlIdPrefix)
			if (!all_boxes[i].disabled && all_boxes[i].checked != !b_allChecked)
			{
				all_boxes[i].checked = !b_allChecked;
				this.updateCheckAndList(all_boxes[i]);
			}
	}
	
	this.summary();
}

function cp_toggleLayer(show_div_name, hide_div_name)
{
	document.getElementById(show_div_name).style.display = "block";
	document.getElementById(hide_div_name).style.display = "none";
}

var SEARCH_ENUMONLY_SEL	= 0x800;
var SEARCH_SINGLE_SEL	= 0x1000;
var SEARCH_MULTI_SEL	= 0x2000;
var SEARCH_OPER_SUBSET	= 0x8000;
var EX_SEARCH_CONTAINONLY_SEL = 0x100;

function criteriaBuilder(client_id, max_filters)
{
	this.client_id = client_id;
	this.max_filters = max_filters;
	this.fieldCount = 0;
	this.enumCount = 0;
	
	this.flags = new Array();
	this.flagsEx = new Array();
	this.enumStartIndex = new Array();
	this.enumEndIndex = new Array();
	this.enumQueryValues = new Array();
	this.enumDispValues = new Array();
	this.critEditors = new Array();
	
	this.addField = cb_addField;
	this.addEnum	= cb_addEnum;
	this.getFieldInfo = cb_getFieldInfo;
	this.addEditor = cb_addEditor;
	this.addFilter = cb_addFilter;
	this.removeFilter = cb_removeFilter;
}

function cb_addField(flgs, enumStart, enumEnd, flgsEx)
{
	this.flags[this.fieldCount] = flgs;
	this.enumStartIndex[this.fieldCount] = enumStart;
	this.enumEndIndex[this.fieldCount] = enumEnd;
	this.flagsEx[this.fieldCount] = flgsEx;
	this.fieldCount++;
}

function cb_addEnum(queryVal, dispVal)
{
	this.enumQueryValues[this.enumCount] = queryVal;
	this.enumDispValues[this.enumCount] = dispVal;
	this.enumCount++;
}

function cb_addEditor(editor)
{
	this.critEditors[this.critEditors.length] = editor;
}

function cb_addFilter()
{
	var cnt_box = document.getElementById(this.client_id);
	var cnt = parseInt(cnt_box.value);
	if (cnt >= this.max_filters)
	{
		alert("You can add at most " + this.max_filters + " filters.");
		return;
	}
	
	var tr_ctrl = document.getElementById(this.client_id + "_tr_" + cnt_box.value);
	tr_ctrl.style.display = "block";
	cnt_box.value = (cnt + 1);
}

function cb_removeFilter(remove_index)
{
	var cnt_box = document.getElementById(this.client_id);
	var cnt = parseInt(cnt_box.value);
	var i;
	for (i = remove_index; i < cnt - 1; i++)
		cb_copyFilterStatus(this.critEditors[i + 1], this.critEditors[i]);
	
	//reset the last crit and hide its row
	this.critEditors[cnt - 1].fieldList.selectedIndex = -1;
	this.critEditors[cnt - 1].onFieldChange();

	cnt_box.value = (cnt - 1);
	var tr_ctrl = document.getElementById(this.client_id + "_tr_" + cnt_box.value);
	tr_ctrl.style.display = "none";
}

function cb_copyFilterStatus(crit_from, crit_to)
{
	//change selected field and simulate a field change event
	if (crit_from.fieldList.selectedIndex >= 0)
		crit_to.fieldList.options[crit_from.fieldList.selectedIndex].selected = true;
	crit_to.fieldList.selectedIndex = crit_from.fieldList.selectedIndex;
	crit_to.onFieldChange();
	//change selected operator and simulate a operator change event
	if (crit_from.operatorList.selectedIndex >= 0)
		crit_to.operatorList.options[crit_from.operatorList.selectedIndex].selected = true;
	crit_to.operatorList.selectedIndex = crit_from.operatorList.selectedIndex;
	crit_to.onOperatorChange();
	//copy other controls' statuses
	crit_to.opEdit.value = crit_from.opEdit.value;
	crit_to.opEdit.style.display = crit_from.opEdit.style.display;
	crit_to.opEnumList.selectedIndex = crit_from.opEnumList.selectedIndex;
	crit_to.opEnumList.style.display = crit_from.opEnumList.style.display;
	crit_to.calLayer.style.display = crit_from.calLayer.style.display;
	crit_to.useEnum.value = crit_from.useEnum.value;
	crit_to.btwLayer.style.display = crit_from.btwLayer.style.display;
	crit_to.btwOpLow.value = crit_from.btwOpLow.value;
	crit_to.btwOpHigh.value = crit_from.btwOpHigh.value;
	if (crit_from.errSpan != null) crit_from.errSpan.style.display = "none";
	if (crit_to.errSpan != null) crit_to.errSpan.style.display = "none";
	if (crit_from.blnOpAnd != null) crit_to.blnOpAnd.checked = crit_from.blnOpAnd.checked;
	if (crit_from.blnOpOr != null) crit_to.blnOpOr.checked = crit_from.blnOpOr.checked;
}

function cb_getFieldInfo(index, infoToGet)
{
	if (infoToGet == 'IsEnumable')
		return (this.enumStartIndex[index] >= 0);
	else if (infoToGet == 'IsText')
	{
		var fmt = (this.flags[index] & 0x1F); 
		return (fmt==1 || fmt==7 || fmt==11);
	}
	else if (infoToGet == 'IsNumeric')
	{
		var fmt = (this.flags[index] & 0x1F); 
		return (fmt==2 || fmt==4 || fmt==6 || fmt==10);
	}
	else if (infoToGet == 'IsDate')
	{
		var fmt = (this.flags[index] & 0x1F); 
		return (fmt==3 || fmt==8  || fmt==9 || fmt==12);
	}
	else if (infoToGet == 'IsID')
	{
		var fmt = (this.flags[index] & 0x1F); 
		return (fmt==5);
	}
	else if (infoToGet == 'Format')
		return (this.flags[index] & 0x1F);
	else
		alert('unknown request: ' + infoToGet);
}

function criterionEditor(builderObject, unique_id)
{
	this.builder = builderObject;
	this.alphabetLayer = null;
	
	//child controls are named by appending the parent unique_id
	this.fieldList = document.getElementById(unique_id + "_fields");
	this.operatorList = document.getElementById(unique_id + "_operators");
	this.opEdit = document.getElementById(unique_id + "_opText");
	this.opEnumList = document.getElementById(unique_id + "_opEnum");
	this.calLayer = document.getElementById(unique_id + "_calLayer");
	this.useEnum = document.getElementById(unique_id + "_useEnum");
	this.btwLayer = document.getElementById(unique_id + "_btwLayer");
	this.btwOpLow = document.getElementById(unique_id + "_opBtwLow");
	this.btwOpHigh = document.getElementById(unique_id + "_opBtwHigh");
	this.errSpan = document.getElementById(unique_id + "_errMsgSpan");
	this.blnOpAnd = document.getElementById(unique_id + "_blnOp_AND");
	this.blnOpOr = document.getElementById(unique_id + "_blnOp_OR");
	
	this.selectOperatorByValue = ce_selectOperatorByValue;
	this.fillOperatorList = ce_fillOperatorList;
	this.updateCriterion = ce_updateCriterion;
	this.isToShowEnum = ce_isToShowEnum;
	this.showAlphabet = null;
	this.onFieldChange = ce_onFieldChange;
	this.onOperatorChange = ce_onOperatorChange;
	this.setFocus = ce_setFocus;
}

function ce_fillOperatorList()
{
	var i = 0;
	var selIndex = this.fieldList.selectedIndex;
	while (this.operatorList.options.length > 0)	//clear all existing operators
		this.operatorList.options[0] = null;
	
	if (selIndex == -1) return;
	
	var flags = this.builder.flags[selIndex];
	var flagsEx = this.builder.flagsEx[selIndex];
	if (this.builder.getFieldInfo(selIndex, "IsText"))
	{
		if (flags & SEARCH_ENUMONLY_SEL)
		{
			this.operatorList.options[i++] = new Option("Equals", "EQ");
			return;	//only show one operator if enumonly
		}
		else if (flags & SEARCH_SINGLE_SEL)
		{
			this.operatorList.options[i++] = new Option("Equals", "EQ");
			this.operatorList.options[i++] = new Option("Not Equal", "NEQ");
			this.operatorList.options[i++] = new Option("Is One Of", "IN");
			this.operatorList.options[i++] = new Option("Not One Of", "NIN");
		}
		else if (flags & SEARCH_MULTI_SEL)
		{
			this.operatorList.options[i++] = new Option("Contains Any Of", "CONANY");
			this.operatorList.options[i++] = new Option("Contains All Of", "CONALL");
		}
		else
		{
			if (flagsEx & EX_SEARCH_CONTAINONLY_SEL)
			{
				this.operatorList.options[i++] = new Option("Starts With", "SW");
				this.operatorList.options[i++] = new Option("Contains", "CON");
				this.operatorList.options[i++] = new Option("Not Contain", "NCON");
				this.operatorList.options[i++] = new Option("Contains Any Of", "CONANY");
				this.operatorList.options[i++] = new Option("Contains All Of", "CONALL");
			}
			else if (flags & SEARCH_OPER_SUBSET)
			{
				this.operatorList.options[i++] = new Option("Starts With", "SW");
				this.operatorList.options[i++] = new Option("Equals", "EQ");
				this.operatorList.options[i++] = new Option("Contains", "CON");
				this.operatorList.options[i++] = new Option("Not Contain", "NCON");
				this.operatorList.options[i++] = new Option("Contains Any Of", "CONANY");
				this.operatorList.options[i++] = new Option("Contains All Of", "CONALL");
			}
			else
			{
				this.operatorList.options[i++] = new Option("Starts With", "SW");
				this.operatorList.options[i++] = new Option("Equals", "EQ");
				this.operatorList.options[i++] = new Option("Not Equal", "NEQ");
				this.operatorList.options[i++] = new Option("Contains", "CON");
				this.operatorList.options[i++] = new Option("Not Contain", "NCON");
				this.operatorList.options[i++] = new Option("Contains Any Of", "CONANY");
				this.operatorList.options[i++] = new Option("Contains All Of", "CONALL");
				this.operatorList.options[i++] = new Option("Is One Of", "IN");
				this.operatorList.options[i++] = new Option("Not One Of", "NIN");
			}
		}
	}
	else if (this.builder.getFieldInfo(selIndex, "IsID"))
	{
		if (flags & SEARCH_ENUMONLY_SEL)
		{
			this.operatorList.options[i++] = new Option("Equals", "EQ");
			return;	//only show one operator if enumonly
		}
		else
		{
			this.operatorList.options[i++] = new Option("=", "EQ");
			this.operatorList.options[i++] = new Option("<>", "NEQ");
			this.operatorList.options[i++] = new Option("Is One Of", "IN");
			this.operatorList.options[i++] = new Option("Not One Of", "NIN");
		}
	}
	else //date or numeric
	{
		this.operatorList.options[i++] = new Option("=", "EQ");
		this.operatorList.options[i++] = new Option(">", "GT");
		this.operatorList.options[i++] = new Option("<", "LT");
		this.operatorList.options[i++] = new Option(">=", "NLT");
		this.operatorList.options[i++] = new Option("<=", "NGT");
		if (this.builder.getFieldInfo(selIndex, "IsNumeric"))
			this.operatorList.options[i++] = new Option("<>", "NEQ");
		this.operatorList.options[i++] = new Option("Between", "BTW");
	}	
}

function ce_selectOperatorByValue(val)
{
	for (var i=0; i < this.operatorList.options.length; i++)
		if (this.operatorList.options[i].value == val)
		{
			this.operatorList.options[i].selected = true;
			this.operatorList.selectedIndex = i;	//netscape can't update automatically
		}
}

function ce_isToShowEnum(b_operatorChanged)
{
	//if the selected column is enumerable, then use dropdown list, but only when user
	//	changed field (not operator), or changed operator to 'The Listed'.
	var oper = '';
	if (this.operatorList.selectedIndex >= 0)
		oper = this.operatorList.options[this.operatorList.selectedIndex].value;
	return this.builder.getFieldInfo(this.fieldList.selectedIndex, "IsEnumable") && 
			(oper=='EQ' || oper=='NEQ');
}
	
function ce_updateCriterion(b_operatorChanged)
{
	var selIndex = this.fieldList.selectedIndex;

	if (selIndex == -1)
	{
		//if undefined, show empty editbox and reset controls.
		this.fillOperatorList();
		this.operatorList.selectedIndex = -1;
		this.opEdit.value = "";
		this.opEdit.style.display = "block";
		this.opEnumList.style.display = "none";
		this.calLayer.style.display = "none";
		this.btwLayer.style.display = "none";
		this.useEnum.value = "0";
	}
	else
	{
		if (!b_operatorChanged)
		{
			//if op not changed, fill in ops depending on txt/non-txt, with "Select From ->" op
			this.fillOperatorList();
			this.operatorList.options[0].selected = true;		//"Select From ->" is the first one.
			this.operatorList.selectedIndex = 0;				//netscape can't update automatically
		}
		
		if (this.isToShowEnum(b_operatorChanged))
		{
			while (this.opEnumList.options.length > 0)	//remove all enum values
			{
				this.opEnumList.selectedIndex = 0;	//netscape is too stupid to reset selectedIndex
				this.opEnumList.options[0] = null;
			}
			//add enum values for the selected field
			var startIdx = this.builder.enumStartIndex[selIndex];
			var endIdx = this.builder.enumEndIndex[selIndex];
			var selItem = -1;
			for (var i=startIdx; i <= endIdx; i++)
			{
				//add all enumerable to the dropdown, select the selected when encountered.
				this.opEnumList.options[i-startIdx] = new Option(this.builder.enumDispValues[i], this.builder.enumQueryValues[i]);
				//if the input box's value happens to be one of the enums, choose the enum item
				if (this.opEdit.value.toUpperCase() == this.builder.enumQueryValues[i].toUpperCase())
					selItem = i - startIdx;
			}
			this.opEnumList.selectedIndex = selItem;
			
			//tell asp to use enum, not editbox			
			this.useEnum.value = "1";
			this.opEdit.style.display = "none";
			this.opEnumList.style.display = "block";	//show enum layer
			this.calLayer.style.display = "none";
			this.btwLayer.style.display = "none";

			if (this.alphabetLayer != null)
				this.alphabetLayer.style.display = "none";
		}
		else
		{
			//tell asp not to use enum, use editbox			
			this.useEnum.value = "0";
			
			var op = this.operatorList.options[this.operatorList.selectedIndex].value;
			var bShow;
			if (op == "BTW")
			{
				this.opEdit.style.display = "none";		//show input box
				this.opEnumList.style.display = "none";
				this.btwLayer.style.display = "block";
				this.calLayer.style.display = "none";
				bShow = false;
			}
			else
			{
				this.opEdit.style.display = "block";		//show input box
				this.opEnumList.style.display = "none";
				this.btwLayer.style.display = "none";
				if (this.builder.getFieldInfo(selIndex, "IsDate"))		//show calendar icon if the type is date
					this.calLayer.style.display = "block";
				else
					this.calLayer.style.display = "none";
					
				bShow = (this.builder.getFieldInfo(selIndex, "IsText") && (op=="SW" || op=="GT" || op=="LT"));
			}
			
			if (this.alphabetLayer != null)
				this.alphabetLayer.style.display = bShow ? "block" : "none";
		}
	}
}

function ce_onFieldChange()
{
	var selIndex = this.fieldList.selectedIndex;

	//show prompt per data type
	switch(this.builder.getFieldInfo(selIndex, "Format"))
	{
		case 3:	this.opEdit.value = "mm/dd/yyyy"; break;
		default: this.opEdit.value = ""; break;
	}
				
	this.updateCriterion(false);
	//during initialization, cannot set focus in that the criterion layer can be invisible altogether. must set focus onxxxchange
	this.setFocus(false);
	
	if (this.errSpan != null)
		this.errSpan.style.display = "none";
}

function ce_onOperatorChange()
{
	this.updateCriterion(true);
	
	//show prompt per data type
	if (this.operatorList.selectedIndex >= 0)
	{
		switch(this.operatorList.options[this.operatorList.selectedIndex].value)
		{
			case 'CONALL':
			case 'CONANY':
			case 'IN':
			case 'NIN':
				this.opEdit.value = "comma delimited list";
				this.opEdit.select();
				break;
			default:
				this.opEdit.value = "";
				break;
		}
	}
				
	//during initialization, cannot set focus in that the criterion layer can be invisible altogether. must set focus onxxxchange
	this.setFocus(true);
	
	if (this.errSpan != null)
		this.errSpan.style.display = "none";
}

function ce_setFocus(b_operatorChanged)
{
	//if it's not enum, set focus to operant edit
	if (this.fieldList.selectedIndex >= 0 && 
			!this.isToShowEnum(b_operatorChanged))
	{
		if (this.operatorList.options[this.operatorList.selectedIndex].value == "BTW")
		{
			this.btwOpLow.select();
			this.btwOpLow.focus();
		}
		else
		{
			this.opEdit.select();
			this.opEdit.focus();
		}
	}	
}

function ce_clear()
{
	this.fieldList.selectedIndex = -1;
	this.opEnumList.selectedIndex = -1;
	this.opEdit.value = "";
	this.useEnum.value = "";
}

//For ToolBar Button DropDown Menu
var MOL=new Array();

function MenuObj(_A,_B,_C,_D,_E,_F,_G,_H,_I){
this.name=_A;
this.bOn=_E;
this.bOf=_F;
this.bA=_G;
this.SBS=SBS;
this.showing=false;
this.TM=TM;
document.onclick=MCH;
this.Direction=_I;
MOL[MOL.length]=this;

this.divObj=_B;
this.get_divObj = function()
	{
		return document.getElementById(this.divObj);
	}

this.get_divStyleObj = function() { return this.get_divObj().style; }

this.refTDObj=_C;
this.get_refTDObj = function()
	{
		return document.getElementById(this.refTDObj);
	}

this.DdTDObj=_D;
this.get_DdTDObj = function()
	{
		var elem;
		if (_D) elem = document.getElementById(this.DdTDObj);
		return elem;
	}

this.frmObj=_H;
this.get_frmObj = function()
	{
		return document.getElementById(this.frmObj);
	}

this.strShow='visible';
this.strHide='hidden';
}

//Reference Object pointer
function ROP(ObjRef){
	var theObj=null;
	if (ObjRef){
		if (typeof ObjRef != 'object') theObj=eval(ObjRef);
		else theObj=ObjRef;
		return theObj;
	}
	else
		return false;
}
function TM(){
	if (!this.showing){
		var RelObjCords=getXY(this.get_refTDObj());
		if (this.Direction){
			this.get_divStyleObj().top = RelObjCords.top + -this.get_divObj().offsetHeight;
			this.get_divStyleObj().left = RelObjCords.left;
		}
		else{
			this.get_divStyleObj().top = RelObjCords.top + 18;
			this.get_divStyleObj().left = RelObjCords.left;
		}
		var pCurrMenuObj=ROP(this);
		CM(this);
		this.SBS('clicked');
		this.get_divStyleObj().visibility = this.strShow;
		this.showing=true;
	}
	else{
		this.get_divStyleObj().visibility = this.strHide;
		this.showing=false;
		this.SBS();
	}
}
function CM(callerObj){
	for (aIndex=0;aIndex < MOL.length; aIndex++){
		if ((callerObj) && (callerObj.name != MOL[aIndex].name)){
			if (MOL[aIndex].showing){
				MOL[aIndex].TM();
				MOL[aIndex].SBS();
			}
		}
		else{
			if (MOL[aIndex].showing){
				MOL[aIndex].TM();
				MOL[aIndex].SBS();
			}
		}
	}
}
function MCH(e, srcObj, srcIsMenuDiv){
	var srcElem;
	if (!e) var e=window.event;
	e.cancelBubble=true;
	if (srcObj){
		var pCurrMenuObj=ROP(srcObj);
		if (!srcIsMenuDiv) pCurrMenuObj.get_divObj().onclick="MCH(event,"+srcObj+",true)";
		pCurrMenuObj.TM();
	}
	else CM();
}
function MME(e, srcObj){
	if (!e) var e=window.event;
	var pCurrMenuObj=ROP(srcObj);
	if (!pCurrMenuObj.showing){
		if (e.type == 'mouseover') pCurrMenuObj.SBS('on');
		else if ((e.type == 'mouseout') || (e.type == 'blur')) pCurrMenuObj.SBS();
	}
}
function SBS(wS){
	if (typeof this.get_refTDObj() != "undefined"){
		if (wS == 'on'){
			if (this.bOn){
				if (typeof this.get_DdTDObj() != "undefined") this.get_DdTDObj().className=this.bOn;
				this.get_refTDObj().className=this.bOn;
			}
		}
		else if (wS == 'clicked'){
			if (this.bA){
				if (typeof this.get_DdTDObj() != "undefined") this.get_DdTDObj().className=this.bA;
				this.get_refTDObj().className=this.bA;
			}
		}
		else{
			if (this.bOf){
				if (typeof this.get_DdTDObj() != "undefined") this.get_DdTDObj().className=this.bOf;
				this.get_refTDObj().className=this.bOf;
			}
		}
	}
}
function getXY(Obj){
for (var sumTop=0,sumLeft=0;Obj!=document.body;sumTop+=Obj.offsetTop,sumLeft+=Obj.offsetLeft, Obj=Obj.offsetParent);
return {left:sumLeft,top:sumTop}
}
//End (For ToolBar Button DropDown Menu)

function treeviewNode()
{
	this.tr = null;
	this.expanded = null;
	this.checked = null;
	this.checkboxValue = null;
}

function treeviewClient(idprefix)
{
	this.initTRs = false;
	this.idPrefix = idprefix;
	this.rowidPrefix = idprefix + "_r";
	this.nodes = new Array();
	this.nodesChildren = new Array();
	
	this.add = tv_add;
	this.onExpandIconClick = tv_onExpandIconClick;
	this.onCheckBoxClick = tv_onCheckBoxClick;
	this.hideChildNodes = tv_hideChildNodes;
	this.showChildNodes = tv_showChildNodes;
	this.onSubmit = tv_onSubmit;
}

function tv_add(expanded, checked, value)
{
	var nd = new treeviewNode();
	nd.expanded = (expanded > 0);
	nd.checked = (checked > 0);
	nd.checkboxValue = value;
	this.nodes[this.nodes.length] = nd;
}

function tv_onExpandIconClick(nodeIndex, plusIconID, minueIconID)
{
	if (!this.initTRs)
	{
		for (var i = 0; i < this.nodes.length; i++)
			this.nodes[i].tr = document.getElementById(this.rowidPrefix + i);
		this.initTRs = true;
	}
	
	var nd = this.nodes[nodeIndex];
	if (nd.expanded)
		this.hideChildNodes(nodeIndex); //to collapse
	else
		this.showChildNodes(nodeIndex); //to expand
		
	nd.expanded = !nd.expanded;
	document.getElementById(plusIconID).style.display = (nd.expanded ? "none" : "inline");
	document.getElementById(minueIconID).style.display = (nd.expanded ? "inline" : "none");
}

function tv_onCheckBoxClick(nodeIndex)
{
	this.nodes[nodeIndex].checked = !this.nodes[nodeIndex].checked;
}

function tv_hideChildNodes(index)
{
	if (this.nodesChildren[index] != null)
	{
		var chrn = this.nodesChildren[index];
		for (var i = 0; i < chrn.length; i++)
		{
			var nd = this.nodes[chrn[i]];
			nd.tr.style.display = "none";
			if (nd.expanded) this.hideChildNodes(chrn[i]);
		}
	}
}

function tv_showChildNodes(index)
{
	if (this.nodesChildren[index] != null)
	{
		var chrn = this.nodesChildren[index];
		for (var i = 0; i < chrn.length; i++)
		{
			var nd = this.nodes[chrn[i]];
			nd.tr.style.display = "block";
			if (nd.expanded) this.showChildNodes(chrn[i]);
		}
	}
}

function tv_onSubmit()
{
	var state = "", checkValues = "";
	for (var i = 0; i < this.nodes.length; i++)
	{
		var nd = this.nodes[i];
		state += (state != "" ? ";" : "") + (nd.expanded ? "1," : "0,");
		state += (nd.checked ? "1," : "0,") + nd.checkboxValue;
		if (nd.checked)
		{
			checkValues += (checkValues != "" ? "," : "");
			checkValues += nd.checkboxValue;
		}
	}

	var stateField = document.getElementById(this.idPrefix + "_tvstate");
	if (this.nodes.length > 0)
		stateField.value = checkValues + ";" + state;		//two parts
	else
		stateField.value = "";
}
