// constants
var ntCData = 4;

// global flag
var isIE = (navigator.appName == "Microsoft Internet Explorer" && navigator.appVersion >= "4.0");

// global vars
var registerfrom = "";
var registersubject = "";
var registerbody = "";
// Parameters for forgot password email
var forgotfrom = "";
var forgotsubject = "";
var forgotbody = "";
//  Parameters for reset password email
var resetfrom = "";
var resetsubject = "";
var resetbody = "";
// location of TeamWeb
var XML_Handler = "/ServiceDesk/TeamServiceDesk.dll";
var sdentry = "/sdesk.xml"
var sdattach = "/sdeskattachfile.xml"
var loginpath = "./default.htm";
// ID of service deskTeamWeb
var havedeskid = false;
var deskid = "";
// field label for ticket number
var ticketfield = "*TicketNo";
// unable to connect bailout message
var bailout = "";
var supportsite = "";
 
// global request and XML document objects
var req;
var XMLresulthandler;
var XMLerrorhandler;
var debug = false;
var ingorewarnings = true;
var currespnode;

// enums
var TSDErrorType = {
      tsdNoError:"0",
      tsdInfo:"1",
      tsdWarning:"2",
      tsdError:"3",
      tsdLogoutError:"4",
      tsdAPIError:"5",
    tsdAssertError:"6"};

// string extensions
    
String.prototype.sameText = function(other) {
    return (this.toLowerCase() == other.toLowerCase());
}

String.prototype.sameStart = function(other) {
    return (this.toLowerCase().indexOf(other.toLowerCase()) == 0);
}

// retrieve text of an XML document element, including
// elements using namespaces
function getElementTextNS(prefix, local, parentElem, index) {
    var result = "";
    if (prefix && isIE) {
        // IE/Windows way of handling namespaces
        result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
    } else {
        // the namespace versions of this method
        // (getElementsByTagNameNS()) operate
        // differently in Safari and Mozilla, but both
        // return value with just local name, provided
        // there aren't conflicts with non-namespace element
        // names
        result = parentElem.getElementsByTagName(local)[index];
    }
    if (result) {
        // get text, accounting for possible
        // whitespace (carriage return) text nodes
        if (result.childNodes.length > 1) {
            return result.childNodes[1].nodeValue;
        } else if (result.childNodes.length == 1) {
            return result.firstChild.nodeValue;
        } else {
        	return "";
        }
    } else {
        return "n/a";
    }
}

function getElementText(Elem) {
    if (Elem) {
        // get text, accounting for possible
        // whitespace (carriage return) text nodes
        if (Elem.childNodes.length > 1) {
            return Elem.childNodes[1].nodeValue;
        } else if (Elem.childNodes.length == 1) {
            return Elem.firstChild.nodeValue;
        } else {
        	return "";
        }
    } else {
        return "n/a";
    }
}

// add random argument

function addRandom(url) {
    // create unique URL to avoid caching by adding unique parameter
    return url + ((url.indexOf("?") >= 0) ? "&": "?") + "unique=" + getRandom();
}

function getRandom() {
    v = new Date();
    d = Date.UTC(v.getFullYear(), v.getMonth(), v.getDate(), v.getHours(), 
        v.getMinutes(), v.getSeconds(), v.getMilliseconds());
    return Math.ceil(Math.random() * 10000) + d;
}

// retrieve XML document (reusable generic function);
// parameter is URL string (relative or complete) to
// an .xml file whose Content-Type is a valid XML
// type, such as text/xml; XML source must be from
// same domain as HTML file
function loadXMLDoc(url, async, thisresulthandler, senddata, thiserrorhandler) {
    XMLresulthandler = thisresulthandler;
    XMLerrorhandler = thiserrorhandler;
    // create unique URL to avoid caching by adding unique parameter
    newurl = addRandom(url);
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        if (async) {
            req.onreadystatechange = processReqChange;
        }
        req.open("POST", newurl, async);
        req.send(senddata);
        if (!async) {
            processReqChange();
        }
        // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("POST", newurl, async);
            if (senddata == null) {
                req.send();
            } else {
                req.send(senddata);
            }
        }
    }
}

// handle onreadystatechange event of req object
function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            XMLresulthandler();
        } else {
            alert("There was a problem retrieving the XML data:\n" + req.statusText);
            if (XMLerrorhandler) {
            	XMLerrorhandler("There was a problem retrieving the XML data:\n" + req.statusText);
            }
        }
    }
}

