//--Copyright © 1999-2008, A Plus Consultants, LLC, All Rights Reserved.
//--No part of this script may be used for any purpose without prior
//--written permission. Contact richard@aplusconsultants.com.
/*
	Common JavaScript functions.
	Created: 01/03/2004

	Functions:
	AreaHide(id) {
	AreaShow(id, sType)
	askDel()				(moved from stores.cfm)
	AssignMessage(oForm, sTarget, iMessage)
	AssignNext(oForm, sTarget, sMode)
	bSaveFileName(oFile, oName)
	bSetChangedCheck(oForm, sElement, sChanged)
	bSetChangedRadio(oForm, sElement, sChanged)
	CalcSalePrice(oForm, sSalePrice, nDiscount, sBasePrice)
	CharCounter(oField, iCharLimit)
	CheckSome(oForm, sElement, sAction)
	DittoSet(sForm, sField)
	DittoSetAll(sForm, sFieldList)
	DittoViewAll(sForm, sFieldList)
	doAddress(sOrder)
	doCloseOrder(sOrder)
	doComment(sOrder)
	doEmail(sOrder)
	doInvoice(sOrder)
	doOrder(sColumn, sDir, sForm)	(moved from archivelist_tb.cfm)
	doReopenOrder(sOrder)
	doShipComplete(sOrder, sFormName)
	doShowShipping(sOrder)
	doSKUFilter()
	doSubmitEngrave()
	doSubmitOrder(iOrder, sFormName)
	FocusOn(sObject)		set focus to the window or object.
	OpenPop(sURL, sTarget)
	selectRow(mT, sWindow)	(moved from searchlist.cfm)
	showPopup(sMsg)			(moved from various pages)
	showWait(bShow)			(moved from archivelist_tb.cfm)
*/
var ww = null;

function AreaHide(id) {
/*
	This function hides an element on a web page.

	Parameters:
	id			: Unique id of the web page element.
*/
	document.getElementById(id).style.display = 'none';
}

function AreaShow(id, sType) {
/*
	This function reveals an element on a web page.

	Parameters:
	id			: Unique id of the web page element.
	sType		: Either block or inline expected.
*/
	document.getElementById(id).style.display = sType;
}

function AreaShowHide(lShowId, lHideId, sType) {
/*
	This function reveals one or more elements on a web page and hides
	a different group of elements.

	Parameters:
	lShowId		: List of unique ids of web page elements to show.
	lHideId		: List of unique ids of web page elements to hide.
	sType		: Either block or inline expected.
*/
	var ar = lShowId.split(",");
	var ii = "0";
	for (ii = 0; ii < ar.length; ii++) {
		if (ar[ii] != "") {
			AreaShow(ar[ii], sType);
		}
	}
	ar = lHideId.split(",");
	for (ii = 0; ii < ar.length; ii++) {
		if (ar[ii] != "") {
			AreaHide(ar[ii]);
		}
	}
}

function askDel() {
	return confirm("WARNING!\n\nYou're about to delete a store. Any users associated to this store need to be changed as well!\n\nIf you wish to continue, click OK. Click Cancel to return to the previous screen.");
}


function AssignMessage(oForm, sTarget, iMessage) {
/*
	This function assigns a value to the comments field of the
	Metrolink form.

	Parameters:
	oForm		: The target form object.
	sTarget		: Name of the target input or textarea control.
	iMessage	: The id of the message to assign.
	
	Called By	: AssignNext()
*/
	oForm[sTarget].value = arMessage[iMessage];
	oForm.Paragraph.value = iMessage;
//	oForm.Subject.value = oForm.Theme.options[oForm.Theme.selectedIndex].text;
}

