//<script>
var regGetAliasMatch = new RegExp("[\]\[A-Z0-9_\"]*$","ig");
var regGetAliasReplace = new RegExp("[\[\]\"]","g");
var regStripAliasReplace = new RegExp("(as ([A-Za-z0-9_])*| ([A-Za-z0-9_])*)$","i");

var debugData = null;

function startDebugging(){

    if(debugData == null){
        var descData = new DataCtlDescr();
    	descData.addDataColumn("Date","dateTime");
    	descData.addDataColumn("Description","string");
    	descData.addDataColumn("Message","string");
    	debugData = new DataCtl(descData);
    }
    DEBUG = true;
    openDialog(window,"MessageViewer.asp",450,600,"Debug messages",null,null,null,true);
}

function ColProto() {
	this.alphaNumeric = true;
	this.backgroundColor = "#ffffff";
	this.bttnShowWhenLocked = false;
	this.commas = true;
	this.defaultValue = "";
	this.delayRetrieve = false;
	this.displayOnly = false;
	this.displayZero = false;
	this.enabled = true;
	this.leadZeros = false;
	this.locked = false;
	this.lookupAddlWhereStr = null;
	this.lookupCallback = null;
	this.lookupMultiSelect = false;
	this.lookupOvrFromStr = null;
	this.lookupSecurity = true;
	this.lookupTitle = null;
	this.lookupWBSWhereClause = null;
	this.required = false;
	this.total = false;
	this.updateable = true;
	this.visible = true;
}

function ColDescr(name, dataType, required, defaultValue) {
	this.name = name;
	this.dataType = dataType;
	if (required != null) this.required = required;
	if (defaultValue != null) this.defaultValue = defaultValue;
	handleDataType(this);
}
ColDescr.prototype = new ColProto();

function DescUtil(){
	this.getColumnWidth = _getColumnWidth;

	function _getColumnWidth(dataType, digits, decimals, strLength) {
		var returnWidth = 0;
		switch (dataType) {
		case "string" :
			returnWidth = strLength * 6;
			break;
		case "currency" :
		case "numeric" :
            returnWidth = (decimals == 0) ? (digits + 1) * 6 : (digits + 2) * 6;
			break;
		case "dateTime" :
			returnWidth = 110;
			break;
		case "date" :
		    returnWidth = 58;
			break;
		case "time" :
			returnWidth = 49;
			break;
		case "account" :
		case "client" :
		case "employee" :
		case "unit" :
		case "vendor" :
		    returnWidth = 89;
			break;
		case "labcd" :
		    returnWidth = 81;
			break;
		case "org" :
		    returnWidth = 121;
			break;
		case "uppercase" :
			returnWidth = strLength * 7;
			break;
		case "unitTable" :
		case "wbs1" :
		    returnWidth = 113;
			break;
		case "wbs2" :
		case "wbs3" :
		    returnWidth = 50;
			break;
		case "refno" :
			returnWidth = 100;
			break;
		}
		return returnWidth;
	}
}

function handleDataType(col){
	var dataType = col.dataType;
	var digits = 0;
	var decimals = 0;
	var commas = 0;
	var strLength = 0;
	var tmp;
	col.dataType = dataType.split(":")[0];
	if (col.dataType == "currency") {
	    decimals = formatSubs.currencyDecimals();
	    digits = formatSubs.currencyDigits() + decimals;
	}
	if (col.dataType == "numeric") {
		tmp = dataType.split(":")[1];
		if (tmp != null) {
			decimals = (tmp.split(".")[1] == null) ? 0 : parseInt(tmp.split(".")[1]);
			digits = parseInt(tmp.split(".")[0]);
			commas = Math.floor(digits / 3);
			digits += decimals;
		}
	}
	if ((col.dataType == "string") || (col.dataType == "uppercase")) {
		tmp = dataType.split(":")[1];
		if (tmp != null) strLength = parseInt(tmp);
	}
	
	switch (col.dataType) {
	case "string" :
		col.width = strLength * 6;
		col.length = strLength;
		break;
	case "currency" :
	case "numeric" :
	    col.width = (decimals == 0) ? (digits + 1) * 6 : (digits + 2) * 6;
		col.digits = digits;
		col.decimals = decimals;
		col.length = digits + commas + ((decimals == 0) ? 1 : 2); // allow for "-", ".", and commas.
		if (col.defaultValue == ""){
			var x = 0;
			col.defaultValue = x.toFixed(col.decimals);
		}			
		break;
	case "date" :
	    col.width = 58;
	    col.length = 0;
		break;
	case "time" :
	    col.width = 49;
	    col.length = 0;
		break;
	case "dateTime" :
	    col.width = 110;
	    col.length = 0;
		break;
	case "wbs1" :
	    col.width = 113;
	    col.length = formatSubs.WBS1Length();
		break;
	case "wbs2" :
	    col.width = 50;
	    col.length = formatSubs.WBS2Length();
		break;
	case "wbs3" :
	    col.width = 50;
	    col.length = formatSubs.WBS3Length();
		break;
	case "account" :
	    col.length = formatSubs.accountLength();
	    col.width = 89;
	    break;
	case "client" :
	    col.length = formatSubs.clientLength();
	    col.width = 89;
		break;
	case "employee" :
	    col.width = 89;
	    col.length = formatSubs.employeeLength();
		break;
	case "labcd" :
	    col.width = 81;
		col.length = formatSubs.laborcodeLength();
		break;
	case "org" :
	    col.width = 121;
		col.length = formatSubs.orgLength();
		break;
	case "unit" :
	    col.width = 89;
	    col.length = formatSubs.unitLength();
		break;
	case "unitTable" :
	    col.width = 113;
	    col.length = formatSubs.unitTableLength();
		break;
	case "uppercase" :
		col.width = strLength * 7;
		col.length = strLength;
		col.uppercase = true;
		break;
	case "vendor" :
	    col.width = 89;
	    col.length = formatSubs.vendorLength();
		break;
	case "refno" :
	    col.width = 100;
		col.length = formatSubs.refnoLength();
		break;
	}
	col.expr = col.name.replace(regStripAliasReplace,"");
	col.name = col.name.match(regGetAliasMatch)[0].replace(regGetAliasReplace,"");
}

function calendarPopupCtl(doc) {
	registerCtl(this);
	var cleaned = false;
	var calendar = this;
	var caller;
	var callerInputCtl;
	var srcDoc = doc;
	var calDiv;
	var dayDiv;
	var tmpElem;
	var tmpElem2;
	var tmpStyle;
	var monthYear;
	var monthName = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	var headingStr = "SMTWTFS";
	var spacer = new Array(6);
	var day = new Array(31);
	var highlightDiv;
	var i;
	var curDate;
	var firstDayOfMonth;
	var lastDayOfMonth;
	var timerId;
	var prevBttn;
	var nextBttn;
	calDiv = srcDoc.createElement("DIV");
	calDiv.onkeydown = onKeyDown;
	tmpStyle = calDiv.style;
	tmpStyle.zIndex = 1000;
	tmpStyle.position = "absolute";
	tmpStyle.pixelWidth = 141;
	tmpStyle.pixelHeight = 129;
	tmpStyle.backgroundColor = "#e8e8e8";
	tmpStyle.border = "1px solid";
	tmpStyle.borderColor = "#ffffff #a0a0a0 #a0a0a0 #ffffff";
	tmpStyle.visibility = "hidden";
	calDiv.onmousedown = on_mousedown;
	calDiv.onclick = on_click;
	// calDiv appended to body at end of construction
	prevBttn = srcDoc.createElement("IMG");
	prevBttn.id = "prevBttn";
	prevBttn.src = "images/calprev.gif";
	prevBttn.width = 10;
	prevBttn.height = 11;
	tmpStyle = prevBttn.style;
	tmpStyle.position = "absolute";
	tmpStyle.pixelTop = 3;
	tmpStyle.pixelLeft = 5;
	prevBttn.onmousedown = bttnPress;
	prevBttn.onmouseup = bttnRelease;
	prevBttn.onmouseout = bttnRelease;
	prevBttn.ondblclick = bttnPress;
	calDiv.appendChild(prevBttn);
	nextBttn = srcDoc.createElement("IMG");
	nextBttn.id = "nextBttn";
	nextBttn.src = "images/calnext.gif";
	nextBttn.width = 10;
	nextBttn.height = 11;
	tmpStyle = nextBttn.style;
	tmpStyle.position = "absolute";
	tmpStyle.pixelTop = 3;
	tmpStyle.pixelLeft = 124;
	nextBttn.onmousedown = bttnPress;
	nextBttn.onmouseup = bttnRelease;
	nextBttn.onmouseout = bttnRelease;
	nextBttn.ondblclick = bttnPress;
	calDiv.appendChild(nextBttn);
	monthYear = srcDoc.createElement("LABEL");
	monthYear.className = "stdFont";
	tmpStyle = monthYear.style;
	tmpStyle.position = "absolute";
	tmpStyle.pixelTop = 1;
	tmpStyle.pixelLeft = 20;
	tmpStyle.pixelWidth = 100;
	tmpStyle.textAlign = "center";
	tmpStyle.fontWeight = "bold";
	tmpStyle.color = "black";
	tmpStyle.filter = "dropShadow(color=#ffffff,offX=1,offY=1)";
	calDiv.appendChild(monthYear);
	tmpElem = srcDoc.createElement("LABEL");
	tmpStyle = tmpElem.style;
	tmpStyle.position = "absolute";
	tmpStyle.pixelLeft = 1;
	tmpStyle.pixelTop = 16;
	tmpStyle.pixelWidth = 137;
	tmpStyle.pixelHeight = 110;
	tmpStyle.border = "1px solid";
	tmpStyle.borderColor = "#a0a0a0 #ffffff #ffffff #a0a0a0";
	calDiv.appendChild(tmpElem);
	tmpElem = srcDoc.createElement("LABEL");
	tmpStyle = tmpElem.style;
	tmpStyle.position = "absolute";
	tmpStyle.pixelLeft = 2;
	tmpStyle.pixelTop = 17;
	tmpStyle.pixelWidth = 135;
	tmpStyle.pixelHeight = 108;
	tmpStyle.border = "1px solid";
	tmpStyle.borderColor = "#606060 #e8e8e8 #e8e8e8 #606060";
	calDiv.appendChild(tmpElem);
	for (i=0; i < 7; i++) {
		tmpElem = srcDoc.createElement("DIV");
		tmpElem.className = "calLblBg";
		tmpElem.style.pixelLeft = (i * 19) + 3;
		calDiv.appendChild(tmpElem);
		tmpElem2 = srcDoc.createElement("LABEL");
		tmpElem2.className = "stdFont calLbl";
		tmpElem2.innerText = headingStr.substr(i, 1);
		tmpElem.appendChild(tmpElem2);
	}
	dayDiv = srcDoc.createElement("DIV");
	tmpStyle = dayDiv.style;
	tmpStyle.overflow = "hidden";
	tmpStyle.backgroundColor = "white";
	tmpStyle.fontSize = "1pt";
	tmpStyle.lineHeight = "15px";
	tmpStyle.position = "absolute";
	tmpStyle.pixelLeft = 3;
	tmpStyle.pixelTop = 33;
	tmpStyle.pixelWidth = 133;
	tmpStyle.pixelHeight = 91;
	calDiv.appendChild(dayDiv);
	for (i=0; i < 6; i++) {
		spacer[i] = srcDoc.createElement("SPAN");
		spacer[i].className = "stdFont calSpacer";
		dayDiv.appendChild(spacer[i]);
	}
	for (i=0; i < 31; i++) {
		day[i] = srcDoc.createElement("SPAN");
		day[i].className = "stdFont calDay";
		day[i].innerText = i + 1;
		day[i].onmousedown = dayMouseDown;
		dayDiv.appendChild(day[i]);
	}
	highlightDiv = srcDoc.createElement("DIV");
	highlightDiv.className = "stdFont";
	tmpStyle = highlightDiv.style;
	tmpStyle.position = "absolute";
	tmpStyle.fontWeight = "bold";
	tmpStyle.paddingRight = "3px";
	tmpStyle.textAlign = "right";
	tmpStyle.pixelWidth = 19;
	tmpStyle.pixelHeight = 16;
	tmpStyle.backgroundColor = "#666699";
	tmpStyle.color = "white";
	highlightDiv.onmouseup = dayClick;
	dayDiv.appendChild(highlightDiv);

	srcDoc.body.appendChild(calDiv); // append to body last for performance

	// external methods
	this.cleanUp = _cleanUp;
	this.prevMonth = _prevMonth;
	this.nextMonth = _nextMonth;
	this.show = _show;
	this.hide = _hide;
	
	function bttnPress() {
		var eventObj = this.document.parentWindow.event;
		var srcElem = this;
		if (eventObj.button > 1) return;
		switch (srcElem.id) {
			case "prevBttn" :
				if (eventObj.type == "mousedown")
					_prevMonth(1);
				else
					_prevMonth(0);
				break;
			case "nextBttn" :
				if (eventObj.type == "mousedown")
					_nextMonth(1);
				else
					_nextMonth(0);
				break;
		}
	}
	
	function bttnRelease() {
		srcDoc.parentWindow.clearTimeout(timerId);
	}

	function _cleanUp() {
		var i;
		if (cleaned) return;
		cleaned = true;
		doc = null;
		calendar = null;
		caller = null;
		callerInputCtl = null;
		srcDoc = null;
		calDiv.onkeydown = null;
		calDiv.onmousedown = null;
		calDiv.onclick = null;
		calDiv = null;
		dayDiv = null;
		tmpElem = null;
		tmpElem2 = null;
		tmpStyle = null;
		monthYear = null;
		prevBttn.onmousedown = null;
		prevBttn.onmouseup = null;
		prevBttn.onmouseout = null;
		prevBttn.ondblclick = null;
		prevBttn = null;
		nextBttn.onmousedown = null;
		nextBttn.onmouseup = null;
		nextBttn.onmouseout = null;
		nextBttn.ondblclick = null;
		nextBttn = null;
		for (i=0; i < 6; i++) spacer[i] = null;
		for (i=0; i < 31; i++) {
			day[i].onmousedown = null;
			day[i] = null;
		}
		highlightDiv.onmouseup = null;
		highlightDiv = null;
	}

	function _prevMonth(callMode) {
		if (callMode == null) callMode = 2;
		curDay = curDate.getDate();
		lastDayOfNewMonth = new Date(curDate.getFullYear(), curDate.getMonth(), 0).getDate();
		if (curDay > lastDayOfNewMonth) curDay = lastDayOfNewMonth;
		curDate = new Date(curDate.getFullYear(), curDate.getMonth() - 1, curDay);
		drawMonth();
		switch (callMode) {
			case 1 :
				timerId = srcDoc.parentWindow.setTimeout(_prevMonth, 500);
				break;
			case 2 :
				timerId = srcDoc.parentWindow.setTimeout(_prevMonth, 1);
				break;
		}	
	}
	
	function _nextMonth(callMode) {
		if (callMode == null) callMode = 2;
		curDay = curDate.getDate();
		lastDayOfNewMonth = new Date(curDate.getFullYear(), curDate.getMonth() + 2, 0).getDate();
		if (curDay > lastDayOfNewMonth) curDay = lastDayOfNewMonth;
		curDate = new Date(curDate.getFullYear(), curDate.getMonth() + 1, curDay);
		drawMonth();
		switch (callMode) {
			case 1 :
				timerId = srcDoc.parentWindow.setTimeout(_nextMonth, 500);
				break;
			case 2 :
				timerId = srcDoc.parentWindow.setTimeout(_nextMonth, 1);
				break;
		}	
	}

	function _show(parentCtl, inputCtl, isForm) {
		var inputDateStr = inputCtl.dataValue;
		var year;
		var mm;
		var dd;
		caller = parentCtl;
		callerInputCtl = inputCtl;
		if ((inputDateStr == null) || (inputDateStr == ""))
			curDate = new Date();
		else
			curDate = formatSubs.strRawToDate(inputDateStr);
		drawMonth();
		positionCalendar(inputCtl, isForm);
		calDiv.style.visibility = "visible";
		calDiv.setCapture(false);
		calDiv.focus();
	}

	function _hide(releaseCapture) {
		calDiv.style.visibility = "hidden";
		if (releaseCapture) calDiv.releaseCapture();
	}

	function positionCalendar(inputCtl, isForm) {
		var ctlLeft = getOffsetLeft(inputCtl);
		var ctlTop = getOffsetTop(inputCtl);
		var bodyWidth = inputCtl.document.body.clientWidth;
		var bodyHeight = inputCtl.document.body.clientHeight;
		var leftPos;
		var topPos;
		var borderAdjustment;
		leftPos = ctlLeft - 1;
		if ((leftPos + calDiv.style.pixelWidth) > bodyWidth) leftPos = bodyWidth - calDiv.style.pixelWidth;
		if (isForm) {
			topPos = ctlTop + 17;
			borderAdjustment = 0;
		}
		else {
			topPos = ctlTop + 16;
			borderAdjustment = 1;
		}
		if ((topPos + calDiv.style.pixelHeight) > bodyHeight)
			topPos = ctlTop - calDiv.style.pixelHeight - borderAdjustment;
		calDiv.style.pixelLeft = leftPos;
		calDiv.style.pixelTop = topPos;
	}

	function on_mousedown() {
		var x = srcDoc.parentWindow.event.clientX;
		var y = srcDoc.parentWindow.event.clientY;
		var left = getOffsetLeft(this);
		var top = getOffsetTop(this);
		if ((x < left) || (x > left + this.style.pixelWidth) || (y < top) || (y > top + this.style.pixelHeight)) {
			srcDoc.parentWindow.event.cancelBubble = true;
			_hide(false);
		}
	}

	function on_click() {
		if (calDiv.style.visibility == "hidden") calDiv.releaseCapture();
	}

	function drawMonth() {
		var i;
		var curDay = curDate.getDay();
		var curDayNum = curDate.getDate() - 1; // want zero-based for calculations
		firstDayOfMonth = curDay - (curDayNum % 7);
		if (firstDayOfMonth < 0) firstDayOfMonth += 7;
		for (i=0; i < 6; i++) {
			if (i < firstDayOfMonth) {
				spacer[i].style.display = "inline";
				spacer[i].innerHTML = "&nbsp";
			}
			else {
				spacer[i].style.display = "none";
				spacer[i].innerHTML = "";
			}
		}
		lastDayOfMonth = new Date(curDate.getFullYear(), curDate.getMonth() + 1, 0).getDate();
		for (i=28; i < 31; i++) {
			if (i < lastDayOfMonth)
				day[i].style.visibility = "inherit";
			else
				day[i].style.visibility = "hidden";
		}
		monthYear.innerHTML = monthName[curDate.getMonth()] + "&nbsp;&nbsp;" + curDate.getFullYear();
		highlight(curDayNum + 1); // switch back to 1-based for highlight
	}

	function highlight(dayNum) {
		var row = Math.floor((dayNum + firstDayOfMonth - 1) / 7);
		var col = (dayNum + firstDayOfMonth - 1) % 7;
		highlightDiv.innerText = dayNum;
		highlightDiv.style.pixelTop = row * 15;
		highlightDiv.style.pixelLeft = col * 19;
	}

	function dayMouseDown() {
		var i;
		for (i=0; i < 31; i++)
			if (day[i] == this) break;
		highlight(i + 1);
		curDate = new Date(curDate.getFullYear(), curDate.getMonth(), i + 1);
	}

	function dayClick() {
		selectCurrentDate();
	}

	function selectCurrentDate() {
	    _hide(true);
		callerInputCtl.focus();
		caller.acceptCalendarInput(curDate);
	}

	function onKeyDown() {
		var eventObj = srcDoc.parentWindow.event;
		var keyCode = eventObj.keyCode;
		var saveMonth;
		if ((keyCode != 13) && ((keyCode < 37) || (keyCode > 40))) return;
		eventObj.returnValue = false;
		saveMonth = curDate.getMonth();
		switch (eventObj.keyCode) {
			case 13 : // carriage return
				selectCurrentDate();
				break;
			case 37 : // left arrow
				curDate = new Date(curDate.getFullYear(), curDate.getMonth(), curDate.getDate() - 1);
				break;
			case 38 : // up arrow
				curDate = new Date(curDate.getFullYear(), curDate.getMonth(), curDate.getDate() - 7);
				break;
			case 39 : // right arrow
				curDate = new Date(curDate.getFullYear(), curDate.getMonth(), curDate.getDate() + 1);
				break;
			case 40 : // down arrow
				curDate = new Date(curDate.getFullYear(), curDate.getMonth(), curDate.getDate() + 7);
				break;
		}
		if (curDate.getMonth() == saveMonth)
			highlight(curDate.getDate());
		else
			drawMonth();
	}
}