// Validate E-mail Address
function isEmailAddress(string) {
	if (string == "undefined")
		return false;
    var addressPattern = /^[A-Za-z0-9_&]+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
    return addressPattern.test(string);
}

function validate(pwc) {

    if (!isEmailAddress(pwc.value)) {
        alert("Please enter a valid email address.");
        pwc.focus();
        return (false);
    }
    if (pwc.value != "") {
        var emailAddrs = pwc.value;
        var lastPeriod = emailAddrs.lastIndexOf(".");
        var endPart = emailAddrs.substring(lastPeriod + 1, emailAddrs.length);
        if (endPart.length < 2) {
            alert("Please enter a valid email address.");
            pwc.focus();
            return (false);
        }
    }
    return (true);
}

// get query string value

function querySt(ji) {
    try {
        hu = window.location.search.substring(1);
        gy = hu.split("&");
        for (i = 0; i < gy.length; i++) {
            ft = gy[i].split("=");
            if (ft[0] == ji) {
                return ft[1];
            }
        }
    } catch(e) {
        var msg = (typeof e == "string") ? e: ((e.message) ? e.message: "Unknown Error");
        return ("Unable argument:\n" + msg);
    }
}

// make currency

function toCurrency(y) {
    max_length = 12; //max_length= length of text input
    spacing = "$               ";
    x = Math.floor(y);
    xx = y - x;
    xx = xx + "00.00" //xx=the cents only (with zeroes).
    a = xx.indexOf(".");
    q = x + xx.substring(a, a + 3);
    ql = (q.length < max_length) ? (max_length - q.length) : 0;
    r = (y) ? spacing.substring(0, ql) + q: "";
    return (r);
}

// Build XML Tools

var RequestRoot;
var RequestObject;
var r_node;

// create XML document with default header and primary node
function initRequest() {
    var text = '<?xml version="1.0" encoding="utf-8" ?> <root/>';
    try //Internet Explorer
    {
        RequestObject=new ActiveXObject("Microsoft.XMLDOM");
        RequestObject.async="false";
        RequestObject.loadXML(text);
    }
    catch(e)
    {
        try //Firefox, Mozilla, Opera, etc.
        {
            parser=new DOMParser();
            RequestObject=parser.parseFromString(text,"text/xml");
        }
        catch(e) {
            alert(e.message);
        }
    }
    //RequestObject = new ActiveXObject("MSXML2.DOMDocument");
    //RequestObject.loadXML('<?xml version="1.0" encoding="utf-8" ?> <root/>');
    RequestRoot = RequestObject.documentElement;
    return true;
}

// create a node and add it
function newRequestNode(parent, nodename) {
    var w_node = RequestObject.createElement(nodename);
    parent.appendChild(w_node);
    return w_node;
}

// create a value node and add it
function newRequestValueNode(parent, nodename, nodevalue) {
    var w_node = RequestObject.createElement(nodename);
    var t_node = RequestObject.createTextNode(nodevalue);
    parent.appendChild(w_node);
    w_node.appendChild(t_node);
    return w_node;
}

// create a CDATA node and add it
function newRequestCDATANode(parent, nodename, nodevalue) {
    var w_node = RequestObject.createElement(nodename);
    var newnv = ("" + nodevalue).replace(/%/gi, "&#37;").replace(/]]>/gi, "%0x5d%0x5d>");
    var cdatasec = RequestObject.createCDATASection(newnv);
    parent.appendChild(w_node);
    w_node.appendChild(cdatasec);
    return w_node;
}

// create a column for a field from an input
function makeColumnField(fname, ffname) {
    // create a column node
    var c_node = newRequestNode(r_node, "col");

    // create a fieldlabel node and set content
    newRequestCDATANode(c_node, "field", fname);

    // create a value node and set content
    var str;
    if (document.getElementById(ffname)) {
	    if (document.getElementById(ffname).className == "checkbox") {
	    	str = (document.getElementById(ffname).checked) ? "1" : "0";
	    } else {
	    	str = (document.getElementById(ffname).value) ? document.getElementById(ffname).value : "";
	    }
	} else {
		str = "";
	}
	
    newRequestCDATANode(c_node, "value", str);
}