function AssignNext(oForm, sTarget, sMode) {
/*
	This function randomizes a set of prepared messages loaded by a
	JavaScript source file. It then assigns that message to the
	the target field of the designated form.

	Parameters:
	oForm		: The target form object.
	sTarget		: Name of the target input or textarea control.
	sMode		: Next or Random.

	Calls		: AssignMessage()
*/
	var iMessages = arMessage.length;
	var iNext = 0;
	var iParagraph = parseInt(oForm.Paragraph.value);
	if (sMode == "Random") {
		//	Choose a random message that is not zero or the current value.
		while (iNext == 0 || iNext == iParagraph) {
			iNext = Math.floor(Math.random() * iMessages);
		}
	}
	else {
		//	Choose the next message in order.
		iNext = iParagraph + 1;
		if (iNext > iMessages - 1) {
			iNext = 1;
		}
	}
	AssignMessage(oForm, sTarget, iNext);
/*
	var id = document.fax.missionid.value;
    var many = 9;

    if ( many > 1 ) {
        while ( (id == document.fax.missionid.value) || (mission[id] == null ) )	{
            id = Math.floor(Math.random() * mission.length);
        }
        document.fax.missionid.value = id;
        document.fax.mission_text.value = mission[id];
    } else {
        alert("There are no alternative opening points or texts for this fax.");
    }
*/
}

function bSaveFileName(oFile, oName) {
/*
	We need to preserve the name of the uploaded file for comparison.
*/
	var sFile = oFile.value;
	sFile = sFile.substr(sFile.lastIndexOf("\\") + 1, sFile.length);
	//	Condition added because of problem when leaving upload file name blank.
	if (sFile != "") {
		oName.value = sFile;
	}
}

function bSetChangedCheck(oForm, sElement, sChanged) {
	var oElement = oForm[sElement];
	var ii = 0;
	var iCnt = 0;
	var sChangedCheck = "";
	for (ii = 0; ii < oElement.length; ii++) {
		if (oElement[ii].type == "checkbox") {
			if (oElement[ii].checked != oElement[ii].defaultChecked) {
				sChangedCheck += "," + oElement[ii].value;
				iCnt++;
			}
		}
	}
	sChangedCheck = sChangedCheck.substr(1, sChangedCheck.length);
	oForm[sChanged].value = sChangedCheck;
//	alert(sChangedCheck);
/*	if (iCnt == 0) {
		alert("You haven't made any changes.");
		return false;
	} */
	alert(iCnt + " box(es) have changed.");
	return true;
}

function bSetChangedRadio(oForm, sElement, sChanged) {
//	var oElement = oForm[sElement];
	var ii = 0;
	var iCnt = 0;
	var sChangedCheck = "";
	var sElName = "";
	for (ii = 0; ii < oForm.elements.length; ii++) {
//alert(oForm.elements[ii].name);	
		if (oForm.elements[ii].type == "radio" && sElName != oForm.elements[ii].name) {
			if (oForm.elements[ii].checked != oForm.elements[ii].defaultChecked) {
				sElName = oForm.elements[ii].name;
				var ar = sElName.split("_");
				sChangedCheck += "," + ar[1];
				iCnt++;
			}
		}
	}
	sChangedCheck = sChangedCheck.substr(1, sChangedCheck.length);
	oForm[sChanged].value = sChangedCheck;
//	alert(sChangedCheck);
/*	if (iCnt == 0) {
		alert("You haven't made any changes.");
		return false;
	} */
	alert(iCnt + " button(s) have changed.");
	return true;
}

function CalcSalePrice(oForm, sSalePrice, nDiscount, sBasePrice) {
/*
	This function computes a sale price for all the elements on a
	form based on the discount percentage and the type of base price
	to calculate on.
	
	It expects two or more sets of prices to be available on the form.
	One price must the sale price element for placing the calculation
	in and the others are the base prices.
	
	The form element names might be:
		sSalePrice:	PriceSale_nnnnn
		sBasePrice:	PriceRegular_nnnnn
					PriceMSRP_nnnnn

	Parameters:
	oForm		: The form object of the calling form.
	sSalePrice	: The sale price element string prefix.
	nDiscount	: A percentage discount to reduce a base price by.
	sBasePrice	: The base price element string prefix.
*/
	var ar = "";
	var arBasePrice = oForm[sBasePrice];
	var ii = 0;
	var nCalcPrice = 0;
	var oEl;
	var sName = "";

	for (ii = 0; ii < arBasePrice.length; ii++) {
		if (arBasePrice[ii].checked) {
			sBasePrice = arBasePrice[ii].value;
		}
	}
	if (nDiscount == "" || parseFloat(nDiscount, 10) == "NaN") {
		alert("Invalid discount.");
		return;
	}
	nDiscount = 1 - (nDiscount / 100);
	for (ii = 0; ii < oForm.elements.length; ii++) {
		if (oForm.elements[ii].type == "text") {
			oEl = oForm.elements[ii];
			sName = oEl.name;
			if (sName.substr(0, sSalePrice.length + 1) == sSalePrice + "_") {
				//	Split out the product identifier to build the
				//	name of the base field.
				ar = sName.split("_");
				nCalcPrice = oForm[sBasePrice + "_" + ar[1]].value;
				oEl.value = parseInt(nCalcPrice * nDiscount * 100, 10) / 100;
			}
		}
	}
}