function HelpButton(div, helpFile, enabled, visible) {
	registerCtl(this);
	var cleaned = false;
	var thisObj = this;
	var helpFileName = helpFile;
	var bttn = new cmdButton(div, "Help", helpClicked, enabled, visible);
	bttn.tabCtl = getTabCtl;
	bttn.tabPage = getTabPage;
	bttn.tabbingIndex = getTabbingIndex;
	this.enable = bttn.enable;
	this.disable = bttn.disable;
	this.hide = bttn.hide;
	this.show = bttn.show;
	this.caption = bttn.caption;
	this.setCaption = bttn.setCaption;
	this.init = bttn.init;
	this.tabInto = bttn.tabInto;
	this.backTabInto = bttn.backTabInto;
	this.focus = bttn.focus;
	this.cleanUp = _cleanUp;

	function _cleanUp(){
		if (cleaned) return;
		cleaned = true;
		div = null;
		bttn = null;
	}

	function helpClicked() {
		global.openNewWindow("help/Vision_Help.htm#" + helpFile)
	}

	function getTabCtl() {
		return thisObj.tabCtl;
	}

	function getTabPage() {
		return thisObj.tabPage;
	}

	function getTabbingIndex() {
		return thisObj.tabbingIndex;
	}
}

function cmdButton(div, caption, onClick, enabled, visible) {
	registerCtl(this);
	var cleaned = false;
	var bttn = this;
	var bttnDiv = div;
	var srcWindow = bttnDiv.document.parentWindow;
	var bttnEnabled = true;
	var bttnFocus = false;
	var bttnAction = onClick;
	var leftImg;
	var backImg;
	var rightImg;
	var bttnCaption;
	var coverImg;
	leftImg = bttnDiv.document.createElement("IMG");
	leftImg.height = 23;
	leftImg.width = 11;
	leftImg.style.position = "absolute";
	leftImg.style.pixelTop = 0;
	leftImg.style.pixelLeft = 0;
	leftImg.src = UI.cmdBttnLeftImg.src;
	backImg = bttnDiv.document.createElement("IMG");
	backImg.style.position = "absolute";
	backImg.style.pixelTop = 0;
	backImg.style.pixelLeft = 11;
	backImg.style.pixelHeight = 23;
	backImg.style.pixelWidth = bttnDiv.style.pixelWidth - 22;
	backImg.src = UI.cmdBttnBgImg.src;
	rightImg = bttnDiv.document.createElement("IMG");
	rightImg.height = 23;
	rightImg.width = 11;
	rightImg.style.position = "absolute";
	rightImg.style.pixelTop = 0;
	rightImg.style.pixelLeft = bttnDiv.style.pixelWidth - 11;
	rightImg.src = UI.cmdBttnRightImg.src;
	bttnCaption = bttnDiv.document.createElement("DIV");
	bttnCaption.className = "cmdButtonCaption";
	bttnCaption.innerText = caption;
	bttnCaption.style.pixelWidth = bttnDiv.style.pixelWidth;
	coverImg = bttnDiv.document.createElement("IMG");
	coverImg.style.position = "absolute";
	coverImg.style.pixelTop = 0;
	coverImg.style.pixelLeft = 0;
	coverImg.style.pixelHeight = 23;
	coverImg.style.pixelWidth = bttnDiv.style.pixelWidth;
	coverImg.src = UI.transparentImg.src;
	bttnDiv.className = "cmdButton";
	bttnDiv.onmousedown = bttnPress;
	bttnDiv.onmouseup = bttnRelease;
	bttnDiv.onmouseout = bttnRelease;
	bttnDiv.onclick = bttnClicked;
	bttnDiv.onfocus = onFocus;
	bttnDiv.onblur = onBlur;
	bttnDiv.onkeydown = onKeydown;
	bttnDiv.appendChild(leftImg);
	bttnDiv.appendChild(backImg);
	bttnDiv.appendChild(rightImg);
	bttnDiv.appendChild(bttnCaption);
	bttnDiv.appendChild(coverImg);
	if (enabled == null)
		bttnEnabled = true;
	else
		bttnEnabled = enabled;
	if (visible == false) bttnDiv.style.display = "none";
	this.enable = _enable;
	this.disable = _disable;
	this.hide = _hide;
	this.show = _show;
	this.caption = _caption;
	this.cleanUp = _cleanUp;
	this.setCaption = _setCaption;
	this.init = _init;
	this.tabInto = _tabInto;
	this.backTabInto = _backTabInto;
	this.focus = _focus;

	function _init() {
		// noop - tabCtl will call init on all registered controls, including command buttons
	}

	function _tabInto() {
		bttnDiv.focus();
	}

	function _backTabInto() {
		bttnDiv.focus();
	}

	function _focus() {
		bttnDiv.focus();
	}

	function _cleanUp(){
		if (cleaned) return;
		cleaned = true;
		div = null;
		onClick = null;
		bttn = null;
		bttnDiv.onmousedown = null;
		bttnDiv.onmouseup = null;
		bttnDiv.onmouseout = null;
		bttnDiv.onclick = null;
		bttnDiv.onfocus = null;
		bttnDiv.onblur = null;
		bttnDiv.onkeydown = null;
		bttnDiv = null;
		srcWindow = null;
		bttnAction = null;
		leftImg = null;
		backImg = null;
		rightImg = null;
		bttnCaption = null;
		coverImg = null;
	}

	function _enable() {
		bttnCaption.style.color = "#000000";
		bttnEnabled = true;
	}

	function _disable() {
		bttnCaption.style.color = "#808080";
		bttnEnabled = false;
	}

	function _hide() {
		bttnDiv.style.display = "none";
	}

	function _show() {
		bttnDiv.style.display = "block";
	}

	function bttnPress() {
		if (bttnEnabled) {
			backImg.src = UI.cmdBttnBgPressImg.src;
			leftImg.src = UI.cmdBttnLeftPressImg.src;
			rightImg.src = UI.cmdBttnRightPressImg.src;
			bttnCaption.style.color = UI.hdrBackground;
			bttnCaption.style.pixelTop = 5;
			bttnCaption.style.pixelLeft = 1;
		}
	}

	function bttnRelease() {
		if (bttnEnabled) {
			if (bttnFocus) {
				backImg.src = UI.cmdBttnFocusBgImg.src;
				leftImg.src = UI.cmdBttnFocusLeftImg.src;
				rightImg.src = UI.cmdBttnFocusRightImg.src;
			}
			else {
				backImg.src = UI.cmdBttnBgImg.src;
				leftImg.src = UI.cmdBttnLeftImg.src;
				rightImg.src = UI.cmdBttnRightImg.src;
			}
			bttnCaption.style.pixelTop = 4;
			bttnCaption.style.pixelLeft = 0;
		}
	}

	function executeAction() {
		bttnAction();
		bttnDiv.style.cursor = "hand";
	}

	function bttnClicked() {
		if (bttnEnabled) {
			bttnDiv.style.cursor = "wait";
			srcWindow.setTimeout(executeAction, 1);
		}
	}

	function _caption() {
		return 	bttnCaption.innerText;
	}

	function _setCaption(caption) {
		bttnCaption.innerText = caption;
	}

	function onFocus() {
		if (bttnEnabled) {
			backImg.src = UI.cmdBttnFocusBgImg.src;
			leftImg.src = UI.cmdBttnFocusLeftImg.src;
			rightImg.src = UI.cmdBttnFocusRightImg.src;
			bttnCaption.style.color = UI.bttnFocusText;
		}
		bttnFocus = true;
	}

	function onBlur() {
		if (bttnEnabled) {
			backImg.src = UI.cmdBttnBgImg.src;
			leftImg.src = UI.cmdBttnLeftImg.src;
			rightImg.src = UI.cmdBttnRightImg.src;
			bttnCaption.style.color = "#000000";
		}
		bttnFocus = false;
	}

	function onKeydown() {
		var eventObj = this.document.parentWindow.event;
		var keyCode = eventObj.keyCode;
		var tabCtl;
		var tabPage;
		var tabbingIndex;
		eventObj.returnValue = false;
		if (keyCode == 13) {
			bttnDiv.style.cursor = "wait";
			srcWindow.setTimeout(executeAction, 1);
		}
		else if (keyCode == 9) {
			if (typeof(bttn.tabCtl) == "function")
				tabCtl = bttn.tabCtl();
			else
				tabCtl = bttn.tabCtl;
			if (typeof(bttn.tabPage) == "function")
				tabPage = bttn.tabPage();
			else
				tabPage = bttn.tabPage;
			if (typeof(bttn.tabbingIndex) == "function")
				tabbingIndex = bttn.tabbingIndex();
			else
				tabbingIndex = bttn.tabbingIndex;
			if (tabCtl != null) {
				if (eventObj.shiftKey)
					tabCtl.processBackTab(tabPage, tabbingIndex);
				else
					tabCtl.processTab(tabPage, tabbingIndex);
			}
		}
	}
}

function ContextCtl(functionPtr, offsetArg, srcWin) {
	registerCtl(this);
	var cleaned = false;
	var getContext = functionPtr;
	var srcWindow;
	var srcDoc;
	var offset = offsetArg;
	var contextDiv1;
	var contextDiv2;
	var contextDiv3;
	
	this.cleanUp = _cleanUp;
	this.setContextStr = _setContextStr;
	
	if (srcWin == null)
		srcWindow = application;
	else
		srcWindow = srcWin;
	srcDoc = srcWindow.document;
	contextDiv1 = srcDoc.createElement("DIV");
	contextDiv1.className = "context";
	contextDiv1.style.position = "absolute";
	contextDiv1.style.pixelTop = 7;
	contextDiv1.style.pixelHeight = 14;
	contextDiv1.style.overflow = "hidden";
	if (offset == null) offset = 0;
	contextDiv1.style.pixelLeft = 10 + offset;
	srcDoc.body.appendChild(contextDiv1);

    function _cleanUp(){
		if (cleaned) return;
	    cleaned = true;
	    functionPtr = null;
	    srcWin = null;
	    getContext = null;
	    srcWindow = null;
	    srcDoc = null;
	    contextDiv1 = null;
	    contextDiv2 = null;
	    contextDiv3 = null;
    }
    
	function _setContextStr() {
		var contextStr = getContext();
		var contextArray = contextStr.split("|");
		contextDiv1.innerText = contextArray[0];
		if (contextArray.length > 1) {
			contextDiv1.style.fontSize = "8pt";
			contextDiv1.style.pixelTop = 1;
			contextDiv1.style.pixelHeight = 13;
			if (contextDiv2 == null) {
				contextDiv2 = srcDoc.createElement("DIV");
				contextDiv2.className = "context";
				contextDiv2.style.fontSize = "8pt";
				contextDiv2.style.position = "absolute";
				contextDiv2.style.pixelTop = 14;
				contextDiv2.style.pixelHeight = 13;
				contextDiv2.style.overflow = "hidden";
				contextDiv2.style.zIndex = -1;
				if (offset == null) offset = 0;
				contextDiv2.style.pixelLeft = 10 + offset;
				srcDoc.body.appendChild(contextDiv2);
			}
			contextDiv2.innerText = contextArray[1];
		}
		else {
			contextDiv1.style.fontSize = "9pt";
			contextDiv1.style.pixelTop = 7;
			contextDiv1.style.pixelHeight = 14;
			if (contextDiv2 != null) contextDiv2.innerText = "";
		}
		if (contextArray.length > 2) {
			if (contextDiv3 == null) {
				contextDiv3 = srcDoc.createElement("DIV");
				contextDiv3.className = "context";
				contextDiv3.style.fontSize = "8pt";
				contextDiv3.style.position = "absolute";
				contextDiv3.style.pixelTop = 27;
				contextDiv3.style.pixelHeight = 13;
				contextDiv3.style.overflow = "hidden";
				contextDiv3.style.zIndex = -1;
				if (offset == null) offset = 0;
				contextDiv3.style.pixelLeft = 10 + offset;
				srcDoc.body.appendChild(contextDiv3);
			}
			contextDiv3.innerText = contextArray[2];
		}
		else {
			if (contextDiv3 != null) contextDiv3.innerText = "";
		}
	}
}

function CookieSubs()
{
	this.setCookie = _setCookie
	this.getCookie = _getCookie
	this.deleteCookie = _deleteCookie
	
	function _getCookie(cookieName)
	{
		return privGetCookie(cookieName)
	}
		
	function _setCookie(cookieName, cookieValue, expireImmediately)
	{
		privSetCookie(cookieName, cookieValue, expireImmediately)
	}

	function _deleteCookie(cookieName)
	{
		privSetCookie(cookieName, "", expireImmediately)
	}

	function privGetCookie(sName)
	{
		var strData;
		
		var aCookie = document.cookie.split("; ")
		for (var i=0; i < aCookie.length; i++)
		{
			// a name/value pair (a crumb) is separated by an equal sign
			var aCrumb = aCookie[i].split("=")
			if (sName == aCrumb[0]) // found name/value pair
			{
			    strData = unescape(aCrumb[1])
			}
		}
		
		if (typeof(strData)=="undefined") { return ""; }
		if (strData.slice(0, 8) == "<NUMBER>") { // return integer, unless float required
		    if (parseInt(strData.slice(8)) == parseFloat(strData.slice(8))) {
		        return parseInt(strData.slice(8))
		    }
		    else {
		        return parseFloat(strData.slice(8))
		    }
		}
		else if (strData.slice(0, 6) == "<DATE>") { // return date object
	        return formatSubs.strRawToDate(strData.slice(6))
		}
		else { // return string otherwise
		    return strData
		}
	}	
	
	function privSetCookie(sName, sValue, expireImmediately)
	{
	    var strData
	    
		var expireStr = "; expires='Wed, 7 Feb 2027 23:59:59 UTC;'"
		if (expireImmediately != null)
			expireStr = ""
		switch (typeof(sValue)) {
		    case "numeric" :
		        strData = "<NUMBER>" + sValue.toString()
		        break
		    case "object" : //assume date object, including null
		        strData = "<DATE>" + formatSubs.dateToStrRaw(sValue)
		        break
		    default : //assume "string" otherwise
		        strData = sValue
		}
		document.cookie = sName + "=" + escape(strData) + expireStr
	}
}