// create a column for a new note from an textarea
function makeColumnNewNote(ffname) {
    // create an addnode and set content
    var str = (document.getElementById(ffname).value) ? document.getElementById(ffname).value.replace(/]]>/gi, "%0x5d%0x5d>") : "";
    newRequestCDATANode(r_node, "addnote", str);
}

// create a column for a field
function makeColumnFieldRO(fname, subfield) {
    // create a column node
    var c_node = newRequestNode(r_node, "col");

    // create a field node and set content
    if (!subfield) {
    	newRequestCDATANode(c_node, "field", fname);
    } else {
        newRequestCDATANode(c_node, "field", fname + ":" + subfield);
    }
    return c_node;
}

// Add a sort

function addSort(parent, fname, sort) {
    var s_node = RequestObject.createElement("sort");
    parent.appendChild(s_node);
    // add field
    newRequestCDATANode(s_node, "field", fname);
    // add order if not ASC
    if (sort != 'ASC') {
    	w_node = RequestObject.createElement("order");
    	var t_node = RequestObject.createTextNode(sort);
    	s_node.appendChild(w_node);
    	w_node.appendChild(t_node);
	}
    return s_node;
}

// Add a lookup sort

function addLookupSort(parent, sort) {
    newRequestValueNode(parent, "sort", sort);
}

// Add a distinct

function addDistinct(parent, sort) {
    newRequestValueNode(parent, "distinct", '1');
}

// adjust domain
function adjustDomain(target) {
	var path = "" + document.location.pathname;
	var loc = "" + document.location;
	var i = loc.indexOf(path);
	if (i >= 0) {
		return loc.substr(0,i) + target;	
	} else { 
		alert("Unable to determine domain from " + loc);
		return target;
	}
}

// submit form
function submitRequest(handler, errorhandler) {
    try {
    	var URL = adjustDomain(XML_Handler + sdentry);
        loadXMLDoc(URL, true, handler, RequestObject, errorhandler);
        return true;
    } catch(e) {
        var msg = (typeof e == "string") ? e: ((e.message) ? e.message: "Unknown Error");
        alert("Unable to contact server:\n" + msg);
    }
    return (false);
}

// browser compatible insert
function InsertThing(thing, parent) {
    if (!isIE) {
        var nr = document.createElement(thing);
        parent.appendChild(nr);
        return nr;
    } else {
        if (thing == "tr") {
            return parent.insertRow();
        } else {
            return parent.insertCell();
        }
    }
}

// browser compatible clear table
function RemoveAllRows(parent) {
    if (!isIE) {
        try {
            for (var i = 0;  ; i++) {
                parent.removeChild(parent.firstChild);
            }
        } catch(E) {
        }
    } else {
        while (parent.rows.length != 0) {
            parent.deleteRow();
        }
    }
}


// process a returned value

function processValue(respnode) {
	if (respnode) {
    	return restoreNLOK(unescape(getElementTextNS("", "value", respnode, 0)));
    } else {
    	return "";
    }
}

// process a returned table

function processTable(tablenode) {
    var headersec = tablenode.getElementsByTagName("header");
    var columns;
    var tbl = new Object();
    tbl.headerblocks = new Array();
    if (headersec.length == 1) {
        columns = headersec[0].childNodes;
        if (columns.length > 0) {
            for (var j = 0; j < columns.length; j++) {
            	tbl.headerblocks[j] = new Object();
                tbl.headerblocks[j].fieldlabel = restore(unescape(getElementTextNS("", "fieldlabel", columns[j], 0)));
                tbl.headerblocks[j].field = getElementTextNS("", "field", columns[j], 0);
                tbl.headerblocks[j].datatype = getElementTextNS("", "type", columns[j], 0);
            }
        }
    	var rowsec = tablenode.getElementsByTagName("row");
    	if (rowsec.length > 0) {
    		tbl.rows = new Array();
        	for (var j = 0; j < rowsec.length; j++) {
        		tbl.rows[j] = new Array();
            	columns = rowsec[j].childNodes;
            	if (columns.length > 0) {
    			    tbl.rows[j].values = new Array();
                	for (i = 0; i < columns.length; i++) {
                      	tbl.rows[j].values[i] = restore(unescape(getElementText(columns[i])));
                    }
                }
            }
        }
    }
	if (debug) {
		var s = '';
		for (var j = 0; j < tbl.headerblocks.length; j++) {
			s += "Column(" + j + "): " + tbl.headerblocks[j].fieldlabel + 
			  " (" + tbl.headerblocks[j].field + "-" +
			  tbl.headerblocks[j].datatype + ")\n";
			if (tbl.rows) {
				for (var i = 0; i < tbl.rows.length; i++) {
					s += "  Value: " + tbl.rows[i].values[j] + "\n"; 
				}
			}
		}
		alert(s);
	}
    return tbl;
}