function CharCounter(oField, iCharLimit) {
/*
	This function determines whether a textarea input has more
	than the allowable characters in it.
	
	It is not the traditional counter in that it doesn't interfere
	with the data entry on a keystroke basis. It prevents exit from
	the field until the character count does not exceed the limit.
	
	Parameters:
	oField		: The target textarea object.
	iCharLimit	: Number of characters to allow.

	iCharLimit does not need to be passed if there is corresponding
	_len element on the page. In that case, it will obtain the limit
	from this element.
*/
	if (! iCharLimit) {
		//	Get the limit value from the element.
		var oCounter = document.getElementById(oField.name + "_len");
		var iCharLimit = oCounter.firstChild.data;
		var re = new RegExp("[()]", "gi");

		//	Remove any parentheses.
		iCharLimit = iCharLimit.replace(re, "");
	}
	if (oField.value.length > iCharLimit) {
//		oField.value = oField.value.substring(0, iCharLimit);
		alert("You've exceeded the allowable number of characters for this entry. Please remove " + (oField.value.length - iCharLimit) + " characters before continuing.");
		oField.focus();
	}
	else {
//		oCounter.value = iCharLimit - oField.value.length;
//		oCounter.firstChild.data = '(' + oField.value.length + ')'; 
	}
}		

function CheckSome(oForm, sElement, sAction) {
/*
	This selects or removes the selection from an array of form
	objects. The three actions are:
	All - select all items in the array.
	None - remove selection from all items in the array.
	Reverse - Toggle selected items off and unselected items on.
	It only works for the checkbox type, but it could be extended
	to work with the select-multiple type as well.
*/
//	alert(oForm.name + "," + sElement + "," + sAction);
	var oElement = oForm[sElement];
	var ii = 0;
	var iCnt = 0;
	for (ii = 0; ii < oElement.length; ii++) {
		if (oElement[ii].type == "checkbox") {
			if (sAction == "All") {
				oElement[ii].checked = true;
				iCnt++;
			}
			if (sAction == "None") {
				oElement[ii].checked = false;
			}
			if (sAction == "Reverse") {
				if (oElement[ii].checked) {
					oElement[ii].checked = false;
				}
				else {
					oElement[ii].checked = true;
					iCnt++;
				}
			}
		}
	}
	alert(iCnt + " box(es) are now selected.");
}

function DittoSet(sForm, sField) {
/*
	Set's the value of a form element to a value that has been
	stored in another element.
	
	Other thoughts on handling this include:
		Writing out a JavaScript array and reading back from it.
		Setting the elements in a separate form.
		Reading all values form a sinlge hidden field.
*/
	var ii = 0;
	var oForm = document.forms[sForm];
	var oTgt = oForm[sField];
	var sDitto = sField + "Ditto";
	var sVal = oForm[sDitto].value;
	
	//	Handle the different object types.
	if (oTgt.type == "text") {
		//	Overwrite.
		oTgt.value = sVal;
	}
	else if (oTgt.type == "textarea") {
		//	Append.
		if (oTgt.value == "") {
			oTgt.value = sVal;
		}
		else {
			if (sVal == "") {
				oTgt.value = sVal;
			}
			else {
				oTgt.value += "\n" + sVal;
			}
		}
	}
	else if (oTgt.type == "select-one") {
		//	Select.
		for (ii = 0; ii < oTgt.options.length; ii++) {
			if (oTgt.options[ii].value == sVal) {
				oTgt.selectedIndex = ii;
			}
		}
	}
}