function Exception(){
	this.errors = new Array()
	this.valid = true;
	this.addError = _addError;
	this.addNode = _addNode;
	this.addInfo = _addInfo;
	this.addWarning = _addWarning;
	this.addFatalError = _addFatalError;
	this.showErrors = _showErrors;
	this.severity = 0;//0= info;1=warning;2=error;3=fatalError
	this.getCount = _getCount;
	this.buildErrorList = _buildErrorList;
	this.buildErrorAddNode = _buildErrorAddNode;
	this.childErrors = null;
	this.disableShow = false;
	this.clearErrors = _clearErrors;
	this.invalidSessionError = _invalidSessionError;
	var curObj = this;
	var dltkErrorCode = -2147219814;
	var dltkErrorInvalidSession = -2147219813;
	function _clearErrors(){
		this.errors.length = 0;
		this.severity = 0;
		this.valid = true;
	}
	function _invalidSessionError(errorDom){
		var invalidSessionNode;
		invalidSessionNode = errorDom.selectSingleNode("//ERROR[NUM = '" + dltkErrorInvalidSession + "']");
		if (invalidSessionNode != null){
			return true;
		}
		return false;
	}
	
	function _getCount(){
		return this.errors.length;
	}
	function _addNode(description,number,severity,module,func,col,table,key){
        var o = new Object();
        //If disable show is on then this is a cascading error don't addit
		if (this.disableShow) return;
        o.module = "";
        o.func = "";
        o.number = 0;
        o.description = "";
        o.col = "";
        o.key = "";
        o.table = "";
		o.severity = 0;
	    if(typeof(description) != "undefined") o.description = description;
	    if(typeof(number) != "undefined") o.number = number;
	    if(typeof(module) != "undefined") o.module = module;
	    if(typeof(func) != "undefined") o.func = func;
	    if(typeof(col) != "undefined") o.col = col;
	    if(typeof(table) != "undefined") o.table = table;
	    if(typeof(key) != "undefined") o.key = key;
	    if(typeof(severity) != "undefined") {
			o.severity = severity;
			if (severity > this.severity){
				this.severity = severity;
			}
	    }

	    this.errors[this.errors.length] = o;
		this.valid = false;
		    
	    if(DEBUG){
	        var msg = "Desc: " + description;
	        msg += "|Num: " + number;
	        msg += "|Module: " + module;
	        msg += "|Func: " + func;
	        msg += "|Col: " + col;
	        msg += "|Table: " + table;
	        msg += "|Key: " + key;
	        msg += "|Severity: " + severity;
	        logEvent("Error added",msg);
	    }
	    return o;
	}
	function _addFatalError(description,number,module,func,col,table,key){
		return this.addNode(description,number,3,module,func,col,table,key);
	}
	function _addError(description,number,module,func,col,table,key){
		return this.addNode(description,number,2,module,func,col,table,key);
	}
	function _addWarning(description,number,module,func,col,table,key){
		return this.addNode(description,number,1,module,func,col,table,key);
	}
	function _addInfo(description,number,module,func,col,table,key){
		return this.addNode(description,number,0,module,func,col,table,key);
	}
	function _buildErrorList(errorDom){
		var i;
		var node,tmpNode;
		var nodeList;
		
		node = errorDom.selectSingleNode("//ERROR[NUM !='0' and NUM != '" + dltkErrorCode + "']");
		if (node != null){
			node = this.buildErrorAddNode(node.parentNode.removeChild(node));
			node.childErrors = new Exception();
			nodeList = errorDom.selectNodes("//ERROR[NUM = " + dltkErrorCode + "]");
			tmpNode = nodeList.nextNode();
			while (tmpNode!=null){
				node.childErrors.buildErrorAddNode(tmpNode.parentNode.removeChild(tmpNode));
				tmpNode = nodeList.nextNode();
			}
		}
		for(i = errorDom.childNodes.length -1 ;i >= 0;i--){
			this.buildErrorAddNode(errorDom.removeChild(errorDom.childNodes(i)));
		}
	}
	function _buildErrorAddNode(errnode){

		var desc,num,mod,func,col,table,key,severity;
		desc = errnode.selectSingleNode("DESC").text;
		num = errnode.selectSingleNode("NUM").text;
		mod = errnode.selectSingleNode("MODULE").text;
		func = errnode.selectSingleNode("FUNC").text;
		col = errnode.selectSingleNode("COL").text;
		table = errnode.selectSingleNode("TABLE").text;
		key = errnode.selectSingleNode("PKEY").text;
		severity = parseInt(errnode.selectSingleNode("SEVERITY").text, 10);
		node = curObj.addNode(desc,num,severity,mod,func,col,table,key);
		return node;
	}

	function _showErrors(haltApplication){
		var win;
		var desc;
		var topWindow;
		if (typeof haltApplication == "undefined") haltApplication = true;
		if (this.disableShow) return;
		if ((this.errors.length == 1) && (this.severity < 3)){
			if (windowStack == null)
				topWindow = window;
			else
				topWindow = windowStack[windowStack.length - 1];
			mb.msgbox(topWindow, this.errors[0].description, mb.OKOnly + mb.Exclamation);
		}
		else if (this.errors.length > 0){
			desc = new Object();
			desc.global = top;
			desc.errorObj = this
			desc.haltApplication = haltApplication;
			win = new ErrorWindow(desc);
			win.open();
		}
	}

	function ErrorWindow(desc)
	{
		this.stateObject = new Object();
		this.stateObject.errorObj = desc.errorObj;
		this.stateObject.global = desc.global;
		this.stateObject.haltApplication = desc.haltApplication;
		this.open = _open;

		function _open() {
			var topWindow;
			var returnObject;
			var appVersionArray = clientInformation.appVersion.split(";");
			var dialogHeight = "225px";
			if (appVersionArray[2].indexOf("Windows NT 5.1") >= 0) dialogHeight = "232px";
			if (windowStack == null)
				topWindow = window;
			else
				topWindow = windowStack[windowStack.length - 1];
			returnObject = topWindow.showModalDialog("error.htm", this.stateObject, "resizable: yes; dialogwidth: 500px; dialogheight: " + dialogHeight + "; status: no");
			return returnObject;
		}

	}
}

function HeaderCtlDescr(contentDiv, caption, top, left, width, collapsible, dashPartID, webDashPart, height, viewState) {
	registerCtl(this);
	var cleaned = false;
	this.contentDiv = contentDiv;
	this.caption = caption;
	this.top = top;
	this.left = left;
	this.width = width;
	this.height = height;
	this.collapsible = collapsible;
	this.viewState = viewState;
	this.dashPartID = dashPartID;
	this.webDashPart = webDashPart;
	this.dashPartColor = UI.hdrBackground;
	this.zIndex = 0;
	this.cmds = 0;
	this.cmdInfo = new Array();
	
	this.addCmd = _addCmd;
	this.cleanUp = _cleanUp;
	
	function _addCmd(cmdName, image, caption, callBack, imageWidth, title, dropdown) {
		var newCmd = new Object();
		newCmd.name = cmdName;
		newCmd.image = image;
		newCmd.imageWidth = imageWidth;
		newCmd.caption = caption;
		newCmd.callBack = callBack;
		if (title == null)
			newCmd.title = "";
		else
			newCmd.title = title;
		newCmd.dropdown = dropdown;
		this.cmdInfo[this.cmds] = newCmd;
		return this.cmdInfo[this.cmds++];
	}

	function _cleanUp() {
		var i;
		if (cleaned) return;
		cleaned = true;
		contentDiv = null;
		this.contentDiv = null;
		for (i=0; i < this.cmds; i++) {
			this.cmdInfo[i].callBack = null;
			this.cmdInfo[i] = null;
		}
	}
}