// restore strings

function restorenote(str) {
	var s =	str.replace(/  /gi, "&nbsp;&nbsp;").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/\n/gi, "<br />").replace(/%0x5d%0x5d&gt;/gi, "]]&gt;");
	var np = '"' + adjustDomain(XML_Handler + "/attachment/");
 	s = s.replace(/"attachment\//gi, np);
	return s; 
}

function restore(str) {
	return str.replace(/  /gi, "&nbsp;&nbsp;").replace(/</gi, "&lt;").replace(/>/gi, "&gt;").replace(/\n/gi, "<br />").replace(/%0x5d%0x5d&gt;/gi, "]]&gt;");
}

function restoreNLOK(str) {
	return str.replace(/  /gi, "&nbsp;&nbsp;").replace(/</gi, "&lt;").replace(/>/gi, "&gt;").replace(/%0x5d%0x5d&gt;/gi, "]]&gt;");
}

// filter output options

function valueoutput() {
    var w_node = RequestObject.createElement('value');
    var t_node = RequestObject.createTextNode("yak");
    w_node.appendChild(t_node);
    return w_node;
}

function seloptionsoutputField(valuefield,displayfield) {
    var w_node = RequestObject.createElement('seloptions');
    if (valuefield) {
    	var v_node = RequestObject.createElement('value');
        newRequestCDATANode(v_node, 'field', valuefield);
        w_node.appendChild(v_node);
   }
    if (displayfield) {
    	var d_node = RequestObject.createElement('display');
        newRequestCDATANode(d_node, 'field', displayfield);
        w_node.appendChild(d_node);
    }
    return w_node;
}

function tableoutputFields(fields) {
	var t_node;
	if (fields.length) {
		t_node = RequestObject.createElement("table");
		for (var i = 0; i < fields.length; i++) {
       		var c_node = RequestObject.createElement("col");
       		newRequestCDATANode(c_node, "field", fields[i]);
       		t_node.appendChild(c_node);
		}
	}
    return t_node;
}

// create a list filter

function makeValueListFilterFromField(parent, field, valuelist, matchnot, matchcomplete, matchcase) {
	if (valuelist) {
		var fnode = newRequestNode(parent, "filter");
        newRequestCDATANode(fnode, 'field', field);
		for (var i = 0; i < valuelist.length; i++) {
	    	var str = valuelist[i].replace(/]]>/gi, "%0x5d%0x5d>");
	    	newRequestCDATANode(fnode, "value", str);
		}
		if (matchnot) {
			newRequestValueNode(fnode, "matchnot", "1");
		}	
		if (matchcomplete) {
			newRequestValueNode(fnode, "matchcomplete", "1");
		}	
		if (matchcase) {
			newRequestValueNode(fnode, "matchcase", "1");
		}
		return fnode;	
	}
	return null;	
}

// create a range filter

function makeRangeFilterFromField(parent, field, startvalue, endvalue, excludestart, excludeend, 
  matchnot, matchcomplete, matchcase) {
	if (startvalue || endvalue) {
		var fnode = newRequestNode(parent, "filter");
        newRequestCDATANode(fnode, 'field', field);
		if (startvalue) {
			newRequestCDATANode(fnode, "rangestart", startvalue);
		}	
		if (endvalue) {
			newRequestCDATANode(fnode, "rangeend", endvalue);
		}	
		if (excludestart) {
			newRequestValueNode(fnode, "excludestart", "1");
		}	
		if (excludeend) {
			newRequestValueNode(fnode, "excludeend", "1");
		}	
		if (matchnot) {
			newRequestValueNode(fnode, "matchnot", "1");
		}	
		if (matchcomplete) {
			newRequestValueNode(fnode, "matchcomplete", "1");
		}	
		if (matchcase) {
			newRequestValueNode(fnode, "matchcase", "1");
		}
		return fnode;	
	}
	return null;	
}

// get attachment data