function DittoSetAll(sForm, sFieldList) {
/*
	This repeats the DittoAll function for all fields in the list.
	It is intended for use on an empty form.
*/
	var ar = sFieldList.split(",");
	var ii = 0;
	var sRes = ar.length;
	for (ii = 0; ii < ar.length; ii++) { 
		DittoSet(sForm, ar[ii]);
//		sRes += ar[ii] + "\n";
	}
//	alert(sRes);
	alert(sRes + " values were set.");	
}

function DittoViewAll(sForm, sFieldList) {
/*
	This function displays the current values of all ditto fields.
	
	Parameters:
	sForm		: The name of the form holding the hidden ditto values.
	sFieldList	: The list of fields participating in the ditto function.
*/
	var ar = sFieldList.split(",");
	var ii = 0;
	var oForm = document.forms[sForm];
	var oTgt = "";
	var sDitto = "";
	var sRes = ar.length;
	var sShow = "CURRENT DITTO VALUES (" + sRes + ")\n====================\n";
	var sVal = "";
	for (ii = 0; ii < ar.length; ii++) { 
		oTgt = oForm[ar[ii]];
		sDitto = ar[ii] + "Ditto";
		sVal = oForm[sDitto].value;
		sShow += "\n" + ar[ii] + ((oTgt.type=="textarea") ? ":\n\t" : ":\t" + (ar[ii].length <= 8 ? "\t" : "")) + sVal.replace(/\n/gi, "\t");
	}
//	sShow += "\n\n" + sRes + " ditto values displayed.";
	alert(sShow);
}

function doAddress(sOrder) {
	window.showModalDialog("orderaddress.cfm?K=" + sOrder, "", "dialogWidth=550px; dialogHeight=210px; center:yes; status:no; scroll:yes; help:no");
}

function doCloseOrder(sOrder) {
	if (confirm("Close Order\n\nThis will close the order, regardless of whether or not it was shipped. To continue, press OK. Press cancel to return.")) {
		document.location.href = "orderclose.cfm?K=" + sOrder;
	}
}

function doComment(sOrder) {
	var W = 550, H = 320;
	L = (screen.width - W) / 2;
	T = (screen.height - H) / 2;
	oWin = window.open("ordercommentedit.cfm?K=" + sOrder, "CommentWin", "width=" + W + ",height=" + H + ",left=" + L + ",top=" + T + ",scrollbars=yes,status=no");
	oWin.focus();
}

function doEmail(sOrder) {
	var W = 593, H = 488;
	L = (screen.width - W) / 2;
	T = (screen.height - H) / 2;
	oWin = window.open("ordermail.cfm?K=" + sOrder, "EmailWin", "width=" + W + ",height=" + H + ",left=" + L + ",top=" + T + ",scrollbars=yes,status=no");
	oWin.focus();
}

function doInvoice(sOrder) {
//	Removed PrintedTicket setting.
//	document.op.action="setstatus.cfm?OrderId=" + sOrder + "&Status=PrintedTicket";
//	document.op.submit();
	oWin = window.open("invoiceshow.cfm?K=" + sOrder, "InvoiceWin", "");
	oWin.focus();
}

function doOrder(sColumn, sDir, sForm) {
	oForm = document.forms[sForm];

	oForm["SortOrder"].value = sColumn;
	oForm["SortDirection"].value = sDir;
	oForm.submit();
/*
	self.location.href = sForm + 'list_tb.cfm?orderby=' + sColumn + '&dir=' + sDir;
//	showWait(true);
	top.workspace[sForm + "list"].location.href = sForm + 'list.cfm?orderby=' + sColumn + '&dir=' + sDir;
*/
}

function doReopenOrder(sOrder) {
	mResult = confirm("Reopen Order\n\nThis will reopen the order. To continue, press OK. Press cancel to return.");
	if (mResult == true) {
		document.op.action="setstatus.cfm?OrderId=" + sOrder + "&Status=Reopened";
		document.op.submit();
	}
}