function HeaderCtl(descr) {
	registerCtl(this);
	var cleaned = false;
	var hdr = this;
	var cmdInfo = new Array();
	var cmds;
	var containerDiv;
	var contentDiv;
	var ctlDiv;
	var srcDoc;
	var captionCtl = null;
	var collapseImg;
	var topRightShadow;
	var rightShadow;
	var bottomLeftShadow;
	var bottomShadow;
	var bottomRightShadow;
	var headerDiv;
	var headerCorner;
	var topRightCorner;
	var dashPartID;
	var dashPartColor;
	var hdrShadow = UI.hdrShadow;
	var dragInitHPos;
	var dragInitClientHPos;
	var dragInitVPos;
	var dragInitClientVPos;
	var dragObj;
	var dragging = false;
	var maximized = false;
	var saveTop;
	var saveLeft;
	var saveHeight;
	var saveWidth;
	var saveViewState;

	this.zIndex = descr.zIndex

	init(descr);
	
	this.myMoveControls = null;
	this.ovrMoveControls = null;

	this.myDashPartAdjust = null;

	// external methods
	this.cleanUp = _cleanUp;
	this.disableAll = _disableAll;
	this.disableCmd = _disableCmd;
	this.enableAll = _enableAll;
	this.enableCmd = _enableCmd;
	this.hideCmd = _hideCmd;
	this.showCmd = _showCmd;
	this.hide = _hide;
	this.resize = _resize;
	this.setPosition = _setPosition;
	this.setCaption = _setCaption;
	this.show = _show;
	this.collapse = _collapse;
	this.expand = _expand;
	this.disableArrow = _disableArrow;
	this.enableArrow = _enableArrow;
	this.maximize = _maximize;
	this.restore = _restore;
	this.remove = _remove;
	
	function _collapse() {
		collapseImg.action = "Collapse";
		toggleContentDisplay();
	}
	
	function _expand() {
		collapseImg.action = "Expand";
		toggleContentDisplay();
	}
	
	function _enableArrow() {
		collapseImg.style.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
		collapseImg.style.cursor = "hand";
		collapseImg.enabled = true;
	}
	
	function _disableArrow() {
		collapseImg.style.filter = "gray alpha(opacity=70)";
		collapseImg.style.cursor = "default";
		collapseImg.enabled = false;
	}
	

	function windowResize() {
		var newWidth = srcDoc.body.clientWidth - 17;
		var newHeight = srcDoc.body.clientHeight - 38;
		_resize(newWidth, newHeight);
	}

	function _maximize() {
		saveTop = containerDiv.style.pixelTop;
		saveLeft = containerDiv.style.pixelLeft;
		saveHeight = contentDiv.style.pixelHeight + 22; // use contentDiv in case containerDiv is collapsed
		saveWidth = containerDiv.style.pixelWidth;
		saveViewState = collapseImg.viewState;
		_setPosition(0, 0);
		if (saveViewState == "Collapsed") toggleContentDisplay();
		windowResize();
		bottomShadow.style.cursor = "default";
		bottomRightShadow.style.cursor = "default";
		rightShadow.style.cursor = "default";
		ctlDiv.style.cursor = "default";
		headerDiv.style.cursor = "default";
		moveToTop();
		srcDoc.parentWindow.attachEvent("onresize", windowResize);
		maximized = true;
	}

	function _restore() {
		srcDoc.parentWindow.detachEvent("onresize", windowResize);
		_setPosition(saveTop, saveLeft);
		_resize(saveWidth, saveHeight);
		if (saveViewState == "Collapsed") toggleContentDisplay();
		if (navigator.appVersion.indexOf('MSIE 5.5') >= 0) {
			bottomShadow.style.cursor = "hand";
			bottomRightShadow.style.cursor = "hand";
			rightShadow.style.cursor = "hand";
		}
		else {
			bottomShadow.style.cursor = "N-resize";
			bottomRightShadow.style.cursor = "NW-resize";
			rightShadow.style.cursor = "E-resize";
		}
		ctlDiv.style.cursor = "move";
		headerDiv.style.cursor = "move";
		moveToTop();
		maximized = false;
	}

	function init(descr) {
		var i;
		var tmpElem;
		var tmpStyle;
		var userLabels;
		var bgColor;
		var highlight;
		var shadow1;
		var shadow2;

		function setUserLabel(labelCtl) {
			var userLabelsCtl = srcDoc.parentWindow.userLabelsCtl;
			var divID;
			var tmpElem;
			var row;
			if (labelCtl.divID == null) {
				tmpElem = labelCtl.parentElement;
				while (tmpElem.className != "tabPage")
					tmpElem = tmpElem.parentElement;
				divID = tmpElem.id;
			}
			else divID = labelCtl.divID;
			row = userLabelsCtl.find("DivID = '" + divID + "' and LabelID = '" + labelCtl.id + "'");
			if (row > 0) {
				labelCtl.divID = divID;
				labelCtl.origHTML = labelCtl.innerHTML;
				labelCtl.innerHTML = userLabelsCtl.getValueAsString(row, "UserDefinedLabel");
				labelCtl.custHTML = labelCtl.innerHTML;
			}
		}

		function setDashPartColors() {
			var bgRed   = parseInt(dashPartColor.substr(1, 2), 16);
			var bgGreen = parseInt(dashPartColor.substr(3, 2), 16);
			var bgBlue  = parseInt(dashPartColor.substr(5, 2), 16);
			var tmpRed;
			var tmpGreen;
			var tmpBlue;

			function colorStr(redValue, greenValue, blueValue) {
				var redStr   = redValue.toString(16);
				var greenStr = greenValue.toString(16);
				var blueStr  = blueValue.toString(16);
				if (redStr.length   == 1) redStr   = "0" + redStr;
				if (greenStr.length == 1) greenStr = "0" + greenStr;
				if (blueStr.length  == 1) blueStr  = "0" + blueStr;
				return "#" + redStr + greenStr + blueStr;
			}

			// highlight
			tmpRed   = bgRed   + Math.round((255 - bgRed)   * 0.5); if (tmpRed   > 255) tmpRed   = 255;
			tmpGreen = bgGreen + Math.round((255 - bgGreen) * 0.5); if (tmpGreen > 255) tmpGreen = 255;
			tmpBlue	 = bgBlue  + Math.round((255 - bgBlue)  * 0.5); if (tmpBlue  > 255) tmpBlue  = 255;
			highlight = colorStr(tmpRed, tmpGreen, tmpBlue);
			// shadow1
			tmpRed   = Math.round(bgRed   * 0.75); if (tmpRed   < 0) tmpRed   = 0;
			tmpGreen = Math.round(bgGreen * 0.75); if (tmpGreen < 0) tmpGreen = 0;
			tmpBlue	 = Math.round(bgBlue  * 0.75); if (tmpBlue  < 0) tmpBlue  = 0;
			shadow1 = colorStr(tmpRed, tmpGreen, tmpBlue);
			// shadow2
			tmpRed   = Math.round(bgRed   * 0.45); if (tmpRed   < 0) tmpRed   = 0;
			tmpGreen = Math.round(bgGreen * 0.45); if (tmpGreen < 0) tmpGreen = 0;
			tmpBlue	 = Math.round(bgBlue  * 0.45); if (tmpBlue  < 0) tmpBlue  = 0;
			shadow2 = colorStr(tmpRed, tmpGreen, tmpBlue);
			// hdrShadow
			tmpRed   = Math.round(bgRed   * 0.6); if (tmpRed   < 0) tmpRed   = 0;
			tmpGreen = Math.round(bgGreen * 0.6); if (tmpGreen < 0) tmpGreen = 0;
			tmpBlue	 = Math.round(bgBlue  * 0.6); if (tmpBlue  < 0) tmpBlue  = 0;
			hdrShadow = colorStr(tmpRed, tmpGreen, tmpBlue);
		}

		cmds = descr.cmds;
		contentDiv = descr.contentDiv;
		srcDoc = contentDiv.document;
		userLabels = (typeof(srcDoc.parentWindow.loadUserLabels) != "undefined");
		for (i=0; i < cmds; i++) {
			cmdInfo[i] = new Object();
			cmdInfo[i] = descr.cmdInfo[i];
			cmdInfo[i].enabled = true;
		}
		dashPartID = descr.dashPartID;
		dashPartColor = descr.dashPartColor;
		hdr.dashPartColor = dashPartColor;
		if (dashPartID != null) {
			setDashPartColors();
			// container DIV
			containerDiv = srcDoc.createElement("DIV");
			tmpStyle = containerDiv.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = descr.top;
			tmpStyle.pixelLeft = descr.left;
			tmpStyle.pixelWidth = descr.width;
			tmpStyle.pixelHeight = descr.height;
			tmpStyle.backgroundColor = "#ffffff";
			if (descr.zIndex != 0) {
				tmpStyle.zIndex = descr.zIndex;
				if (srcDoc.parentWindow.dashPartZIndex == null) srcDoc.parentWindow.dashPartZIndex = 1;
				if (descr.zIndex > srcDoc.parentWindow.dashPartZIndex) srcDoc.parentWindow.dashPartZIndex = descr.zIndex;
			}
			// topRightShadow
			topRightShadow = srcDoc.createElement("IMG");
			topRightShadow.src = UI.dashTopShadowImg.src;
			tmpStyle = topRightShadow.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 0;
			tmpStyle.pixelLeft = descr.width - 5;
			tmpStyle.pixelHeight = 5;
			tmpStyle.pixelWidth = 5;
			containerDiv.appendChild(topRightShadow);
			// rightShadow
			rightShadow = srcDoc.createElement("IMG");
			rightShadow.src = UI.dashRightShadowImg.src;
			tmpStyle = rightShadow.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 5;
			tmpStyle.pixelLeft = descr.width - 5;
			tmpStyle.pixelHeight = descr.height - 15; // top (5) + corner shadow (10)
			tmpStyle.pixelWidth = 5;
			if (navigator.appVersion.indexOf('MSIE 5.5') >= 0)
				tmpStyle.cursor = "hand";
			else
				tmpStyle.cursor = "E-resize";
			rightShadow.ondblclick = cancelBubble;
			rightShadow.onclick = cancelBubble;
			rightShadow.onmousedown = hResizeStart;
			rightShadow.onmousemove = hResizeDrag;
			rightShadow.onmouseup = hResizeEnd;
			containerDiv.appendChild(rightShadow);
			// bottomLeftShadow
			bottomLeftShadow = srcDoc.createElement("IMG");
			bottomLeftShadow.src = UI.dashLeftShadowImg.src;
			tmpStyle = bottomLeftShadow.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = descr.height - 5;
			tmpStyle.pixelLeft = 0;
			tmpStyle.pixelHeight = 5;
			tmpStyle.pixelWidth = 5;
			containerDiv.appendChild(bottomLeftShadow);
			// bottomShadow
			bottomShadow = srcDoc.createElement("IMG");
			bottomShadow.src = UI.dashBottomShadowImg.src;
			tmpStyle = bottomShadow.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = descr.height - 5;
			tmpStyle.pixelLeft = 5;
			tmpStyle.pixelHeight = 5;
			tmpStyle.pixelWidth = descr.width - 15; // left (5) + corner shadow (10)
			if (navigator.appVersion.indexOf('MSIE 5.5') >= 0)
				tmpStyle.cursor = "hand";
			else
				tmpStyle.cursor = "N-resize";
			bottomShadow.ondblclick = cancelBubble;
			bottomShadow.onclick = cancelBubble;
			bottomShadow.onmousedown = vResizeStart;
			bottomShadow.onmousemove = vResizeDrag;
			bottomShadow.onmouseup = vResizeEnd;
			containerDiv.appendChild(bottomShadow);
			// bottomRightShadow
			bottomRightShadow = srcDoc.createElement("IMG");
			bottomRightShadow.src = UI.dashCornerShadowImg.src;
			tmpStyle = bottomRightShadow.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = descr.height - 10;
			tmpStyle.pixelLeft = descr.width - 10;
			tmpStyle.pixelHeight = 10;
			tmpStyle.pixelWidth = 10;
			if (navigator.appVersion.indexOf('MSIE 5.5') >= 0)
				tmpStyle.cursor = "hand";
			else
				tmpStyle.cursor = "NW-resize";
			bottomRightShadow.ondblclick = cancelBubble;
			bottomRightShadow.onclick = cancelBubble;
			bottomRightShadow.onmousedown = resizeStart;
			bottomRightShadow.onmousemove = resizeDrag;
			bottomRightShadow.onmouseup = resizeEnd;
			containerDiv.appendChild(bottomRightShadow);
			// adjust descr properties for remaining elements
			descr.top = 0;
			descr.left = 0;
			descr.width -= 5;
		}

		// ctlDiv (heading)
		ctlDiv = srcDoc.createElement("DIV");
		tmpStyle = ctlDiv.style;
		tmpStyle.position = "absolute";
		tmpStyle.pixelTop = descr.top;
		tmpStyle.pixelLeft = descr.left;
		tmpStyle.pixelWidth = descr.width;
		tmpStyle.overflow = "hidden";
		ctlDiv.align = "right";
		if (dashPartID == null) {
			tmpStyle.pixelHeight = 15;
			tmpStyle.backgroundColor = UI.hdrBackground;
		}
		else {
			tmpStyle.pixelHeight = 17;
			tmpStyle.backgroundColor = dashPartColor;
			tmpStyle.border = "1px solid";
			tmpStyle.borderColor = dashPartColor + " " + shadow2 + " " + shadow2 + " " + dashPartColor;
			tmpStyle.cursor = "move";
			ctlDiv.ondblclick = cancelBubble;
			ctlDiv.onclick = cancelBubble;
			ctlDiv.onmousedown = moveStart;
			ctlDiv.onmousemove = moveDrag;
			ctlDiv.onmouseup = moveEnd;
			containerDiv.appendChild(ctlDiv);
			// headerDiv
			headerDiv = srcDoc.createElement("DIV");
			tmpStyle = headerDiv.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 0;
			tmpStyle.pixelLeft = 0;
			tmpStyle.width = "100%";
			tmpStyle.fontSize = "1pt";
			tmpStyle.pixelHeight = 15;
			tmpStyle.backgroundColor = dashPartColor;
			tmpStyle.border = "1px solid";
			tmpStyle.borderColor = highlight + " " + shadow1 + " " + shadow1 + " " + highlight;
			tmpStyle.cursor = "move";
			ctlDiv.appendChild(headerDiv);
		}
		// left corner image of heading DIV
		if (dashPartID == null) {
			headerCorner = srcDoc.createElement("IMG");
			headerCorner.src = UI.sectionImg.src;
			tmpStyle = headerCorner.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelHeight = 15;
			tmpStyle.pixelWidth = 14;
			tmpStyle.pixelTop = 0;
			tmpStyle.pixelLeft = 0;
			ctlDiv.appendChild(headerCorner);
		}
		else {
			// top left corner of header
			tmpElem = srcDoc.createElement("IMG");
			tmpElem.src = UI.dashCornerImg.src;
			tmpStyle = tmpElem.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 0;
			tmpStyle.pixelLeft = 0;
			tmpStyle.pixelHeight = 1;
			tmpStyle.pixelWidth = 1;
			containerDiv.appendChild(tmpElem);
			// top right corner of header
			topRightCorner = srcDoc.createElement("IMG");
			topRightCorner.src = UI.dashCornerImg.src;
			tmpStyle = topRightCorner.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 0;
			tmpStyle.pixelLeft = descr.width - 1;
			tmpStyle.pixelHeight = 1;
			tmpStyle.pixelWidth = 1;
			containerDiv.appendChild(topRightCorner);
		}
	
		if (descr.caption != null) {
			captionCtl = srcDoc.createElement("LABEL");
			captionCtl.id = contentDiv.id + "HdrCaption";
			captionCtl.className = "stdFont";
			captionCtl.innerHTML = descr.caption;
			if (userLabels && !descr.webDashPart) {
				captionCtl.userLabelType = "hdrCaption";
				captionCtl.onmousedown = srcDoc.parentWindow.userLabelClicked;
			}
			tmpStyle = captionCtl.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 0;
			tmpStyle.fontWeight = "bold";
			if (dashPartID == null) {
				tmpStyle.pixelLeft = 15;
				tmpStyle.color = UI.hdrText;
			}
			else {
				tmpStyle.pixelLeft = 6;
				tmpStyle.color = "#ffffff";
				tmpStyle.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
			}
			ctlDiv.appendChild(captionCtl);
		}
		
		for (i=0; i < descr.cmds; i++) {
			if (descr.cmdInfo[i].image != null) {
				tmpElem = srcDoc.createElement("IMG");
				cmdInfo[i].img = tmpElem;
				tmpElem.cmdIndex = i;
				tmpElem.onclick = cmdClick;
				tmpElem.ondblclick = cmdClick;
				tmpElem.onmousedown = cancelBubble;
				tmpElem.onmouseover = mouseOver;
				tmpElem.onmouseout = mouseOut;
				tmpElem.src = descr.cmdInfo[i].image;
				tmpElem.height = 15;
				if (descr.cmdInfo[i].caption == "" || descr.cmdInfo[i].caption == null)
					tmpElem.title = descr.cmdInfo[i].title;
				if (descr.cmdInfo[i].imageWidth != null)
					tmpElem.width = descr.cmdInfo[i].imageWidth;
				tmpStyle = tmpElem.style;
				tmpStyle.position = "relative";
				tmpStyle.marginBottom = "0px";
				tmpStyle.cursor = "hand";
				tmpStyle.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
				ctlDiv.appendChild(tmpElem);
			}
			if (descr.cmdInfo[i].caption != null) {
				tmpElem = srcDoc.createElement("LABEL");
				cmdInfo[i].label = tmpElem;
				tmpElem.cmdIndex = i;
				tmpElem.onclick = cmdClick;
				tmpElem.ondblclick = cmdClick;
				tmpElem.onmousedown = cancelBubble;
				tmpElem.onmouseover = mouseOver;
				tmpElem.onmouseout = mouseOut;
				tmpElem.className = "stdFont";
				tmpElem.innerText = descr.cmdInfo[i].caption;
				tmpStyle = tmpElem.style;
				tmpStyle.position = "relative";
				if ((descr.cmds == 1) && (descr.cmdInfo[i].image == null) && (!descr.collapsible))
					tmpStyle.pixelTop = 1;
				else
					tmpStyle.pixelTop = -2;
				if (dashPartID != null) tmpStyle.pixelTop -= 1;
				tmpStyle.pixelHeight = 14;
				if (dashPartID == null)
					tmpStyle.color = UI.hdrText;
				else
					tmpStyle.color = "#ffffff";
				if ((i == descr.cmds - 1) && !descr.collapsible)
					tmpStyle.marginRight = "6px";
				tmpStyle.marginBottom = "0px";
				tmpStyle.cursor = "hand";
				tmpStyle.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
				ctlDiv.appendChild(tmpElem);
			}
			if (descr.cmdInfo[i].dropdown) {
				tmpElem = srcDoc.createElement("IMG");
				cmdInfo[i].ddwnArrow = tmpElem;
				tmpElem.cmdIndex = i;
				tmpElem.onclick = cmdClick;
				tmpElem.ondblclick = cmdClick;
				tmpElem.onmousedown = cancelBubble;
				tmpElem.onmouseover = mouseOver;
				tmpElem.onmouseout = mouseOut;
				tmpElem.src = UI.hdrDdwnImg.src;
				tmpElem.width = 11;
				tmpElem.height = 15;
				if (descr.cmdInfo[i].caption == "" || descr.cmdInfo[i].caption == null)
					tmpElem.title = descr.cmdInfo[i].title;
				if (descr.cmdInfo[i].imageWidth != null)
					tmpElem.width = descr.cmdInfo[i].imageWidth;
				tmpStyle = tmpElem.style;
				tmpStyle.position = "relative";
				tmpStyle.marginBottom = "0px";
				tmpStyle.cursor = "hand";
				tmpStyle.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
				ctlDiv.appendChild(tmpElem);
			}
			if ((i < descr.cmds - 1) || descr.collapsible) {
				tmpElem = srcDoc.createElement("IMG");
				cmdInfo[i].separator = tmpElem;
				if (descr.cmdInfo[i].caption != null) {
					tmpElem.src = UI.hdrSepImg.src;
					tmpElem.width = 14;
				}
				else {
					tmpElem.src = UI.hdrSep2Img.src;
					tmpElem.width = 10;
				}
				tmpElem.height = 15;
				tmpStyle = tmpElem.style;
				tmpStyle.position = "relative";
				tmpStyle.marginBottom = "0px";
				tmpStyle.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
				ctlDiv.appendChild(tmpElem);
			}
		}
		
		if (descr.collapsible) {
			collapseImg = srcDoc.createElement("IMG");
			collapseImg.enabled = true;
			collapseImg.action = "Collapse";
			collapseImg.viewState = "Expanded";
			collapseImg.onclick = toggleContentDisplay;
			collapseImg.onmousedown = cancelBubble;
			collapseImg.width = 9;
			collapseImg.height = 15;
			collapseImg.src = UI.hdrCollapseImg.src;
			tmpStyle = collapseImg.style;
			tmpStyle.position = "relative";
			tmpStyle.marginLeft = "1px";
			tmpStyle.marginRight = "4px";
			tmpStyle.marginBottom = "0px";
			tmpStyle.cursor = "default";
			if (dashPartID != null) tmpStyle.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
			ctlDiv.appendChild(collapseImg);
		}
		
		if (dashPartID == null)
			contentDiv.parentElement.insertBefore(ctlDiv, contentDiv);
		else {
			contentDiv.parentElement.insertBefore(containerDiv, contentDiv);
			containerDiv.appendChild(contentDiv);
			tmpStyle = contentDiv.style;
			tmpStyle.position = "absolute";
			tmpStyle.pixelTop = 17;
			tmpStyle.pixelLeft = 0;
			tmpStyle.pixelHeight = descr.height - 22; // header (17) + bottom shadow (5)
			tmpStyle.pixelWidth = descr.width;
			tmpStyle.overflow = "auto";
			tmpStyle.borderLeft = "solid 1px";
			tmpStyle.borderLeftColor = highlight;
		}
		if (userLabels && (captionCtl != null) && !descr.webDashPart) setUserLabel(captionCtl);
		if (dashPartID != null) {
			if (descr.viewState == "Collapsed") _collapse();
			if (descr.zIndex == 0) moveToTop();
		}
	}

	function cancelBubble() {
		this.document.parentWindow.event.cancelBubble = true;
	}

	function hResizeStart() {
		var eventObj = this.document.parentWindow.event;
		var srcElem = this;
		eventObj.cancelBubble = true;
		if (eventObj.button > 1) return;
		if (maximized) return;
		dragInitHPos = srcElem.style.pixelLeft;
		dragInitClientHPos = eventObj.clientX;
		dragObj = srcElem;
		dragging = true;
		moveToTop();
		srcElem.setCapture();
	}

	function hResizeDrag() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		hResize(newLeft);
	}

	function hResizeEnd() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		dragging = false;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		hResize(newLeft);
		dragObj.releaseCapture();
		dashPartAdjust();
	}

	function hResize(leftPos) {
		var mod = leftPos % 10;
		if (!dragging && (mod != 0)) {
			if (Math.abs(mod) < 5)
				leftPos -= mod;
			else
				if (mod > 0)
					leftPos += 10 - mod;
				else
					leftPos -= 10 - Math.abs(mod);
		}
		if (leftPos < 50) leftPos = 50;
		containerDiv.style.pixelWidth = leftPos + 5;
		topRightShadow.style.pixelLeft = leftPos;
		rightShadow.style.pixelLeft = leftPos;
		topRightCorner.style.pixelLeft = leftPos - 1;
		ctlDiv.style.pixelWidth = leftPos;
		contentDiv.style.pixelWidth = leftPos;
		bottomShadow.style.pixelWidth = leftPos - 10;
		bottomRightShadow.style.pixelLeft = leftPos - 5;
	}

	function vResizeStart() {
		var eventObj = this.document.parentWindow.event;
		var srcElem = this;
		eventObj.cancelBubble = true;
		if (eventObj.button > 1) return;
		if (collapseImg.viewState == "Collapsed") return;
		if (maximized) return;
		dragInitVPos = srcElem.style.pixelTop;
		dragInitClientVPos = eventObj.clientY;
		dragObj = srcElem;
		dragging = true;
		moveToTop();
		srcElem.setCapture();
	}

	function vResizeDrag() {
		var eventObj = this.document.parentWindow.event;
		var newTop;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		vResize(newTop);
	}

	function vResizeEnd() {
		var eventObj = this.document.parentWindow.event;
		var newTop;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		dragging = false;
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		vResize(newTop);
		dragObj.releaseCapture();
		dashPartAdjust();
	}

	function vResize(topPos) {
		var mod = topPos % 10;
		if (!dragging && (mod != 0)) {
			if (Math.abs(mod) < 5)
				topPos -= mod;
			else
				if (mod > 0)
					topPos += 10 - mod;
				else
					topPos -= 10 - Math.abs(mod);
		}
		if (topPos < 20) topPos = 20;
		containerDiv.style.pixelHeight = topPos + 5;
		bottomLeftShadow.style.pixelTop = topPos;
		bottomShadow.style.pixelTop = topPos;
		contentDiv.style.pixelHeight = topPos - 17;
		rightShadow.style.pixelHeight = topPos - 10;
		bottomRightShadow.style.pixelTop = topPos - 5;
	}

	function resizeStart() {
		var eventObj = this.document.parentWindow.event;
		var srcElem = this;
		eventObj.cancelBubble = true;
		if (eventObj.button > 1) return;
		if (collapseImg.viewState == "Collapsed") return;
		if (maximized) return;
		dragInitHPos = srcElem.style.pixelLeft;
		dragInitVPos = srcElem.style.pixelTop;
		dragInitClientHPos = eventObj.clientX;
		dragInitClientVPos = eventObj.clientY;
		dragObj = srcElem;
		dragging = true;
		moveToTop();
		srcElem.setCapture();
	}

	function resizeDrag() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		var newTop;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		hResize(newLeft + 5);
		vResize(newTop + 5);
	}

	function resizeEnd() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		var newTop;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		dragging = false;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		hResize(newLeft + 5);
		vResize(newTop + 5);
		dragObj.releaseCapture();
		dashPartAdjust();
	}

	function moveStart() {
		var eventObj = this.document.parentWindow.event;
		var srcElem = this;
		eventObj.cancelBubble = true;
		if (eventObj.button > 1) return;
		if (maximized) return;
		dragInitHPos = containerDiv.style.pixelLeft;
		dragInitVPos = containerDiv.style.pixelTop;
		dragInitClientHPos = eventObj.clientX;
		dragInitClientVPos = eventObj.clientY;
		dragObj = srcElem;
		dragging = true;
		moveToTop();
		srcElem.setCapture();
	}

	function moveDrag() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		var newTop;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		if (newLeft < 0) newLeft = 0;
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		if (newTop < 0) newTop = 0;
		containerDiv.style.pixelLeft = newLeft;
		containerDiv.style.pixelTop = newTop;
	}

	function moveEnd() {
		var eventObj = this.document.parentWindow.event;
		var newLeft;
		var newTop;
		var mod;
		var tmpStyle;
		eventObj.cancelBubble = true;
		if (!dragging) return;
		dragging = false;
		newLeft = dragInitHPos + eventObj.clientX - dragInitClientHPos;
		if (newLeft < 0) newLeft = 0;
		mod = newLeft % 10;
		if (!dragging && (mod != 0)) {
			if (mod < 5)
				newLeft -= mod;
			else
				newLeft += 10 - mod;
		}
		newTop = dragInitVPos + eventObj.clientY - dragInitClientVPos;
		if (newTop < 0) newTop = 0;
		mod = newTop % 10;
		if (!dragging && (mod != 0)) {
			if (mod < 5)
				newTop -= mod;
			else
				newTop += 10 - mod;
		}
		containerDiv.style.pixelLeft = newLeft;
		containerDiv.style.pixelTop = newTop;
		dragObj.releaseCapture();
		dashPartAdjust();
	}

	function moveToTop() {
		if (srcDoc.parentWindow.dashPartZIndex == null)
			srcDoc.parentWindow.dashPartZIndex = 1;
		else
			srcDoc.parentWindow.dashPartZIndex++;
		containerDiv.style.zIndex = srcDoc.parentWindow.dashPartZIndex;
		hdr.zIndex = containerDiv.style.zIndex;
	}

	function dashPartAdjust() {
		var tmpStyle;
		tmpStyle = containerDiv.style;
		if (hdr.myDashPartAdjust != null)
			hdr.myDashPartAdjust(dashPartID, contentDiv, hdr, tmpStyle.pixelTop, tmpStyle.pixelLeft, contentDiv.style.pixelHeight + 20, tmpStyle.pixelWidth, collapseImg.viewState);
	}

	function cmdClick() {
		var cmd = cmdInfo[this.cmdIndex];
		if (cmd.enabled && (cmd.callBack != null)) cmd.callBack(dashPartID, contentDiv, hdr);
	}

	function mouseOver() {
		var cmd = cmdInfo[this.cmdIndex];
		if (!cmd.enabled) return;
		if (cmd.img != null)
			cmd.img.style.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
		if (cmd.ddwnArrow != null)
			cmd.ddwnArrow.style.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
		if (cmd.label != null) {
			cmd.label.style.textDecorationUnderline = true;
			cmd.label.style.color = "#ffffcc";
		}
	}

	function mouseOut() {
		var cmd = cmdInfo[this.cmdIndex];
		if (!cmd.enabled) return;
		if (cmd.img != null)
			cmd.img.style.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
		if (cmd.ddwnArrow != null)
			cmd.ddwnArrow.style.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
		if (cmd.label != null) {
			cmd.label.style.textDecorationUnderline = false;
			cmd.label.style.color = "#ffffff";
		}
	}

	function _disableCmd(cmdName) {
		var i;
		var cmd;
		for (i=0; i < cmds; i++)
			if (cmdInfo[i].name == cmdName) break;
		if (i == cmds) return;
		cmd = cmdInfo[i];
		cmd.enabled = false;
		if (cmd.img != null) {
			cmd.img.style.filter = "gray alpha(opacity=70)";
			cmd.img.style.cursor = "default";
		}
		if (cmd.ddwnArrow != null) {
			cmd.ddwnArrow.style.filter = "gray alpha(opacity=70)";
			cmd.ddwnArrow.style.cursor = "default";
		}
		if (cmd.label != null) {
			cmd.label.style.filter = "alpha(opacity=70)";
			cmd.label.style.cursor = "default";
		}
	}

	function _enableCmd(cmdName) {
		var i;
		var cmd;
		for (i=0; i < cmds; i++)
			if (cmdInfo[i].name == cmdName) break;
		if (i == cmds) return;
		cmd = cmdInfo[i];
		cmd.enabled = true;
		if (cmd.img != null) {
			cmd.img.style.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
			cmd.img.style.cursor = "hand";
		}
		if (cmd.ddwnArrow != null) {
			cmd.ddwnArrow.style.filter = "gray dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
			cmd.ddwnArrow.style.cursor = "hand";
		}
		if (cmd.label != null) {
			cmd.label.style.filter = "dropShadow(color=" + hdrShadow + ",offX=1,offY=1)";
			cmd.label.style.cursor = "hand";
		}
	}

	function _disableAll() {
		var i;
		for (i=0; i < cmds; i++) _disableCmd(cmdInfo[i].name);
	}

	function _enableAll() {
		var i;
		for (i=0; i < cmds; i++) _enableCmd(cmdInfo[i].name);
	}

	function _hideCmd(cmdName) {
		var i;
		var cmd;
		for (i=0; i < cmds; i++)
			if (cmdInfo[i].name == cmdName) break;
		if (i == cmds) return;
		cmd = cmdInfo[i];
		cmd.enabled = true;
		if (cmd.img != null) cmd.img.style.display = "none";
		if (cmd.ddwnArrow != null) cmd.ddwnArrow.style.display = "none";
		if (cmd.label != null) cmd.label.style.display = "none";
		if (cmd.separator != null) cmd.separator.style.display = "none";
	}

	function _showCmd(cmdName) {
		var i;
		var cmd;
		for (i=0; i < cmds; i++)
			if (cmdInfo[i].name == cmdName) break;
		if (i == cmds) return;
		cmd = cmdInfo[i];
		cmd.enabled = true;
		if (cmd.img != null) cmd.img.style.display = "inline";
		if (cmd.ddwnArrow != null) cmd.ddwnArrow.style.display = "inline";
		if (cmd.label != null) cmd.label.style.display = "inline";
		if (cmd.separator != null) cmd.separator.style.display = "inline";
	}

	function toggleContentDisplay() {
		var children;
		var childCount;
		var i;
		var offset;
		if (!collapseImg.enabled) return;
		if (collapseImg.action == "Collapse") {
			contentDiv.style.display = "none";
			offset = -contentDiv.style.pixelHeight;
			collapseImg.src = UI.hdrExpandImg.src;
			collapseImg.action = "Expand";
			collapseImg.viewState = "Collapsed";
			if (dashPartID != null) {
				containerDiv.style.pixelHeight = 22;
				rightShadow.style.pixelHeight = 7;
				bottomLeftShadow.style.pixelTop = 17;
				bottomShadow.style.pixelTop = 17;
				bottomShadow.style.cursor = "default";
				bottomRightShadow.style.pixelTop = 12;
				bottomRightShadow.style.cursor = "default";
			}
		}
		else {
			contentDiv.style.display = "block";
			offset = contentDiv.style.pixelHeight;
			collapseImg.src = UI.hdrCollapseImg.src;
			collapseImg.action = "Collapse";
			collapseImg.viewState = "Expanded";
			if (dashPartID != null) {
				containerDiv.style.pixelHeight = offset + 22;
				rightShadow.style.pixelHeight = offset + 7;
				bottomLeftShadow.style.pixelTop = offset + 17;
				bottomShadow.style.pixelTop = offset + 17;
				bottomRightShadow.style.pixelTop = offset + 12;
				if (navigator.appVersion.indexOf('MSIE 5.5') >= 0) {
					bottomShadow.style.cursor = "hand";
					bottomRightShadow.style.cursor = "hand";
				}
				else {
					bottomShadow.style.cursor = "N-resize";
					bottomRightShadow.style.cursor = "NW-resize";
				}
			}
		}
		if (!hdr.ovrMoveControls) {
			children = ctlDiv.parentElement.children;
			childCount = children.length;
			for (i=0; i < childCount; i++) {
			  if (children[i] == contentDiv) break;
			}
			for (i=i+1; i < childCount; i++)
				children[i].style.pixelTop += offset;
		}
		if (hdr.myMoveControls != null) hdr.myMoveControls(offset, dashPartID);
		if (dashPartID != null) {
			moveToTop();
			dashPartAdjust();
		}
	}

	function _resize(width, height) {
		if (dashPartID == null)
			ctlDiv.style.pixelWidth = width;
		else {
			containerDiv.style.pixelWidth = width;
			topRightShadow.style.pixelLeft = width - 5;
			rightShadow.style.pixelLeft = width - 5;
			topRightCorner.style.pixelLeft = width - 6;
			ctlDiv.style.pixelWidth = width - 5;
			contentDiv.style.pixelWidth = width - 5;
			bottomShadow.style.pixelWidth = width - 15;
			bottomRightShadow.style.pixelLeft = width - 10;
			if (collapseImg.viewState == "Expanded") {
				containerDiv.style.pixelHeight = height;
				bottomLeftShadow.style.pixelTop = height - 5;
				bottomShadow.style.pixelTop = height - 5;
				rightShadow.style.pixelHeight = height - 15;
				bottomRightShadow.style.pixelTop = height - 10;
			}
			contentDiv.style.pixelHeight = height - 22;
			moveToTop();
			dashPartAdjust();
		}
	}

	function _show() {
		if (dashPartID == null)
			ctlDiv.style.visibility = "inherit";
		else {
			containerDiv.style.display = "block";
			moveToTop();
		}
	}

	function _hide() {
		if (dashPartID == null)
			ctlDiv.style.visibility = "hidden";
		else
			containerDiv.style.display = "none";
	}

	function _setCaption(newCaption) {
		captionCtl.innerHTML = newCaption;
	}

	function _setPosition(top, left) {
		if (dashPartID == null) {
			ctlDiv.style.pixelTop = top;
			ctlDiv.style.pixelLeft = left;
		}
		else {
			containerDiv.style.pixelTop = top;
			containerDiv.style.pixelLeft = left;
			moveToTop();
			dashPartAdjust();
		}
	}

	function _remove() {
		_cleanUp(true);
		
	}

	function _cleanUp(removeFromDOM) {
		var i;
		if (cleaned) return;
		cleaned = true;
		hdr = null;
		for (i=0; i < cmds; i++) {
			cmdInfo[i].callBack = null;
			if (cmdInfo[i].img != null) {
				cmdInfo[i].img.onclick = null;
				cmdInfo[i].img.ondblclick = null;
				cmdInfo[i].img.onmousedown = null;
				cmdInfo[i].img.onmouseover = null;
				cmdInfo[i].img.onmouseout = null;
				cmdInfo[i].img = null;
			}
			if (cmdInfo[i].ddwnArrow != null) {
				cmdInfo[i].ddwnArrow.onclick = null;
				cmdInfo[i].ddwnArrow.ondblclick = null;
				cmdInfo[i].ddwnArrow.onmousedown = null;
				cmdInfo[i].ddwnArrow.onmouseover = null;
				cmdInfo[i].ddwnArrow.onmouseout = null;
				cmdInfo[i].ddwnArrow = null;
			}
			if (cmdInfo[i].label != null) {
				cmdInfo[i].label.onclick = null;
				cmdInfo[i].label.ondblclick = null;
				cmdInfo[i].label.onmousedown = null;
				cmdInfo[i].label.onmouseover = null;
				cmdInfo[i].label.onmouseout = null;
				cmdInfo[i].label = null;
			}
			if (cmdInfo[i].separator != null) cmdInfo[i].separator = null;
		}
		if (collapseImg != null) {
			collapseImg.onclick = null;
			collapseImg.onmousedown = null;
			collapseImg = null;
		}
		if (captionCtl != null) {
			captionCtl.onmousedown = null;
			captionCtl = null;
		}
		if (dashPartID != null) {
			ctlDiv.ondblclick = null;
			ctlDiv.onclick = null;
			ctlDiv.onmousedown = null;
			ctlDiv.onmousemove = null;
			ctlDiv.onmouseup = null;
		}
		ctlDiv = null;
		srcDoc = null;
		if (dashPartID != null) {
			topRightShadow = null;
			rightShadow.ondblclick = null;
			rightShadow.onclick = null;
			rightShadow.onmousedown = null;
			rightShadow.onmousemove = null;
			rightShadow.onmouseup = null;
			rightShadow = null;
			bottomLeftShadow = null;
			bottomShadow.ondblclick = null;
			bottomShadow.onclick = null;
			bottomShadow.onmousedown = null;
			bottomShadow.onmousemove = null;
			bottomShadow.onmouseup = null;
			bottomShadow = null;
			bottomRightShadow.ondblclick = null;
			bottomRightShadow.onclick = null;
			bottomRightShadow.onmousedown = null;
			bottomRightShadow.onmousemove = null;
			bottomRightShadow.onmouseup = null;
			bottomRightShadow = null;
			topRightCorner = null;
			headerDiv = null;
			contentDiv.innerHTML = "";
		}
		contentDiv = null;
		headerCorner = null;
		this.myMoveControls = null;
		if (removeFromDOM) containerDiv.parentElement.removeChild(containerDiv);
		containerDiv = null;
	}
}