function getAttachmentData(respnode) {
	var attachnodes = respnode.getElementsByTagName("attachsettings");
	var attachnode = attachnodes[0];
	var o = null;
	if (attachnode) {
		o = new Object();
		o.message = getElementTextNS("","message",attachnode,0);
		o.blocked = (getElementTextNS("","blocked",attachnode,0) == "1");
		o.enabled = (getElementTextNS("","enabled",attachnode,0) == "1");
		o.maxkb = getElementTextNS("","maxkb",attachnode,0);
		var extnodes = attachnode.getElementsByTagName("ext");
		o.ext = new Array();
		if (extnodes) {
			for (var i = 0; i < extnodes.length; i++) {
				o.ext[i] = getElementTextNS("","ext",attachnode,i);
			}
		}
	}
	return o;
}

// get attachment data

function getAttachmentList() {
	var root = req.responseXML.documentElement;
	var attachments = root.getElementsByTagName("attachment");
	var o = null;
	if (attachments) {
		o = new Object();
		o.attachments = new Array();
		for (var i = 0; i < attachments.length; i++) {
			o.attachments[i] = new Object();
			o.attachments[i].fileName = getElementTextNS("","shortname",attachments[i],0);
			o.attachments[i].size = getElementTextNS("","sizedisplay",attachments[i],0);
			o.attachments[i].attDate = TimeStampToDate(getElementTextNS("","date",attachments[i],0));
			o.attachments[i].href = getElementTextNS("","href",attachments[i],0);
		}
		if (debug) {
			s = "";
			for (var i = 0; i < o.attachments.length; i++) {
				s += "Attachment("+i+"):\n" +
				"Filename: "+o.attachments[i].fileName+"\n" +
				"Size: "+o.attachments[i].size+"\n" +
				"Date: "+o.attachments[i].attDate+"\n" +
				"HREF: "+o.attachments[i].href+"\n";
			}			
			alert(s);
		}
	}	
	return o;
}

function TimeStampToDate(xmlDate)
{
    var dt = new Date();
    var dtS;
    if (xmlDate.indexOf('.') >= 0) {
   		dtS = xmlDate.slice(xmlDate.indexOf('T')+1, xmlDate.indexOf('.'));
	} else {
   		dtS = xmlDate.substr(xmlDate.indexOf('T')+1);
	}
    var TimeArray = dtS.split(":");
    dt.setHours(TimeArray[0],TimeArray[1],TimeArray[2]);
    dtS = xmlDate.slice(0, xmlDate.indexOf('T'))
    TimeArray = dtS.split("-");
    dt.setFullYear(TimeArray[0],TimeArray[1]-1,TimeArray[2]);
    return dt;
}

function getNodeName(nn) {
	if (isIE) {
		return nn.toUpperCase();
	} else {
		return nn;
	}
}

// error message handler

function handleError(errrespnode) {
	var ret = 0;
	if (errrespnode) {
	    var errorsec = errrespnode.getElementsByTagName("error");
		if (errorsec.length > 0) {
		    var errortype = getnodetext(findnodeunder(errrespnode, "errortype"));
		    if (errortype && errortype == TSDErrorType.tsdWarning && ingorewarnings) {
		    	return ret;
		    }
		    ret = 2;
		    var errorxdomain = 'Exception in cross-domain transfer';
		    var errortext = getnodetext(findnodeunder(errrespnode, "error"));
		    if (errorxdomain.sameText(errortext)) {
			    var finalmess = errortext + 
			        "\n\n" + getnodetext(findnodeunder(errrespnode, "message")) +
			        "\n\nPlease try our support site";
			    alert(finalmess);
				window.open(supportsite, "_self");
		    } else {
		        var finalmess = getnodetext(findnodeunder(errrespnode, "error")) + 
		            "\n\n" + getnodetext(findnodeunder(errrespnode, "message"))
		        alert(finalmess);
			}
		    if (errortype && errortype == TSDErrorType.tsdLogoutError) {
		    	window.open(loginpath + "?username=" + userid, "_self");
		    }
		}
	}
	return ret;
}

function findnodeunder(parent, child) {
	var allofthem = parent.getElementsByTagName(child);
	if (allofthem) {
		for (var i = 0; i < allofthem.length; i++) {
			if (allofthem[i].parentNode == parent) {
				return allofthem[i];
			}
		}
	}
	return null;
}