function doShipComplete(sOrder, sFormName) {
/*
	Automate the process of assigning the shipping quanties for
	an order in orderpreview.cfm.
	06/04/2005: Fixed a bug that caused the overwriting of the
				hidden shipped quantity field.
*/
	var iComplete = 0;
	var ii = 0;
	var oForm = document.forms[sFormName];
	if (! confirm("You are about to ship all remaining items in the order. Are you sure?")) {
		return false;
	}
	for (ii = 0; ii < oForm.elements.length; ii++) {
		var oE = oForm[ii];
//		alert(oE.name);
		if (oE.name) {
			//	Take the number remaining to be shipped.
			if (oE.name.substr(0, 6) == "ToShip") {
				iComplete = oE.value;
//				alert(oE.name + "=" + oE.value);
			}
			//	Fill the number into the form.
//			if (oE.name.substr(0, 2) == "S_") { //-- Bug in code.
			if (oE.name.substr(0, 2) == "S_" && oE.type == "text") {
//				alert(oE.name + "=" + oE.value);
				oE.value = iComplete;
//				alert(oE.name + "=" + oE.value);
			}
		}
	}

	doSubmitOrder(sOrder, sFormName);
}

function doShowShipping(sOrder) {
	var W = 550, H = 173;
	L = (screen.width - W) / 2;
	T = (screen.height - H) / 2;
	oWin = window.open("ordershipping.cfm?K=" + sOrder, "ShippingWin", "width=" + W + ",height=" + H + ",left=" + L + ",top=" + T + ",scrollbars=yes,status=no");
	oWin.focus();
}

function doSKUFilter() {
	var lstSKU = prompt("Set a list of SKU's to filter by. Use commas to separate SKU's.", "");
	var oFrame = top.frames["workspace"].orderlist;
//	alert(oFrame.location.href);
	var sHref = oFrame.location.href;
	//	Remove any SKU search string from the href value.
	iPos = sHref.indexOf("&");
	if (iPos >= 0) {
		sHref = sHref.substr(0, iPos);
	}
	alert(sHref);
	if (lstSKU == "") {
		oFrame.location.href = sHref;
	}
	else {
		oFrame.location.href = sHref + "&SKU=" + lstSKU;
	}
//	alert("SKU Filter");
}

function doSubmitEngrave() {
	document.op.action="toengraver.cfm";
	document.op.submit();
}

function doSubmitOrder(iOrder, sFormName) {
/*
	Determine whether this is a partial shipment and, if yes, confirm
	that this is intentional in orderpreview.cfm.
	06/04/2005: Fixed a bug that compared the quantity and shipped
				amount for all rows. It should only compare incomplete
				rows and then only with the remaining quantity to ship.
*/
	var bOk = true;
	var mBackItems = "";
	var oForm = document.forms["op"];
	var sToShip = oForm["ToShip"].value;
	var arToShip = sToShip.split(",");
	for (ii = 0; ii < TotalItems; ii++) {
		var oShipped = oForm["S_" + ItemsDisplayed[ii]];
		//	If the shipped field is hidden, then it's completed.
		if (oShipped.type == "text") {
//			mDiscrepancy = oForm["SQ_" + ItemsDisplayed[ii]].value - oShipped.value;
			mDiscrepancy = arToShip[ii] - oShipped.value;
//			alert(oForm["SQ_" + ItemsDisplayed[ii]].name + ":" + oForm["SQ_" + ItemsDisplayed[ii]].value); 
//			alert("arToShip[" + ii + "]" + ":" + arToShip[ii] + " = " + oShipped.name + ":" + oShipped.value); 
//			alert("mDiscrepancy" + ":" + mDiscrepancy);
			if (mDiscrepancy != 0) {
				mBackItems = mBackItems + mDiscrepancy + " out of " + oForm["SQ_" + ItemsDisplayed[ii]].value + " pcs for item '" + ItemsDisplayed[ii] + "' [" + oForm["SD_" + ItemsDisplayed[ii]].value + "]\n";
			}
		}
	}
	if (mBackItems != "") {
		bOk = confirm("Shipping Discrepancy\n\nThe following items have not been shipped the amount ordered:\n\n" + mBackItems + "\nIf this is correct, press OK to continue. Press Cancel to make any required changes.");
	}
	if (bOk) {
		//	05/11/2005:	Allow for change of FormName when Finish button is pressed.
		if (arguments.length == 2) {
			oForm["FormName"].value = arguments[1];
		}
		oForm.action = "orderfinish.cfm?K=" + iOrder;
		oForm.submit();
	}
}