function MsgCtl() {
	this.msgbox = _msgbox;

	this.OKOnly = 0;          
	this.OKCancel = 1;        
	this.AbortRetryIgnore = 2;
	this.YesNoCancel = 3;     
	this.YesNo = 4;           
	this.RetryCancel = 5;     
	this.Critical = 16;       
	this.Question = 32;       
	this.Exclamation = 48;    
	this.Information = 64;    
	this.DefaultButton1 = 0;  
	this.DefaultButton2 = 256;
	this.DefaultButton3 = 512;
	this.CrLf = "^^^^";        

	this.OK = 1;    
	this.Cancel = 2;
	this.Abort = 3; 
	this.Retry = 4; 
	this.Ignore = 5;
	this.Yes = 6;   
	this.No = 7;    
	
	function _msgbox(caller, msg, options, title, width)
	{
		if (global == null)	return false

		var teststr;
		var buttons;
		var bitmap;
		var defaultBttn;
		var mask;
		var i;
		var msgwidth = 0;
		var linewidth;
		var msgheight;
		var msgtop = 25;
		var msgleft = 62;
		var appVersionArray;
		var args = new Object();
		args.global = global;
		args.msg = new Array();
		args.button = new Array();
		args.buttonVal = new Array();
		
		if (msg == null || msg == "") return 0;
		msg = msg.toString();
		if (options == null) options = 0;
		if (title == null) title = "Deltek Vision"
		args.title = title;
		//get number of lines and width of longest
		teststr = msg.split("^^^^");
		//Set width for reporting messageboxes that do not have a appTitle available
		if ((top.appTitle == null) && (width == null))
			width = 350;

		if (width != null) msgwidth = width;
		msgheight = 16 * teststr.length;
		for (var i = 0; i < teststr.length; i++) {
			if (width == null) {
				linewidth = top.textWidthInPixels(top.titleGraphic2.document, teststr[i], "stdFont");
				if (linewidth > msgwidth)
					msgwidth = linewidth;
			}
			args.msg[i] = teststr[i];
		}
		args.msgwidth = msgwidth;
		args.msgheight = msgheight;
		
		//get buttons
		buttons = options & 15;
		switch (buttons) {
			case this.OKCancel:
				args.button[0] = "OK";
				args.buttonVal[0] = this.OK;
				args.button[1] = "Cancel";
				args.buttonVal[1] = this.Cancel;
				args.returnVal = this.Cancel;
				break;
			case this.AbortRetryIgnore:
				args.button[0] = "Abort";
				args.buttonVal[0] = this.Abort;
				args.button[1] = "Retry";
				args.buttonVal[1] = this.Retry;
				args.button[2] = "Ignore";
				args.buttonVal[2] = this.Ignore;
				args.returnVal = this.Ignore;
				break;
			case this.YesNoCancel:
				args.button[0] = "Yes";
				args.buttonVal[0] = this.Yes;
				args.button[1] = "No";
				args.buttonVal[1] = this.No;
				args.button[2] = "Cancel";
				args.buttonVal[2] = this.Cancel;
				args.returnVal = this.Cancel;
				break;
			case this.YesNo:
				args.button[0] = "Yes";
				args.buttonVal[0] = this.Yes;
				args.button[1] = "No";
				args.buttonVal[1] = this.No;
				args.returnVal = this.No;
				break;
			case this.RetryCancel:
				args.button[0] = "Retry";
				args.buttonVal[0] = this.Retry;
				args.button[1] = "Cancel";
				args.buttonVal[1] = this.Cancel;
				args.returnVal = this.Cancel;
				break;
			default:
				args.button[0] = "OK";
				args.buttonVal[0] = this.OK;
				args.returnVal = this.OK;
		}
		minbttnwidth = 12 + (args.button.length * 80) - 5 + 22;

		//get bitmap
		bitmap = options & 240;
		switch (bitmap) {
			case this.Critical:
				args.bitmap = "msgbox01.ico";
				break;
			case this.Question:
				args.bitmap = "msgbox02.ico";
				break;
			case this.Exclamation:
				args.bitmap = "msgbox03.ico";
				break;
			case this.Information:
				args.bitmap = "msgbox04.ico";
				break;
			default:
				args.bitmap = "";
				msgtop = 12;
				msgleft = 12;
		}

		//get default button
		defaultBttn = options & 3840;
		switch (defaultBttn) {
			case this.DefaultButton2:
				args.defaultBttn = 1;
				break;
			case this.DefaultButton3:
				args.defaultBttn = 2;
				break;
			default:
				args.defaultBttn = 0;
		}
		var dialogHeight = msgtop + (args.msg.length * 13) + 95;
		appVersionArray = clientInformation.appVersion.split(";");
		if (appVersionArray[2].indexOf("Windows NT 5.1") >= 0) dialogHeight += 7; // add 7 pixels if Windows XP
		var dialogWidth = msgleft + msgwidth + 40;
		if (dialogWidth < minbttnwidth) dialogWidth = minbttnwidth;
		
		args = caller.showModalDialog("DLGmsgCtl.htm", args, "dialogwidth: " + dialogWidth + "px; dialogheight: " + dialogHeight + "px; status: no; scroll: no; help: no")
		return args.returnVal;
	}
}