function getnodetext(node) {
    if (node) {
        // get text, accounting for possible
        // whitespace (carriage return) text nodes
        if (node.childNodes.length > 1) {
            return node.childNodes[1].nodeValue;
        } else if (node.childNodes.length == 1) {
            return node.firstChild.nodeValue;
        } else {
        	return "";
        }
    } else {
        return "n/a";
    }
}

// get notes data

function getNotes(respnode) {
	var notes = respnode.getElementsByTagName("note");
	var o = null;
	if (notes) {
		o = new Object();
		o.notes = new Array();
		for (var i = 0; i < notes.length; i++) {
			o.notes[i] = new Object();
			o.notes[i].thedate = TimeStampToDate(getElementTextNS("","date",notes[i],0));
			o.notes[i].theid = getElementTextNS("","id",notes[i],0);
			o.notes[i].parentid = getElementTextNS("","parentid",notes[i],0);
			o.notes[i].reply = getElementTextNS("","reply",notes[i],0);
			o.notes[i].thevalue = getElementTextNS("","value",notes[i],0);
		}
		if (debug) {
			s = "";
			for (var i = 0; i < o.notes.length; i++) {
				s += "Note("+i+"):\n" +
				"Date: "+o.notes[i].Date+"\n" +
				"ID: "+o.notes[i].id+"\n" +
				"ParentID: "+o.notes[i].parentid+"\n" +
				"Reply: "+o.notes[i].reply+"\n";
			}			
			alert(s);
		}
	}	
	return o;
}

function findParent(notes,pid) {
	for (var i = 0; i < notes.notes.length; i++) {
		if (pid == notes.notes[i].theid) {
			return i;
		}
	}
	return -1;
}

// get license data

function getLicense(respnode) {
	var license = respnode.getElementsByTagName("license");
	var o = null;
	if (license && license.length == 1) {
		o = new Object();
	    o.servicedesk = getElementTextNS("", "servicedesk", license[0], 0);
   	    o.caption = getElementTextNS("", "caption", license[0], 0);
	    o.message = getElementTextNS("", "message", license[0], 0);
	    o.remaining = getElementTextNS("", "remaining", license[0], 0);
		if (debug) {
			s = "License:\n" +
			"Service Desk Licensed: "+ ((o,servicedesk == "0") ? "No" : "Yes") + "\n" +
			"Caption: "+o.caption+"\n" +
			"Message: "+o.message+"\n" +
			"Tickets Remaining: "+o.remaining+"\n";
			alert(s);
		}
	}	
	return o;
}

// get MOTD data

function getMOTD(respnode) {
	var MOTD = respnode.getElementsByTagName("motd");
	var o = null;
	if (MOTD && MOTD.length == 1) {
		o = new Object();
   	    o.caption = getElementTextNS("", "caption", MOTD[0], 0);
	    o.message = getElementTextNS("", "message", MOTD[0], 0);
		if (debug) {
			s = "MOTD:\n" +
			"Caption: "+o.caption+"\n" +
			"Message: "+o.message+"\n" +
			alert(s);
		}
	}	
	return o;
}

function displayCascadeDropdown(dobj, n, nr, hc, dc, caption, captionnorequired) {
	dobj[n].row = nr;
    dobj[n].caption = caption;
    dobj[n].baseoptioncaption = captionnorequired;
	if (isIE || n == 0) {
        dobj[n].cellhead = hc;
        dobj[n].cellhead.innerHTML = selectPrefix + caption;
        dobj[n].cellhead.className = "rowhead";
		dobj[n].cell = dc;
    	dobj[n].cell.className = "itemleft"; 
		if (n == 0) {
    		dobj[n].cell.innerHTML = dobj.activedrop.innerHTML;
		} else {
			dobj[n].row.style.display = "none";
		}
	}
}
// do get dropdown AJAX data

var cascadelastdobj = null;