function FocusOn(sObject) {
	/*
		Created: 01/03/2004
	*/
	//	First set the focus to the window.
	window.focus();
	if (arguments.length == 0) {
		return;
	}
	//	Then set focus to the specified object.
	oObj = eval(sObject);
	oObj.focus();
}

function OpenPop(sURL, sTarget, sDimensions, sAttributes) {
/*
	Pop-up the URL in the target window.
	In general, the window is not resizable, but for certain types
	of window content, we want to allow it.
*/
	var W = 500;
	var H = 300;
	var L = 100;
	var T = 100;
	//	Allow the window dimensions to be passed.
	if (sDimensions) {
		var ar = sDimensions.split(",");
		W = ar[0];		
		H = ar[1];		
		L = ar[2];		
		T = ar[3];		
	}
	var sAttr = ",scrollbars=yes";
	if (sAttributes) {
		sAttr += sAttributes;
	}
	if (sTarget == "_document" || sTarget == "_email" || sTarget == "_help") {
		W = 600;
		H = 400;
		T = 50;
		if (sTarget == "_document") {
			sAttr += ",menubar=yes";	//	To allow for printing.
		}
		sAttr += ",resizable=yes,status=yes";
	}
	if (sURL == "") {
		alert("The web address is blank.");
	}
	else {
		window.open(sURL, sTarget, "width=" + W + ",height=" + H + ",left=" + L + ",top=" + T + sAttr);
	}
	return false;
}

function selectRow(mT, sWindow) {
	var oWin = parent;
//	var oWinSub = oWin[sWindow];
	var sBGColor = "LightGrey";	// "highlight"
	var sFGColor = "Navy";	// "highlighttext"
	if (bOrders) {
		if (document.getElementById) {
			if (mT.mSelected == null) {
				if (prevSelRow) {
					prevSelRow.replaceNode(prevSelStyle);
				}

				prevSelStyle = mT.cloneNode(true);
				prevSelRow = mT;

				mT.style.background = sBGColor;
				mT.style.color = sFGColor;
				mT.mSelected = true;

				if (bSearchArchive) {
					oWinSub.loadArchive(mT.id);
				}
				else {
//					oWinSub.loadOrder(mT.id);
					window.open(sWindow + '.cfm?K=' + mT.id, sWindow);

//	alert(sWindow);
//	return true;
				}

				clearTimeout(timerID);
			}
		}
		else {
			//	This makes it work, without hightlighting
			//	in some other browsers.
			mT.style.background = sBGColor;
			mT.style.color = sFGColor;
			if (bSearchArchive) {
				oWinSub.loadArchive(mT.id);
			}
			else {
				oWinSub.loadOrder(mT.id);
			}
		}
	}
}

function showPopup(sMsg) {
	if (sMsg != "") {
		alert(sMsg);
	}
}

function showWait(bShow) {
	if (bShow == true) {
		var W = 200, H = 100;
		L = (screen.width - W) / 2;
		T = (screen.height - H) / 2;
		ww = window.open("showwait.cfm","WaitWin","height=" + H + ",left=" + L + ",scrollbars=yes,status=no,top=" + T + ",width=" + W);
	} else {
		if (ww) {
			ww.close();
		}
	}
}

/*
Change History:
01/28/2004:	Removed PrintedTicket setting from doInvoice.
02/15/2004:	Moved showPopup() into this script.
			Moved askDel() into this script.
04/09/2005:	Changed doOrder to work outside of frame.
			Renamed from beops.js.
04/30/2005:	Added new function - bSetChangedCheck.
			Added function CheckSome from msc_util.js
05/01/2005:	Added new function - CalcSalePrice.
05/21/2005:	Added new function - bSetChangedRadio.
01/17/2006:	Added new function - DittoSet.
			Added new function - DittoSetAll.
2008-05-18:	Added new function - AreaHide.
			Added new function - AreaShow.
2008-05-24:	Added new function - AssignMessage
			Added new function - AssignNext
2008-08-08:	Added new function - CharCounter
2008-10-30:	Added new function - DittoViewAll.
*/