/*  This is the RemoteCall object which is used for making calls
	to COM+ components via the web server.  This object
	packs up parameters in an XML document and sends that document to
	the MethodCall.asp page which makes the call and sends the
	results back via another XML document.  Using this object is
	easy, just create the object and use the makeCall method to
	execute a COM+ method.

*/
function RemoteCall(){
	this.classname = "";
	this.methodname = "";
	this.paramlist = null;
	this.retval = "";
	this.aspURL="MethodCall.asp";
	this.makeCall = _makeCall;
	this.makeAsyncCall = _makeAsyncCall;
	this.setTimeout = _setTimeout;
	this.loadXML = _loadXML;
	
	var tmpdom
	var dom
	var host
	var hostAsync;
	var cbAsync
	var retObj
	var rcErrors
	var obj = this;
	var timeout = 0;
    var loadXMLArray = new Array()
    
	function _makeCall(classname,methodname,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10){
		retObj = new Object();
		this.paramlist = new Array();
		var e,root,err
		rcErrors = new Exception();
		if(typeof(arg1) != "undefined") this.paramlist[0] = arg1
		if(typeof(arg2) != "undefined") this.paramlist[1] = arg2
		if(typeof(arg3) != "undefined") this.paramlist[2] = arg3
		if(typeof(arg4) != "undefined") this.paramlist[3] = arg4
		if(typeof(arg5) != "undefined") this.paramlist[4] = arg5
		if(typeof(arg6) != "undefined") this.paramlist[5] = arg6
		if(typeof(arg7) != "undefined") this.paramlist[6] = arg7
		if(typeof(arg8) != "undefined") this.paramlist[7] = arg8
		if(typeof(arg9) != "undefined") this.paramlist[8] = arg9
		if(typeof(arg10) != "undefined") this.paramlist[9] = arg10

		this.params = this.paramlist.length
		this.classname = classname
		this.methodname = methodname
		rcErrors.clearErrors();
		try {
			host = new ActiveXObject("Microsoft.XMLHTTP")
			host.open("POST", this.aspURL, false)

			dom = new ActiveXObject("Microsoft.XMLDOM")
			dom.async = false
			dom.preserveWhiteSpace = true;
			tmpdom = new ActiveXObject("Microsoft.XMLDOM")
			tmpdom.async = false
			tmpdom.validateOnParse = false;

			root = dom.createElement("methodcall")
			dom.appendChild(root)
			root.setAttribute("params",this.params)
			e = dom.createElement("sessionid")
			e.text = sessionID
			root.appendChild(e)
			e = dom.createElement("class")
			e.text = this.classname
			root.appendChild(e)
			e = dom.createElement("function")
			e.text = this.methodname
			root.appendChild(e)
			
			if (DEBUG){
			    e = dom.createElement("DEBUG")
			    root.appendChild(e)
			}
			
			if(timeout > 0){
			    e = dom.createElement("TIMEOUT");
			    e.text = timeout;
			    root.appendChild(e);
			    timeout = 0;
			}

			for(i = 0;i < this.params;i++){
				e = dom.createElement("param" + i)
				_setNodeValue(e,this.paramlist[i])
				root.appendChild(e)
			}
			
			if(DEBUG){
				var clientTimer = new Timer();
				clientTimer.start();
			}
			host.send(dom);
			if(DEBUG){
				var clientTime = clientTimer.stop()/1000;
			}
			
			//Clear out the loadXMLArray in case this object is reused for multiple requests
			loadXMLArray = new Array();
			
		}catch(err){
			rcErrors.addError(err.description + " " + classname + " " + methodname,err.number,"RemoteCall","MakeCall")
		}

		if(host.status == "200"){
			dom = host.responseXML
			e = dom.documentElement.selectSingleNode("ERRORS")
			if(e != null){ //If an "ERRORS" node exists, there are errors
				if (! rcErrors.invalidSessionError(e)){
					rcErrors.buildErrorList(e);
				}else{
					if (windowStack == null)
						topWindow = window;
					else
						topWindow = windowStack[windowStack.length - 1];				
					var loginDlgArgs;
					loginDlgArgs = new Object();
					loginDlgArgs.reLogin = true;
					loginDlgArgs.global = top;
					loginDlgArgs.repost = false;					
					loginDlgArgs = openDialog(topWindow, "login.asp", 400, 400, "Re-Login", loginDlgArgs);
					if (! loginDlgArgs.cancel){
						retObj = obj.makeCall(classname,methodname,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)
						return retObj;
					}else{
						rcErrors.buildErrorList(e);
					}
					
				}
			}
			t = dom.documentElement.selectSingleNode("timer")
			if(t != null){ //If a "timer" node exists, log the server-side time
				logEvent(classname + "." + methodname,"Server-side time=" + t.text + " client-side time=" + clientTime);
			}
			this.retval = dom.documentElement.selectSingleNode("return").text
			for(i = 0;i < this.params;i++){
				this.paramlist[i] = _getNodeValue(dom.documentElement.selectSingleNode("param"+i))
			}
			//debugger
			//logEvent("Download size",dom.xml.length);
		}else{
			rcErrors.addError("Received status of " + host.status +
			                    " from MethodCall.asp.  Details:\r\n\r\n" +
			                    host.responseText,0,"RemoteCall","makeCall");
		}
		retObj.retval = this.retval;
		retObj.errorObj = rcErrors;
		retObj.params = this.paramList;
		if(DEBUG) logCall(classname,methodname,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,retObj)
		return retObj;
	}

	function _setNodeValue(node,val){
	    node.text = val
	    for (var i=0;i<loadXMLArray.length;i++)
			if (loadXMLArray[i].xmlFile == val) {
				node.setAttribute("loadType", "xml")
				node.setAttribute("xPath", loadXMLArray[i].xPath)
				node.setAttribute("copyChildren", loadXMLArray[i].copyChildren)
			}
	}

	function _loadXML(param, xPath, copyChildren){
		var index = loadXMLArray.length;
		var newObj = new Object();
		
		newObj.xmlFile = param;
		if (xPath > "")
			newObj.xPath = xPath;
		else
			newObj.xPath = "";
			
		if ((copyChildren == null) || (copyChildren))
			newObj.copyChildren = "Y";
		else
			newObj.copyChildren = "N";
		
		loadXMLArray[index] = newObj;
	}
	
	function _getNodeValue(node){
	    return node.text
	}
	function _makeAsyncCall(callBack,classname,methodname,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10){
		retObj = new Object();
		this.paramlist = new Array();
		var e,root,err
		rcErrors = new Exception();
		cbAsync = callBack
		
		if(typeof(arg1) != "undefined") this.paramlist[0] = arg1
		if(typeof(arg2) != "undefined") this.paramlist[1] = arg2
		if(typeof(arg3) != "undefined") this.paramlist[2] = arg3
		if(typeof(arg4) != "undefined") this.paramlist[3] = arg4
		if(typeof(arg5) != "undefined") this.paramlist[4] = arg5
		if(typeof(arg6) != "undefined") this.paramlist[5] = arg6
		if(typeof(arg7) != "undefined") this.paramlist[6] = arg7
		if(typeof(arg8) != "undefined") this.paramlist[7] = arg8
		if(typeof(arg9) != "undefined") this.paramlist[8] = arg9
		if(typeof(arg10) != "undefined") this.paramlist[9] = arg10

		this.params = this.paramlist.length
		this.classname = classname
		this.methodname = methodname
		rcErrors.clearErrors();
		try {
			hostAsync = new ActiveXObject("Microsoft.XMLHTTP")
			hostAsync.open("POST", this.aspURL, true)
			hostAsync.onreadystatechange = watchHostReturn;

			dom = new ActiveXObject("Microsoft.XMLDOM")
			dom.async = false
			tmpdom = new ActiveXObject("Microsoft.XMLDOM")
			tmpdom.async = false

			root = dom.createElement("methodcall")
			dom.appendChild(root)
			root.setAttribute("params",this.params)
			e = dom.createElement("sessionid")
			e.text = sessionID
			root.appendChild(e)
			e = dom.createElement("class")
			e.text = this.classname
			root.appendChild(e)
			e = dom.createElement("function")
			e.text = this.methodname
			root.appendChild(e)
			
			if (DEBUG){
			    e = dom.createElement("DEBUG")
			    root.appendChild(e)
			}

			for(i = 0;i < this.params;i++){
				e = dom.createElement("param" + i)
				_setNodeValue(e,this.paramlist[i])
				root.appendChild(e)
			}
			hostAsync.send(dom);
		}catch(err){
			rcErrors.addError(err.description + " " + classname + " " + methodname,err.number,"RemoteCall","MakeCall")
		}
	}
	
	function watchHostReturn(){
	    if(hostAsync.readyState == 4){
		    if(hostAsync.status == "200"){
		    	dom = hostAsync.responseXML
		    	e = dom.documentElement.selectSingleNode("ERRORS")
				if(e != null){ //If an "ERRORS" node exists, there are errors
					if (! rcErrors.invalidSessionError(e)){
						rcErrors.buildErrorList(e);
					}else{
						if (windowStack == null)
							topWindow = window;
						else
							topWindow = windowStack[windowStack.length - 1];				
						var loginDlgArgs;
						loginDlgArgs = new Object();
						loginDlgArgs.reLogin = true;
						loginDlgArgs.global = top;
						loginDlgArgs.repost = false;					
						loginDlgArgs = openDialog(topWindow, "login.asp", 400, 400, "Re-Login", loginDlgArgs);
						if (! loginDlgArgs.cancel){
							obj.makeAsyncCall(cbAsync,obj.classname,obj.methodname,obj.paramlist[0],obj.paramlist[1],obj.paramlist[2],obj.paramlist[3],obj.paramlist[4],obj.paramlist[5],obj.paramlist[6],obj.paramlist[7],obj.paramlist[8],obj.paramlist[9],obj.paramlist[10])
							return;
						}else{
							rcErrors.buildErrorList(e);
						}
						
					}
				}
		    	obj.retval = dom.documentElement.selectSingleNode("return").text
		    	for(i = 0;i < obj.params;i++){
		    		obj.paramlist[i] = _getNodeValue(dom.documentElement.selectSingleNode("param"+i))
		    	}
		    	//return this.retval
		    }else{
		    	rcErrors.addError("Received status of " + hostAsync.status +
		    	                    " from MethodCall.asp.  Details:\r\n\r\n" +
		    	                    hostAsync.responseText,0,"RemoteCall","makeCall");
		    }
		    retObj.retval = obj.retval;
		    retObj.errorObj = rcErrors;
		    retObj.params = obj.paramList;
		    if (DEBUG) logCall(obj.classname,obj.methodname,obj.paramlist[0],
		                             obj.paramlist[1],obj.paramlist[2],
		                             obj.paramlist[3],obj.paramlist[4],
		                             obj.paramlist[5],obj.paramlist[6],
		                             obj.paramlist[7],obj.paramlist[8],
		                             obj.paramlist[9],retObj)
		    cbAsync(retObj);
		}
	}
	
	function logCall(classname,methodname,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,retObj){
	    var desc = "RemoteCall method";
	    var msg = classname + "." + methodname + "(" + sessionID;
	    if(typeof(arg1) != "undefined") msg += ",\"" + arg1 + "\"";
        if(typeof(arg2) != "undefined") msg += ",\"" + arg2 + "\"";
        if(typeof(arg3) != "undefined") msg += ",\"" + arg3 + "\"";
        if(typeof(arg4) != "undefined") msg += ",\"" + arg4 + "\"";
        if(typeof(arg5) != "undefined") msg += ",\"" + arg5 + "\"";
        if(typeof(arg6) != "undefined") msg += ",\"" + arg6 + "\"";
        if(typeof(arg7) != "undefined") msg += ",\"" + arg7 + "\"";
        if(typeof(arg8) != "undefined") msg += ",\"" + arg8 + "\"";
        if(typeof(arg9) != "undefined") msg += ",\"" + arg9 + "\"";
        if(typeof(arg10) != "undefined") msg += ",\"" + arg10 + "\"";
        msg += ") returning \"" + retObj.retval + "\"";
        logEvent(desc,msg);
	}
	
	function _setTimeout(val){
	    timeout = val;
	}
}

function FileSaveAsCtl(srcDoc) {
	registerCtl(this);
	var cleaned = false;
	
	var serverXMLParms = null;
	this.fileName="";
	this.method="";
	this.className=""
	var curObj = this
	this.cleanUp = _cleanUp
	var frm=null;
	
	this.setServerParm = _setServerParm;
	this.saveAs = _saveAs;
		
	function _setServerParm(name, value) {
		serverXMLParms = setParm(serverXMLParms, name, value)
	}
	
	var newFrm = srcDoc.createElement('<IFRAME id=iFrm name="nmIFrm" style="display:none"></IFRAME>')
	
	srcDoc.body.appendChild(newFrm)
	
	
	function _saveAs() {
				
		try {				
			
			frm = srcDoc.createElement("FORM"); 
			
			var inpt; 
		
			inpt = srcDoc.createElement("INPUT")
		
			inpt.type="text"
			inpt.name="xmlParms"
			inpt.value = serverXMLParms.xml
		
			frm.appendChild(inpt)
		
			inpt = srcDoc.createElement("INPUT")
			inpt.type="text"
			inpt.name="method"
			inpt.value = curObj.method
		
			frm.appendChild(inpt)
		
			inpt = srcDoc.createElement("INPUT")
			inpt.type="text"
			inpt.name="className"
			inpt.value = curObj.className
		
			frm.appendChild(inpt)

			inpt = srcDoc.createElement("INPUT")
			inpt.type="text"
			inpt.name="sessionID"
			inpt.value = sessionID
		
			frm.appendChild(inpt)
		
			inpt = srcDoc.createElement("INPUT")
			inpt.type="text"
			inpt.name="fileName"
			inpt.value = curObj.fileName
		
			frm.appendChild(inpt)
		
			frm.action = "download.asp?"+curObj.fileName
			frm.method="post"
			frm.target="nmIFrm"
			frm.style.visiblity="none"
					
			srcDoc.body.appendChild(frm)
		
			frm.submit();
			
			frm.removeNode(true)
			
		} catch(e) 
		 {
			
			gErrors.addError(e.description, 0, "SaveAsCtl", "SaveAs()")
			gErrors.showErrors()
			gErrors.clearErrors()
		
		 }
		
	}
	
	function _cleanUp() {
		if (cleaned) return;
		cleaned = true;
		srcDoc = null;
		serverXMLParms=null;
		curObj = null;
		frm = null;
		newFrm = null;
	}

}

function SubmitCtl(){
	var cWaiting  = 0;
	var cRunning  = 1;
	var cFailed	  = 2;
	var cHold	  = 3;
	var cComplete = 4;
	var cCancel   = 5;
	this.masterJob = null;
	this.masterProfile = null;
	this.detailJob = null;
	this.detailProfile = null;
	this.profileSubmit = false;
	var dlgArgs = new Object();
	var inited = false;
	this.submit = _submit;
	this.addOneJob = _addOneJob;
	this.init = _init;
	
	function _submit(){
		var topWindow;
		if (! inited)
			this.init();
		dlgArgs.profileSubmit = this.profileSubmit;
		dlgArgs.masterJob =	this.masterJob;
		dlgArgs.detailJob = this.detailJob;
		dlgArgs.masterProfile = this.masterProfile;
		dlgArgs.detailProfile = this.detailProfile
		if (windowStack == null)
			topWindow = window;
		else
			topWindow = windowStack[windowStack.length - 1];
		dlgArgs = openDialog(topWindow, "dlgProcessQueueSubmit.asp", 310, 440, "Schedule", dlgArgs);
		return dlgArgs.returnValue;
	}
	function _addOneJob(description, ProgID, xmlParams){
		if (! inited)
			this.init();
		var mRow,dRow;
		dlgArgs.description = description;
		dlgArgs.progID = ProgID;
		dlgArgs.xmlParams = xmlParams;

	}
	
	function _init(){

		var masterJobDescr = new DataCtlDescr();
		masterJobDescr.table = "masterJobs";
		masterJobDescr.keys[0] = "QueueID";
		masterJobDescr.keys[1] = "ProcessID";
		masterJobDescr.addDataColumn('QueueID','string');
		tmpObj = masterJobDescr.addDataColumn("QueueStatus", "string:0");
		tmpObj.updateable = false;
		tmpObj = masterJobDescr.addDataColumn("chkSubmit", "string");
		tmpObj.updateable = false;
		tmpObj = masterJobDescr.addDataColumn("null as profileID","string:0");
		tmpObj.updateable = false;
		masterJobDescr.addDataColumn('ProcessID','string',true,"[GUID]");
		masterJobDescr.addDataColumn('ProcessStatus','string',true,cWaiting);
		masterJobDescr.addDataColumn('TimeSubmitted','dateTime',true,"[TODAY]");
		masterJobDescr.addDataColumn('RunAfter','dateTime',false,"[TODAY]");
		masterJobDescr.addDataColumn('Submitter','string',true,username);
		masterJobDescr.addDataColumn('Description','string');
		masterJobDescr.addDataColumn('ProcessAlert','string',true,"N");
		tmpObj = masterJobDescr.addDataColumn("printReport",'string',true,"N");
		tmpObj.updateable = false;
		tmpObj = masterJobDescr.addDataColumn("txtPrinterName",'string',true,"");
		tmpObj.updateable = false;              
		this.masterJob = new DataCtl(masterJobDescr);
		
		var masterProfileDescr = new DataCtlDescr();
		masterProfileDescr.table = "masterProfiles";
		masterProfileDescr.keys[0] = "QueueID";
		masterProfileDescr.keys[1] = "ProcessID";
		masterProfileDescr.addDataColumn("QueueID","string");
		tmpObj = masterProfileDescr.addDataColumn("QueueStatus", "string:0");
		tmpObj.updateable = false;
		tmpObj = masterProfileDescr.addDataColumn("chkSubmit", "string");
		tmpObj.updateable = false;
		tmpObj = masterProfileDescr.addDataColumn("null as profileID","string:0");
		tmpObj.updateable = false;
		masterProfileDescr.addDataColumn("ProcessID","string",true,"[GUID]");
		masterProfileDescr.addDataColumn("ProcessStatus","string",true,cWaiting);
		masterProfileDescr.addDataColumn("TimeSubmitted","dateTime",true,"[TODAY]");
		masterProfileDescr.addDataColumn("RunAfter","dateTime",false,"[TODAY]");
		masterProfileDescr.addDataColumn("Submitter","string",true,username);
		masterProfileDescr.addDataColumn("Description","string");
		masterProfileDescr.addDataColumn("ProcessAlert","string",true,"N");
		tmpObj = masterProfileDescr.addDataColumn("printReport",'string',true,"N");
		tmpObj.updateable = false;
		tmpObj = masterProfileDescr.addDataColumn("txtPrinterName",'string',true,"");
		tmpObj.updateable = false;    				
		this.masterProfile = new DataCtl(masterProfileDescr);

		var DetailJobDescr = new DataCtlDescr();

		DetailJobDescr.table = "DetailJobs";
		DetailJobDescr.keys[0] = "QueueID";
		DetailJobDescr.keys[1] = "ProcessID";
		DetailJobDescr.keys[2] = "DetailID";
		DetailJobDescr.addDataColumn('QueueID','string');
		DetailJobDescr.addDataColumn('ProcessID','string');
		DetailJobDescr.addDataColumn("DetailID","string",true,"[GUID]");		
		DetailJobDescr.addDataColumn('Seq','numeric',true,0);
		DetailJobDescr.addDataColumn('Description','string');
		DetailJobDescr.addDataColumn('ProgID','string');		
		DetailJobDescr.addDataColumn('ProcessStatus','numeric',true,cWaiting);
		DetailJobDescr.addDataColumn('xmlParams','string');
		this.detailJob = new DataCtl(DetailJobDescr);
		
		var detailProfileDescr = new DataCtlDescr();
		detailProfileDescr.table = "DetailProfiles";
		detailProfileDescr.keys[0] = "QueueID";
		detailProfileDescr.keys[1] = "ProcessID";
		detailProfileDescr.keys[2] = "DetailID";
		detailProfileDescr.addDataColumn("QueueID","string");
		detailProfileDescr.addDataColumn("ProcessID","string");
		detailProfileDescr.addDataColumn("DetailID","string",true,"[GUID]");
		detailProfileDescr.addDataColumn("Seq","numeric",true,0);
		detailProfileDescr.addDataColumn("Description","string");		
		detailProfileDescr.addDataColumn("ProgID","string");
		detailProfileDescr.addDataColumn("ProcessStatus","numeric",true,cWaiting);
		detailProfileDescr.addDataColumn("xmlParams","string");
		this.detailProfile = new DataCtl(detailProfileDescr);
		inited = true;
	}
}