function getCascadeDropdownData(dobj, n, match, sequence) {
	// level 0 is obtained as part of a combinded request
	// levels 1..n are independent requests 
	
	if (n != 0) {
	    // create XML document with default header and root node
	    initRequest();
	}

    // create a lookup field node and set content
	doGetDropdownDataFromField(dobj[n].field,dobj[n].display); 

	// filter match of higher level (if present)
    if (dobj[n].matchfield != "") {
		topf_node = makeValueListFilterFromField(r_node, dobj[n].matchfield, new Array(match), 
		   ((dobj[n].matchnot && !dobj[n].matchnot.sameText("false")) ? true : false), 
		   ((dobj[n].matchcomplete && !dobj[n].matchcomplete.sameText("false")) ? true : false), 
		   ((dobj[n].matchcase && !dobj[n].matchcase.sameText("false")) ? true : false));
	}
	if (dobj[n].filters) {
		dobj[n].filters(topf_node);
	}
	
	// remember the one we are on
	dobj.activedrop = dobj[n];
	// submit if not level 0
	if (n != 0) {
		// submit
		dobj.activesequence = 0;
		cascadelastdobj = dobj;
		return submitRequest(getCascadeDropdownDataDone);
	} else {
		dobj.activesequence = sequence;
	}
}

// process returned results

var pleaseSelect = "Please select a";
var selectPrefix = "Select ";

function getCascadeDropdownDataDone(dobj) {
	if (!dobj) {
		dobj = cascadelastdobj
	}
    if (!dobj.activedrop.baseoptioncaption) {
    	dobj.activedrop.baseoptioncaption = dobj.activedrop.caption;
    }
	
    var responsesec = req.responseXML.getElementsByTagName("response");
   
    var reqtxt;
    try {
        reqtxt = req.responseText;
    } catch(e) {
        reqtxt = "This browser does not return the XML as a string.  Check the trace.file.";
    }
 
    switch (handleError(responsesec[dobj.activesequence])) {
    case 1:
        alert("Unable to get response from server\n\nServer returned:\n" + reqtxt);
    case 2:
		skipbody = true;
    	return false;
    }
        
    // process the return table
    dobj.activedrop.innerHTML = '<select id="new_' + dobj.activedrop.field + 
    '" class="treeend" size="1" onChange="getnextdropdowndata(' + 
    dobj.activedrop.list + ', ' + (dobj.activedrop.level + 1) +
    ');">' +
                  '<option selected="1" value="">-- ' + pleaseSelect + ' ' + dobj.activedrop.baseoptioncaption + ' --</option>';
    var valuelist = processValue(responsesec[dobj.activesequence]);
    // ignore if empty
    if (valuelist != "") {
	    dobj.activedrop.innerHTML += valuelist.replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/\n/gi,"<br />");
	    dobj.activedrop.innerHTML += '</select>';
	    
	    if (dobj.activedrop.level != 0) {
	    	dobj.activedrop.showing = true;
		    if (dobj.activedrop.row) {
		    	if (isIE) {
		    		dobj.activedrop.row.style.display = "inline"
		    	} else {
		    		dobj.activedrop.row.innerHTML = "";
			        dobj.activedrop.cellhead = InsertThing("td", dobj.activedrop.row);
			        dobj.activedrop.cellhead.innerHTML = "Select " + dobj.activedrop.caption;
			        dobj.activedrop.cellhead.className = "rowhead";
					dobj.activedrop.cell = InsertThing("td", dobj.activedrop.row);
			    	dobj.activedrop.cell.className = "itemleft";
			    } 
		        dobj.activedrop.cell.innerHTML = dobj.activedrop.innerHTML;
			}
		}
	}

    return false;
}

// get data for next level of dropdown

function getnextdropdowndata(dobj, level) {
    if (level < dobj.length) {
    	// find select
	    var sel = document.getElementById("new_"+dobj[level-1].field);
		// hide lower levels
	    for (var i = level; i < dobj.length; i++) {
	    	if (dobj[i].row) {
	    		dobj[i].showing = false;
		    	if (isIE) {
		    		dobj[i].row.style.display = "none";
				} else {
		    		dobj[i].row.innerHTML = "";
		    	}
		    }
	    }
	    // get net level data
   		getCascadeDropdownData(dobj, level, sel.value, 0);
	}		
}

// check for unselected fields

function checkCascadeDropdownSelected(drop) {
	for (var i = drop.length - 1; i >= 0; i--) {
		if (drop[i].showing) {
			var valfield = document.getElementById("new_" + drop[i].field);
			if (valfield && valfield.value == "") {
				alert("You have not selected the " + drop[i].caption);
				valfield.focus();
				return false;
			}
		}
	}
	return true;
} 


// sample data for a dropdown