function SysConfig() {
    this.version = _version;
    this.firmName = _firmName;
    this.currentPeriod = _currentPeriod;
    
 this.activePeriod = _activePeriod;
 this.activeFYStart = _activeFYStart;
 
 this.accountPdStart = _accountPdStart;
 this.accountPdEnd = _accountPdEnd;
 this.fyStart = _fyStart;
 this.fyEnd = _fyEnd;
 
 this.OHAllocNeeded = _OHAllocNeeded;
 this.RevGenNeeded = _RevGenNeeded;
 this.Closed = _Closed;
 this.Purged = _Purged;
 
 this.enableAutoRetrieve = _enableAutoRetrieve;
 this.lookupLimitError = _lookupLimitError;
 this.lookupLimit = _lookupLimit;
 this.alertsPollingInterval = _alertsPollingInterval;
 
 this.reset = _reset;
 this.changePeriod = _changePeriod;
 
    function _version() {return sysVersion};
    function _firmName() {return sysFirmName};
    function _currentPeriod() {return parseInt(sysCurrentPeriod)};
 
 function _activePeriod() {return parseInt(sysActivePeriod)};
 function _activeFYStart() {return Math.floor(sysActivePeriod / 100) * 100};
 
 function _accountPdStart() {return formatSubs.strRawToDate(sysAccountPdStart)};
 function _accountPdEnd() {return formatSubs.strRawToDate(sysAccountPdEnd)};
 function _fyStart() {return formatSubs.strRawToDate(sysFYStart)};
 function _fyEnd() {return formatSubs.strRawToDate(sysFYEnd)};
 
 function _OHAllocNeeded() {return sysOHAllocNeeded};
 function _RevGenNeeded() {return sysRevGenNeeded};
 function _Closed() {return sysClosed};
 function _Purged() {return sysPurged};
 
 function _enableAutoRetrieve() {return (sysEnableAutoRetrieve == "Y")};
 function _lookupLimitError() {return sysLookupLimitError};
 function _lookupLimit() {
  if (sysLookupLimitError == "N") 
   return 0; 
  else 
   return parseInt(sysLookupLimit);
 }
 function _alertsPollingInterval() {return parseInt(sysAlertsPollingInterval)};
 
    // private copies of system settings are kept in raw data
    // string format -- initial load does not necessarily have
    // access to formatting routines residing in other .js files
    
    var sysVersion;
    var sysFirmName;
    var sysCurrentPeriod;
 
 var sysActivePeriod;
 
 var sysAccountPdStart;
 var sysAccountPdEnd;
 var sysFYStart;
 var sysFYEnd;
 
 var sysOHAllocNeeded;
 var sysRevGenNeeded;
 var sysClosed;
 var sysPurged;
 
 var sysEnableAutoRetrieve;
 var sysLookupLimitError;
 var sysLookupLimit;
 var sysAlertsPollingInterval;
 
 function _reset(xmlDom) {
  var dataObjConst = new DataCtlDescr();
  dataObjConst.method = "DLTKSysConfig.SystemConfiguration.loadSystemInfo";
  var dataObj = new DataCtl(dataObjConst);
  if (xmlDom == null)
   dataObj.getData();
  else
  //When loading the frameset, load directly from the XML data island
   dataObj.loadData(xmlDom);
  
  with (dataObj) {
            sysVersion = getValueAsString(1,'Version');
            sysFirmName = getValueAsString(1,'FirmName');
            sysCurrentPeriod = getValueAsString(1,'CurrentPeriod');
            sysEnableAutoRetrieve = getValueAsString(1,'EnableAutoRetrieve');
            sysLookupLimitError = getValueAsString(1,'LookupLimitError');
            sysLookupLimit = getValueAsString(1,'LookupLimit');
            sysAlertsPollingInterval = getValueAsString(1,'AlertsPollingInterval');
  }
  dataObjConst = null;
  dataObj = null;
 }
 
 function _changePeriod(Period, xmlDom) {
  var dataObjConst = new DataCtlDescr();
  dataObjConst.method = "DLTKSysConfig.SystemConfiguration.loadPeriodInfo";
  var dataObj = new DataCtl(dataObjConst);
  if (xmlDom == null)
   dataObj.getData(Period);
  else
  //When loading the frameset, load directly from the XML data island
   dataObj.loadData(xmlDom);
  
  if (dataObj.rowCount() == 0) {
   sysActivePeriod = '0';
   sysAccountPdStart = '1/1/1900';
   sysAccountPdEnd = '1/1/1900';
   sysFYStart = '1/1/1900';
   sysFYEnd = '1/1/1900';
   sysOHAllocNeeded = 'N';
   sysRevGenNeeded = 'N';
   sysClosed = 'N';
   sysPurged = 'N';
  }
  else {
   with (dataObj) {
    sysActivePeriod = getValueAsString(1,'Period');
       sysAccountPdStart = getValueAsString(1,'AccountPdStart');
       sysAccountPdEnd = getValueAsString(1,'AccountPdEnd');
       sysFYStart = getValueAsString(1,'FYStart');
       sysFYEnd = getValueAsString(1,'FYEnd');
    sysOHAllocNeeded = getValueAsString(1,'OHAllocNeeded');
    sysRevGenNeeded = getValueAsString(1,'RevGenNeeded');
    sysClosed = getValueAsString(1,'Closed');
    sysPurged = getValueAsString(1,'Purged');
   }
  }
  dataObjConst = null;
  dataObj = null;
 }
}

function TicklerCtl(pollInterval){
    this.setInterval = _setInterval
    this.start = _start
    this.stop = _stop
 
    var obj = this
    var interval
    var timerID
    var rc = new RemoteCall()
    var empID = ""
    var strPollSQL
    var oldKeys = new Object()
    var descData,dataActivity
        
    if(typeof(pollInterval) == "undefined"){
        interval = 300000
    }else{
        interval = pollInterval
    }
    
    retObj = rc.makeCall("DltkSysData.SelectBO","GetData",
                         "select employee from seuser where username = '" + 
                         username + "' and popupalertsenabled = 'Y'")
    if(retObj.errorObj.getCount() == 0){
        var ret = retObj.retval.match(/<employee>.*<\/employee>/)
        if(ret != null){
			empID = retObj.retval.substring(ret.index + 10,ret.lastIndex - 11);
			if(pollInterval == 0){
				mb.msgbox(window,"You have popup Activity alerts enabled but Vision has a polling interval of zero " +
						  "seconds.  Popup alerts will only work with an interval of at least 60 seconds.  " +
						  "Please inform your administrator that this value needs to be set in " +
						  "Configuration->General->System Setup->Miscellaneous tab.");
				return;
			}
		}
    }
                         
    descData = new DataCtlDescr()
    descData.addDataColumn("ActivityID","string")
    dataActivity = new DataCtl(descData)
 
    function _setInterval(newInterval){
        interval = newInterval
    }
    
    function _start(){
        if(interval > 0 && empID != "" && CRMUser){
            clearInterval(timerID)
            timerID = setInterval(pollServer,interval)
        }
    }
    
    function _stop(){
        clearInterval(timerID)
    }
    
    function pollServer(){
        var now
        var dt = new Date()
        var mn
            
        now = formatSubs.dateToStrRaw(dt,true);
        
        strPollSQL = "select a.activityid " +
                             "from AllActivities a,emactivity e " +
                             "where ReminderInd = 'Y' " +
                             "and CompletionInd = 'N' " +
                             "and a.activityid = e.activityid " +
                             "and e.employee = '" + empID + "' " +
                             "and ReminderDate <= '" + now + "' " +
                             "and datediff(wk,reminderdate,'" + now + "') < 3 " +
                             "and (e.PopupDismissed < reminderdate or e.PopupDismissed is null)";

        //debugger                                  
        var retObj = rc.makeAsyncCall(cbRemoteCall,
                                      "DltkSysData.SelectBO",
                                      "getData",
                                      strPollSQL)
    }
    
    function cbRemoteCall(retObj){
        if(retObj.errorObj.getCount() > 0){
            mb.msgbox(application,"An unexpected error has occurred " +
                    "with the activity reminders.  The next window will display " +
                    "the error and reminders will be disabled for the rest of " +
                    "this session.")
            retObj.errorObj.showErrors()
            obj.stop()
        }else if(retObj.retval != "<ROOT/>"){
            var dlgArgs = new Object()
            dataActivity.loadXMLStr(retObj.retval)
            if(dataActivity.rowCount() > 0){
                dlgArgs.dataCtl = dataActivity
                dlgArgs.empID = empID;
                dlgArgs = openDialog(application,"dlgActivityAlert.asp",455,510,"Reminder!",dlgArgs)
                if(dlgArgs.snoozeArray.length > 0 && getAppDoc().handleSnoozes){
                    getAppDoc().handleSnoozes(dlgArgs.snoozeArray);
                }
            }
        }
    }
}

//********************************************************
//********************************************************
//*************** GLOBAL HELPER FUNCTIONS ****************
//********************************************************
//********************************************************
function userHasAccess(navTreeID) {
	var setHREF = navtree.navTreeObj.getPage(navTreeID);
	if ((setHREF == null) || (setHREF == ""))
		return false;
	else
		return true;
}