/*
var drop1 = new Array();
drop1.activesequence = 0;
drop1.activedrop = null;

drop1[0] = new Object();
drop1[0].level = 0;
drop1[0].list = "drop1";
drop1[0].field = "TEXT8_";
drop1[0].matchfield = "";
drop1[0].display = "Description_=Description";
drop1[0].caption = "Catagory";
drop1[0].showing = true;

drop1[1] = new Object();
drop1[1].level = 1;
drop1[1].list = "drop1";
drop1[1].field = "TEXT12_";
drop1[1].matchfield = "Text1_";
drop1[1].display = "Description_=Description";
drop1[1].showing = false;
*/

// goto knowledge base
function kb() {
    var url = "./kb.htm?userid=" + userid + "&key=" + sessionkey;;
    document.getElementById("dokb").href = addRandom(url);
    return true;
}

// get simple dropdown

function doGetDropdownDataFromTable(table,display,field) {

    // create a request node
    r_node = newRequestNode(RequestRoot, "request")

    // create a function node and set content
    newRequestValueNode(r_node, "function", "getlookupvalues");

    // create a email node and set content
    newRequestValueNode(r_node, "email", userid);

    // create a key node and set content
    newRequestValueNode(r_node, "key", sessionkey);

    // create a lookup field node and set content
    newRequestValueNode(r_node, "tablename", table);
    
    // request output
    if (!display) {
    	r_node.appendChild(seloptionsoutputField(field, null));
    } else {
    	r_node.appendChild(seloptionsoutputField(field, display));
    }
}

function doGetDropdownDataFromField(rfield,display,field) {

    // create a request node
    r_node = newRequestNode(RequestRoot, "request")

    // create a function node and set content
    newRequestValueNode(r_node, "function", "getlookupvalues");

    // create a email node and set content
    newRequestValueNode(r_node, "email", userid);

    // create a key node and set content
    newRequestValueNode(r_node, "key", sessionkey);

    // create a lookup field node and set content
    newRequestValueNode(r_node, "field", rfield);
    
    // request output
    if (!display) {
    	r_node.appendChild(seloptionsoutputField(field, null));
    } else {
    	r_node.appendChild(seloptionsoutputField(field, display));
    }
}

function doGetDropdownDataDone(indx, optionvar, caption, field) {
    var errorsec = req.responseXML.getElementsByTagName("error");
    var responsesec = req.responseXML.getElementsByTagName("response");
    var tbl = document.getElementById("alex_tickets");
    var doonce;
    var nr;
    var options_____;
    
    var reqtxt;
    try {
        reqtxt = req.responseText;
    } catch(e) {
        reqtxt = "This browser does not return the XML as a string.  Check the trace.file.";
    }

    switch (handleError(responsesec[indx])) {
    case 1:
        alert("Unable to get response from server\n\nServer returned:\n" + reqtxt);
    case 2:
		skipbody = true;
    	return false;
    }
        
    // process the return table
   
    options_____ = '<select id="' + field + '">\n' +
        '<option selected="1" value="">-- ' + pleaseSelect + ' ' + caption +' --</option>\n';
    var valuelist = processValue(responsesec[indx]);
    options_____ += valuelist.replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/\n/gi,"<br />");
    options_____ += '</select>\n';
    eval(optionvar + ' = options_____;');
    return false;
}

// label remapping

var staticlabels = new Array();
var requiredlabels = new Array();
var requiredtext = "*";

function getStaticLabel(field, label, addrequired) {
	var newlabel = staticlabels[field.toLowerCase()];
	if (!newlabel) {
		newlabel = label;
	}
	var required = requiredlabels[field.toLowerCase()];
	if (!required || !addrequired) {
		required = "";
	} else {
		required = requiredtext;
	}
	return required + newlabel;
}

// busy activity

function revealAction(divID)
{
    document.getElementById(divID+"button").style.display = "none";
    document.getElementById(divID+"wait").style.display = "block";
    document.getElementById(divID+"wait").innerHTML =  document.getElementById(divID+"wait").innerHTML;
}

function hideAction(divID)
{
    document.getElementById(divID+"button").style.display = "block";
    document.getElementById(divID+"wait").style.display = "none";
}

function revealModal(divID)
{
    window.onscroll = function () { document.getElementById(divID).style.top = document.body.scrollTop;};
    document.getElementById(divID).style.display = "block";
    document.getElementById(divID).style.top = document.body.scrollTop;
}

function hideModal(divID)
{
    document.getElementById(divID).style.display = "none";
}