function strApplyLoggedInEmployee(wkstr) {
	return wkstr.replace(/\'\[LOGGED_IN_EMPLOYEE\]\'/ig, "'" + loggedInEmployee + "'");
}

function winHeight() {
	if (screen.availHeight > 600)
		return 572 - 50; //572 allow for a standard windows start menu bar
	else
		return screen.availHeight - 50
}

function winWidth(mainWindow) {
	var wknum
	
	if (mainWindow == true)
		wknum = 0 //If loading the main window from default.htm, navtree will be there
	else
		wknum = 76
		
	if (screen.availWidth > 800)
		return 800 - 12 - wknum; //Subtract width of explorer border and navigation menu
	else
		return screen.availWidth - 12 - wknum;
}

function topOffset(center) {
	if (screen.availHeight > 600)
		if (center == true)
			return (screen.availHeight - 572) / 2; //572 allow for a standard windows start menu bar
		else
			return window.screenTop - 23 + 20; //Subtract title bar and offset 20 pixels down
	else
		return 0;
}

function leftOffset(center) {
	if (screen.availWidth > 800)
		if (center == true)
			return (screen.availWidth - 800) / 2;
		else
			return window.screenLeft - 4 + 20; //Subtract left border and offset 20 pixels right
	else
		return 0;
}

function openNewWindow(page, center, mainWindow) {
	var newWindow;
	
	newWindow = window.open(page, "_blank", "width=" + winWidth(mainWindow) + ", height=" + winHeight() + ", left=" + leftOffset(center) + ", top=" + topOffset(center) + ", resizable=yes, status=yes, scrollbars=yes" );
	return newWindow;
}

function openDialog(caller, page, height, width, title, dlgArgs, top, left, modeless, resize, queryString) {
	var styleStr;
	var appVersionArray;
	var pageQueryString;
	if (resize==true) { resize="yes" } else if (resize==false || typeof(resize)=="undefined") { resize="no" }

	if (dlgArgs == null)
		dlgArgs = new Object();
	if(dlgArgs.global == null) dlgArgs.global = global;
	dlgArgs.title = title;
	dlgArgs.caller = caller;
	
	if (height == null)
		height = winHeight();
	else {
		appVersionArray = clientInformation.appVersion.split(";");
		if (appVersionArray[2].indexOf("Windows NT 5.1") >= 0) height += 7; // add 7 pixels if Windows XP
	}
	if (width == null)
		width = winWidth();
		
	styleStr = "dialogHeight: " + height + "px; dialogWidth: " + width + "px; status: no; scroll: no; help: no; resizable: " + resize; 
	
	if (top != null)
		styleStr += "; dialogTop: " + top + "px";
	if (left != null)
		styleStr += "; dialogLeft: " + left + "px";

	if (queryString != null)
		pageQueryString = "?sessionID=" + sessionID + "&" + queryString;
	else
		pageQueryString = "?sessionID=" + sessionID;
		
	if (modeless == true)
		return caller.showModelessDialog(page + pageQueryString, dlgArgs, styleStr);
	else{
		var tmpObj;
		tmpObj = caller.showModalDialog(page + pageQueryString, dlgArgs, styleStr);
		if (dlgArgs.invalidSession){
			if (windowStack == null)
				topWindow = window;
			else
				topWindow = windowStack[windowStack.length - 1];
			var loginDlgArgs;
			loginDlgArgs = new Object();
			loginDlgArgs.reLogin = true;
			loginDlgArgs.global = top;
			loginDlgArgs.repost = false;
			loginDlgArgs = openDialog(topWindow, "login.asp", 400, 400, "Re-Login", loginDlgArgs);
			if (! loginDlgArgs.cancel){
				dlgArgs.invalidSession = false;
				return openDialog(caller, page, height, width, title, dlgArgs, top, left, modeless, resize, queryString)				
			}else{
			}
		}
		return dlgArgs;
	}
	
}

function getOffsetLeft(ctl) {
	var par, off, bdy, par1, bdr, tmp;
			
	off = ctl.offsetLeft;
	par = ctl;
	bdy = ctl.document.body;
	for(;;) {
		if (par.offsetParent != null)
			par = par.offsetParent
		else
			return off;
		if (par == bdy)
			break;
		bdr = parseInt(par.style.borderLeftWidth);
		if (isNaN(bdr)) bdr = 0;
		tmp = par.offsetLeft - par.scrollLeft;
		if ((tmp == 0) && (par.scrollLeft == 0)) tmp = par.style.pixelLeft; // offsetLeft may not be valid if object has yet to be rendered
		off += tmp + bdr;
	}
	return off;
}

function getOffsetTop(ctl) {
	var par, off, bdy, par1, bdr, tmp;
			
	off = ctl.offsetTop
	par = ctl
	bdy = ctl.document.body
			
	for(;;) {
		if (par.offsetParent != null)
			par = par.offsetParent
		else
			return off;			
		if (par == bdy)
			break;
		bdr = parseInt(par.style.borderTopWidth);
		if (isNaN(bdr)) bdr = 0;
		tmp = par.offsetTop - par.scrollTop;
		if ((tmp == 0) && (par.scrollTop == 0)) tmp = par.style.pixelTop; // offsetTop may not be valid if object has yet to be rendered
		off += tmp + bdr;
	}
	return off;
}

function textWidthInPixels(objDoc, txt, styleClass) {
    var el;
    var txtWidth;

    el = objDoc.createElement("<SPAN>");
    el.innerText = txt;
    el.style.position = 'absolute';
    el.style.visibility = 'hidden';
    if (styleClass) {
        el.className = styleClass;
    }
    objDoc.body.appendChild(el);
    txtWidth = el.offsetWidth;
    objDoc.body.removeChild(el);
    return txtWidth
}

function getAppDoc(){
	return top.application.document
}

function browseForFile() {
   	var el;
   	var fileName;

   	el = document.createElement("<INPUT id=text1 name=text1>");
   	el.style.position = 'absolute';
   	el.style.visibility = 'hidden';
	el.type = 'file';
	document.body.appendChild(el);
	el.click();
	fileName = el.value;
   	document.body.removeChild(el);
 	return fileName;
}

function checkRecordLimit(rows) {
	if ((sysConfig.lookupLimit() > 0) && (rows >= sysConfig.lookupLimit()))
		mb.msgbox(window, 
			"WARNING - Your system is configured to allow a maximum of " + 
			sysConfig.lookupLimit() + 
			" records in a search list.  To ensure that all matching records are retrieved, you should change your search criteria.", mb.Information, "Deltek Vision");
}

//*************** minor useful classes ****************
function Timer(){
  var d1 = null;
  var d2 = null;
  this.startTime = _startTime;
  this.endTime = _endTime;
  this.start = _start
  this.stop = _stop
  this.log = _log;
  this.logArray = new Array();
  this.app = "";
  this.ctl = "";
	function _log(theStr){
		if (d1 != null)
			this.logArray[this.logArray.length] = this.app + "," + this.ctl + "," + theStr + "," + _stop() + "<BR/>";
	}
  
  function _startTime(){
  		return d1.getTime();
  }
  function _endTime(){
  		return d2.getTime();
  }
  function _start(){
  	this.logArray = new Array();
    d1 = new Date();
  }
  function _stop(){
    d2 = new Date();
    return d2.getTime() - d1.getTime();
  }
}

//************* validation routines ****************
function validate(className, table, col, value, fieldList){
	var retObj = new Object();
	var xmlDom = new ActiveXObject("Microsoft.XMLDOM");

	var mObj = remoteCall.makeCall("DLTKMaintBO.MaintBO", "fieldValidate", table, col, "", 0, value, className, fieldList);
	if (mObj.errorObj.getCount() > 0 && mObj.errorObj.severity > 2)
		mObj.errorObj.showErrors();
	else {
		xmlDom.loadXML(mObj.retval);
		retObj.valid = xmlDom.documentElement.childNodes(0).text == "True";
		if (retObj.valid)
			for (var i = 1; i < xmlDom.documentElement.childNodes.length; i++)
				eval("retObj." + xmlDom.documentElement.childNodes(i).nodeName + " = '" + evalDoubleQuote(xmlDom.documentElement.childNodes(i).text) + "'");
		retObj.description = "";
		for (var i = 0; i < mObj.errorObj.errors.length; i++)
			if (retObj.description == "")
				retObj.description = mObj.errorObj.errors[i].description;
			else
				retObj.description += mb.CrLf + mObj.errorObj.errors[i].description
	}
	return retObj;	
}

function duplicateRecordCheck(caller,table,fieldList,values,returnList,bExactMatch){
    if(values != ""){
        if(typeof(bExactMatch) == "undefined"){
            var retObj = remoteCall.makeCall("DltkMaintBO.Validation","dupeRecordCheck",table,fieldList,values,returnList,false);
        }else{
            var retObj = remoteCall.makeCall("DltkMaintBO.Validation","dupeRecordCheck",table,fieldList,values,returnList,bExactMatch);
        }
        var dom = new ActiveXObject("Microsoft.XMLDOM")
        var dlgArgs = new Object()
    
        if(retObj.errorObj.getCount() > 0){
            retObj.errorObj.showErrors()
            return false
        }
        var xml = retObj.retval

        dom.loadXML(xml)
    
        if(dom.documentElement.childNodes.length == 0){
            return true
        }else{
            dlgArgs.dom = dom
            dlgArgs = openDialog(caller,"DLGDupeRecord.asp",295,330,"Potential Duplicate Records Found",dlgArgs)
            return false;
        }
    }else{
        return true;
    }
}

function duplicateContactCheck(caller,firstname,lastname){

    var dom = new ActiveXObject("Microsoft.XMLDOM")
    var dlgArgs = new Object()

    var retObj = remoteCall.makeCall("DltkMaintBO.Validation","dupeContactCheck",firstname,lastname);
    
    if(retObj.errorObj.getCount() > 0){
        retObj.errorObj.showErrors()
        return false
    }
    var xml = retObj.retval

    dom.loadXML(xml)
    
    if(dom.documentElement.childNodes.length == 0){
        return true
    }else{
        dlgArgs.dom = dom
        dlgArgs = openDialog(caller,"DLGDupeRecord.asp",290,320,"Potential Duplicate Contacts Found",dlgArgs)
        return false;
    }
}

// launches dhtml text editor and return edited html
function launchTextEditor(windRef, HTML, fontFamily, fontSize, fontColor, height, width) {
	
	// windRef: reference to the calling document's window object
	// fontFamily e.g. "Tahoma Arial Wingdings"
	// fontSize    Accepted values: "8pt", "10pt", "12pt", "14pt", "18pt", "24pt", "36pt"
	// fontColor   e.g. "pink", "#FFFFFF"
	// width: integer value e.g. 200
	// height: integer value e.g. 4,256 ha ha
	
	var dlgArgs = new Object()
	
	if (typeof(fontFamily)=="undefined" || fontFamily=="") {
		fontFamily="Tahoma Arial Sans Serif"
	}	
	if (typeof(fontSize)=="undefined" || fontSize=="") {
		fontSize="8pt"
	}	
	if (typeof(fontColor)=="undefined" || fontColor=="") {
		fontFamily="black"
	}	
	
	if (typeof(height)=="undefined" || height=="") {
		height=400
	}	
	
	if (typeof(width)=="undefined" || width=="") {
		width=600
	}	
	
	dlgArgs.global=top
	dlgArgs.cancel=false
	dlgArgs.fontFamily=fontFamily
	dlgArgs.fontSize=fontSize
	dlgArgs.fontColor=fontColor
	dlgArgs.HTML=HTML
	//caller, page, height, width, title, dlgArgs, top, left, modeless, resize
	dlgArgs = openDialog(windRef, "DLGTextEditor.asp", height, width, "Vision Text Editor", dlgArgs, null, null, false, true);

	return dlgArgs.HTML
}

function getGUID() {
	var iTest
	var dateObj = new Date();
	iTest = dateObj.getTime();
	while (dateObj.getTime() == iTest)
		dateObj = new Date();
	return username + dateObj.getTime().toString();
}

function roundNumber(amount, decimals) {
    if (amount == null)
        return 0;
    else
        return parseFloat(amount.toFixed((decimals == null) ? 0 : decimals));
}

function roundCurrency(amount) {
    return roundNumber(amount, formatSubs.currencyDecimals());
}

function sqlCurrencyCol(expr) {
    //always convert to DECIMAL(19,<currency decimals>) so that any data exceeding the column/data type
    //format can still be retrieved without causing the SELECT to fail
    return "CONVERT(VARCHAR,CONVERT(DECIMAL(19," + formatSubs.currencyDecimals() + ")," + expr + "))";
}
    
function sqlNumericCol(expr, digits, decimals) {
    //always convert to DECIMAL(19,<decimals>) so that any data exceeding the column/data type
    //format can still be retrieved without causing the SELECT to fail
    return "CONVERT(VARCHAR,CONVERT(DECIMAL(19," + decimals + ")," + expr + "))";
}
    
function sqlDateCol(expr) {
    return "REPLACE(CONVERT(VARCHAR," + expr + ",121),' ','T')";
}

function sqlDateListCol(expr) {
	var fmt = formatSubs.shortDateFormat();
	var dStr;
	
	if ((fmt.substr(0,1) == "m") || (fmt.substr(0,1) == "M"))
		dStr = " convert(varchar,month(" + expr + ")) + '/' + convert(varchar,day(" + expr + "))";
	else
		dStr = " convert(varchar,day(" + expr + ")) + '/' + convert(varchar,month(" + expr + "))";
	return dStr + " + '/' + substring(convert(varchar,datepart(yyyy," + expr + ")),3,2)";
}

function sqlDateTimeListCol(expr) {
	var fmt = formatSubs.shortDateFormat();
	var dStr;
	
	var colExpr = " dateadd(\"hh\"," + getUTCDiff() + "," + expr + ")";
	if ((fmt.substr(0,1) == "m") || (fmt.substr(0,1) == "M"))
		dStr = " convert(varchar,month(" + colExpr + ")) + '/' + convert(varchar,day(" + colExpr + "))";
	else
		dStr = " convert(varchar,day(" + colExpr + ")) + '/' + convert(varchar,month(" + colExpr + "))";
	dStr += " + '/' + substring(convert(varchar,datepart(yyyy," + colExpr + ")),3,2)";
	dStr += " + ' ' + replace(str(case when datepart(hh," + colExpr + ") > 12 then datepart(hh," + colExpr + ") - 12 else datepart(hh," + colExpr + ") end,2),' ','0')";
	dStr += " + ':' + replace(str(datepart(mi," + colExpr + "),2),' ','0')";
	dStr += " + ':' + replace(str(datepart(ss," + colExpr + "),2),' ','0')";
	dStr += " + ' ' + case when datepart(hh," + colExpr + ") >= 12 then 'PM' else 'AM' end";
	return dStr;
}

function sqlDateConstant(dateObj) {
	var rawDate = formatSubs.dateToStrRaw(dateObj);
	var dtArray = rawDate.split("T");

	return dtArray[0];
}

function strToSQLDateConstant(strShortDate) {
	var retObj = formatSubs.finishDate(strShortDate);
	if (retObj.value != null)
		return sqlDateConstant(retObj.value);
	else
		return "";
}

function shortDateToDateObj(strShortDate) {
	var retObj = formatSubs.finishDate(strShortDate);
	return retObj.value;
}

function getUTCDiff(){
	var dateObj = new Date();
	var dateDif = dateObj.getHours() - dateObj.getUTCHours();
	if (dateObj.getUTCDate() < dateObj.getDate()){
		dateDif += 24
	} else if (dateObj.getUTCDate() > dateObj.getDate()){
		dateDif -=24
	}
	return dateDif;
}

function getParm(xmlStr, nodeName, defaultValue) {
	var tmpNode;
	var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
	
    xmlDom.preserveWhiteSpace = true;
	xmlDom.loadXML(xmlStr);	

    tmpNode = xmlDom.documentElement.selectSingleNode(nodeName);
    if (tmpNode == null) {
    	if (defaultValue == null)
    		return "";
    	else
    		return defaultValue;
	}
	else
		return tmpNode.text;
}

function setParm(xmlDom, nodeName, value) { 
    var searchString;
    var tmpNode; 

	if (xmlDom == null) {
	    xmlDom = new ActiveXObject("Microsoft.XMLDOM");
	    xmlDom.preserveWhiteSpace = true;
	}
    if (!xmlDom.hasChildNodes){
    	var root = xmlDom.createElement("parms");
    	 xmlDom.appendChild(root);
    }        
        
    tmpNode = xmlDom.documentElement.selectSingleNode(nodeName);
    if (tmpNode == null) {
    	if (value != null) {
    		tmpNode = xmlDom.createElement(nodeName);
    		tmpNode.text = value.toString();
    		xmlDom.documentElement.appendChild(tmpNode);
    	}
    }
    else {
    	if (value != null)
    		tmpNode.text = value.toString();
    	else
			xmlDom.documentElement.removeChild(tmpNode); 
    }
    return xmlDom;
}

function evalDoubleQuote(str) {
	return str.replace(/'/g,"\\'");
}

function getDefaultPrinter(){
	return reportingDefaultPrinter;
}

function getPrinterDataCtl(ignoreErrors){
	report.loadPrinters(false, ignoreErrors);
	return report.reportPrintersDataCtl;
}

function logEvent(desc,message){
    var row;
    
    if (DEBUG){
        row = debugData.insertRow(1);
        debugData.setValue(row,"Date",new Date());
        debugData.setValue(row,"Description",desc);
        debugData.setValue(row,"Message",message);
    }
}

function getFunctionName(func){
	return func.toString().match(/function\s+([^(\s]+)/)[1];
}

function broadcastEmail(dlgArgs){
    var mb = new MsgCtl();
    var addresses = "";
    var subject = "";
    var mail;
    var node;
    var lu;
    var i;
    var descData,dataCtl;
    var ret;
    var newArgs,mailArgs;
	
	switch(dlgArgs.type){
	case "select":
	    if(dlgArgs.dataCol == "Contacts.ContactID"){
	        lu = getStandardLookup("Contacts");
	    }else if(dlgArgs.dataCol == "EM.Employee"){
	        lu = getStandardLookup("EM");
	    }else if(dlgArgs.dataCol == "Leads.LeadID"){
	        lu = getStandardLookup("Leads");
	    }
	    lu.setMultiSelect(true);
	    lu.open();
	    if(lu.stateObject.selected == false) return;
	    dataCtl = lu.stateObject.returnDataCtl;
	    if(dataCtl.rowCount() == 0) return;
	    break;
	case "group":
	    descData = new DataCtlDescr();
	    if(dlgArgs.dataCol == "Contacts.ContactID"){
	        descData.fromString = "((Contacts LEFT JOIN CL ON Contacts.ClientID = CL.ClientID) LEFT JOIN CLAddress ON Contacts.ClientID = CLAddress.ClientID AND CLAddress.PrimaryInd = 'Y')";
			descData.addDataColumn("Contacts.Email","string");
	        if(dlgArgs.dataCtl == null){
	            descData.whereString = dlgArgs.whereClause;
	        }else{
	            descData.whereString = "Contacts.ContactID in (";
	            dataCtl = dlgArgs.dataCtl;
	            for(i = 1;i <= dataCtl.rowCount();i++){
	                if(i < dataCtl.rowCount())
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "',";
	                else
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "')";
	            }
	        }
	    }else if(dlgArgs.dataCol == "EM.Employee"){
	        descData.fromString = "(EM LEFT JOIN Organization ON EM.Org=Organization.Org)";
			descData.addDataColumn("EM.Email","string");
	        if(dlgArgs.dataCtl == null){
	            descData.whereString = dlgArgs.whereClause;
	        }else{
	            descData.whereString = "EM.Employee in (";
	            dataCtl = dlgArgs.dataCtl;
	            for(i = 1;i <= dataCtl.rowCount();i++){
	                if(i < dataCtl.rowCount())
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "',";
	                else
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "')";
	            }
	        }
	    }else if(dlgArgs.dataCol == "Leads.LeadID"){
	        descData.fromString = "Leads";
			descData.addDataColumn("Leads.Email","string");
	        if(dlgArgs.dataCtl == null){
	            descData.whereString = dlgArgs.whereClause;
	        }else{
	            descData.whereString = "Leads.LeadID in (";
	            dataCtl = dlgArgs.dataCtl;
	            for(i = 1;i <= dataCtl.rowCount();i++){
	                if(i < dataCtl.rowCount())
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "',";
	                else
	                    descData.whereString += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "')";
	            }
	        }    
	    }
	    dataCtl = new DataCtl(descData);
	    dataCtl.getData();
	    break;
	case "current":
	    descData = new DataCtlDescr();
	    if(dlgArgs.dataCol == "Contacts.ContactID"){
	        descData.fromString = "Contacts";
	        descData.whereString = "Contacts.ContactID = '" + 
	                               formatSubs.doubleQuote(dlgArgs.key) + "'";
	    }else if(dlgArgs.dataCol == "EM.Employee"){
	        descData.fromString = "EM";
	        descData.whereString = "EM.Employee = '" + 
	                               formatSubs.doubleQuote(dlgArgs.key) + "'";
	    }else if(dlgArgs.dataCol == "Leads.LeadID"){
	        descData.fromString = "Leads";
	        descData.whereString = "Leads.LeadID = '" + 
	                               formatSubs.doubleQuote(dlgArgs.key) + "'";
	    }
	    descData.addDataColumn("Email","string");
	    dataCtl = new DataCtl(descData);
	    dataCtl.getData();
	    break;
	}

	if(dataCtl != null){
	    for(i = 1;i <= dataCtl.rowCount();i++){
	        mail = dataCtl.getValue(i,"Email");
	        if(mail != ""){
	            addresses += mail + ";";
	        }
	        mail = "";
	    }
	}
    
    if(addresses != ""){
        var infoCenterArea;
        var whereClause;
        
	    ret = mb.msgbox(application,"Would you like to create an activity for this " +
	                    "emailing?",mb.YesNo);
	    if(ret == mb.Yes){
	        dlg = new ActivityDialog(getAppDoc());
	        if(dlgArgs.dataCol == "EM.Employee"){
	            infoCenterArea = "Employees";
	        }else if(dlgArgs.dataCol == "Contacts.ContactID"){
	            infoCenterArea = "Contacts";
	        }else if(dlgArgs.dataCol == "Leads.LeadID"){
	            infoCenterArea = "Leads";
	        }
	        if(dlgArgs.type == "select"){
	            whereClause = dlgArgs.dataCol + " in (";
	            for(i = 1;i <= dataCtl.rowCount();i++){
	                if(i < dataCtl.rowCount())
	                    whereClause += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "',";
	                else
	                    whereClause += "'" + formatSubs.doubleQuote(dataCtl.getValue(i,"Key")) + "')";
	            }
	        }else{
	            whereClause = dataCtl.getWhereString();
	        }
	        dlg.showBulkMode(whereClause,infoCenterArea);
	        subject = dlg.getValue(1,"Subject");
	    }
	    
	    mailArgs = new Object();
	    if(dlgArgs.type == "current"){
	        mailArgs.to = addresses;
	    }else{
	        mailArgs.bcc = addresses;
	    }
	    mailArgs.subject = subject;
	    if(ret == mb.Yes) mailArgs.message = dlg.getValue(1,"Notes");
	    mailArgs = openDialog(application,"dlgEmail.asp",410,530,"Send Email",mailArgs);
	}else{
	    mb.msgbox(application,"There are no email addresses for the records you selected.");
	}
}

function convertOptionString(optionString)
{
	//Used to debug report options
	var stringLength;
	var wkstr = "defaultOptions = \"";
	var curChar;
	var insideEndTag;

	optionString = optionString.replace(/"/ig, "'");
	
	optionString = formatSubs.trimStr(optionString);
	var reportWindow = window.open("", "_blank");
	for (i=0;i<optionString.length;i++)
	{
		if ((optionString.substring(i, i + 1) == "/") && (optionString.substring(i - 1, i) == "<"))
			insideEndTag = true;
				
		if (insideEndTag && (optionString.substring(i, i + 1) == ">"))
		{
			wkstr = wkstr + optionString.substring(i, i + 1)
			if (i < optionString.length - 1)
				wkstr = wkstr + "\"" + String.fromCharCode(13) + String.fromCharCode(10) + "+ & \"";
			insideEndTag = false;
		}
		else
			wkstr = wkstr + optionString.substring(i, i + 1)
	}
		
	wkstr = wkstr + "\"";
	
	reportWindow.document.write("<HTML><BODY>");
	reportWindow.document.write("<TEXTAREA id='optionString'");
	reportWindow.document.write(" style='position:absolute;top:5px;left:5px;width:700px;height:400px'>");
	reportWindow.document.write(wkstr);
	reportWindow.document.write("</TEXTAREA></BODY></HTML>");
		
	return wkstr;
}