/*
	Standard Functions providing user interface support for constraint User Interfaces
	Author: Chuck Ingrum, Nathan Huebner
*/

/* 
All material herein (c) 2004 TechniCon Corporation              
All Rights Reserved.

The source code is owned by TechniCon Corporation and is protected by  
copyright laws and international copyright treaties, as well as other   
intellectual property laws and treaties. COPYRIGHT. The source code is  
licensed, not sold. All right, title and interest in the source code    
(including any images, "applets," photographs, animations, video, audio,
music, and text incorporated into the source code), accompanying printed
materials, and any copies you are permitted to make herein, are owned by
TechniCon Corporation, and the source code is protected by United States 
copyright laws and international treaty provisions.  Therefore, you must
treat the source code like any other copyrighted material.      
*/

/*
	The following objects and arrays must have been declared somewhere in the referencing page. Normally this
	will be done by the js_config_init_blocksV2.cfm module.
	
		aExRules = [];
		oDomainToRuleMap;
		oDomains = new DomainMap();
		oEMsgStr = new MessageStore();
*/

//Override values as necessary in calling document.
var gNoConstraintColor = "#000000";
var gExcludedChoiceColor = "#777777";
var gHardConstraintColor = "#A00000";
var gSoftConstraintColor = "#807000";

var gConstraintFormID = "my_config"; //Reset in app as required.

function setDomainValue(ndomid, oFormEle) {
	/**

		Select Elements: If the selectedIndex is 0 then unset the 
						 domain. Otherwise set it. Domains set through
						 this routine are userset.
	**/
	var oDom = oDomains.getDomainObject(ndomid);

	if (oDom.dtype == Domain.List) {
		setListDomainValue(oDom, oFormEle)
	} else {
		//oFormEle must be a text input element
		if (oFormEle.value == '') {
			oDom.setChoice(-1, Domain.NotSet);
		} else {
			switch (oDom.dtype) {
			case Domain.IntegerRange:
				setIntegerDomainValue(oDom, oFormEle);
				break;
			case Domain.DecimalRange:
				setDecimalDomainValue(oDom, oFormEle);
				break;
			case Domain.Mixed:
				setMixedDomainValue(oDom, oFormEle);
				break;
			case Domain.Constant:
				//No Action
				break;
			default:
				alert('Cannot not set selected choice for domain type '+oDom.dtype+' in domain '+oDom.label+'.');
				return;
			}
		}
	}
}


function setListDomainValue(oDom, oFormEle) {
	//var choiceid = -1;
	//var domainstate = Domain.NotSet;
	var form_type = getFormObjectType(oFormEle);
	
	oDom.clearDomainChoices();
		
	if (form_type == "select-multiple") {
		for (var i=0; i<oFormEle.options.length; i++) {
			if (oFormEle.options[i].selected) {
				oDom.setChoice(oFormEle.options[i].value, Domain.UserSet);
			}
		}
	} else {
		var form_value = getFormObjectValue(oDom, oFormEle);
		var nDomID = parseInt(form_value);
		
		if (!isNaN(form_value)) {
			switch (form_type) {
			case "select-one":
				if (oFormEle.selectedIndex != 0) {
					//choiceid = oFormEle.options[oFormEle.selectedIndex].value;
					oDom.setChoice(form_value, Domain.UserSet);
				}
				break;
			case "radio":
				oDom.setChoice(form_value, Domain.UserSet);
				break;
			case "checkbox": //should  be treated same as select-multiple
				oDom.setChoice(form_value, Domain.UserSet);
				break;
			}
		}
	}
}


function setIntegerDomainValue(oDom, oFormEle, bReportError) {
	var bDomainSet = false;

	if (arguments.length < 3) bReportError = true;
	
	numval = parseInt(oFormEle.value);
	
	if (isNaN(numval)) {
		if (bReportError) alert('Not a number value: "'+oFormEle.value+'"');
		return bDomainSet;
	}

	oDom.clearDomainChoices();
	
	var oDomMember = oDom.validateValueRange(numval);
	if (oDomMember != null) {
		document.getElementById('dom_'+oDom.did+'_choiceid').value = oDomMember.id;
		numval = Math.floor(numval);
		//document.getElementById('dom_'+oDom.did).value = numval;
		oFormEle.value = numval;
		sNum = Number(numval).toString();
		oDom.setChoice(oDomMember.id, Domain.UserSet, sNum);
		bDomainSet = true;
	} else {
		if (bReportError) alert('Number out of range: '+numval);
	}	
	
	return bDomainSet;
}


function setDecimalDomainValue(oDom, oFormEle, bReportError) {
	var bDomainSet = false;
	
	if (arguments.length < 3) bReportError = true;
	
	numval = parseFloat(oFormEle.value);
	
	if (isNaN(numval)) {
		if (bReportError) alert('Not a number value: "'+oFormEle.value+'"');
		return bDomainSet;
	}

	oDom.clearDomainChoices();
	
	var oDomMember = oDom.validateValueRange(numval);
	if (oDomMember != null) {
		var sNum;
		document.getElementById('dom_'+oDom.did+'_choiceid').value = oDomMember.id;
		//document.getElementById('dom_'+oDom.did).value = numval;
		oFormEle.value = numval;
		sNum = Number(numval).toString();
		/* Part Number Block Formatting Deferred until block is requested 
		if ('undefined' == typeof DomInputValProcessor) {
			sNum = Number(numval).toString();
		} else {
			//DomInputValProcessor must be supplied by calling app
			sNum = DomInputValProcessor(oDom, oDomMember, numval);
		}
		*/
		oDom.setChoice(oDomMember.id, Domain.UserSet, sNum);
		bDomainSet = true;
	} else {
		if (bReportError) alert('Number out of range or not on specified interval boundary: '+numval);
	}	
	
	return bDomainSet;
}


function setMixedDomainValue(oDom, oFormEle, bReportError) {
	var bDomainSet = false;
	
	if (arguments.length < 3) bReportError = true;

	if (!setDecimalDomainValue(oDom, oFormEle, false)) {
		var oDomMember = oDom.validateValueList(oFormEle.value);
		
		if (oDomMember != null) {
			document.getElementById('dom_'+oDom.did+'_choiceid').value = oDomMember.id;
			//It does not make sense to replace a user typed in value with a code
			//document.getElementById('dom_'+oDom.did).value = oDomMember.code;
			oDom.clearDomainChoices();
			oDom.setChoice(oDomMember.id, Domain.UserSet, oDomMember.code);
			bDomainSet = true;
		} else if (bReportError) {
			alert('Not a valid entry: "'+oFormEle.value+'"');
		}
	}
	return bDomainSet;
}

//TODO: Should be defined in stdevents.js instead of here.
function eventKeypress(e)
{
	var key;
	var ele;
	var retval = true;
	if (!e) var e = window.event;
	
	if (e.keyCode) key = e.keyCode;
	else if (e.which) key = e.which;
	//window.status=key DEBUG
	if (key == 13) {
		if(e.srcElement) {
			e.cancelBubble = true;
			e.srcElement.blur();
		} else if (e.target) {
			e.stopPropagation();
			e.target.blur();
		}
		retval = false;
	}
	return retval;
}


function getDomainConflictMessages(domainid, slinefeed) {
	/*
		Get any generated messages for the domain
		For each violated rule
			If there is a reason id attempt to get from the message store
			
			If the message cannot be obtained or the reason id is 0 get
			a generated message from the rule
	*/
	var oRule;
	var oDom = oDomains.domains[domainid];
	var sMessage='';
	var tmpMessage;

	if (arguments.length == 1) {
		slinefeed = '\n';
	}

	//non rule related messages created during configuration evaluation 
	for (var id in oDom.generatedMessages) {
		if (oDom.generatedMessages.hasOwnProperty(id)) {
			sMessage += oDom.generatedMessages[id]+slinefeed;
		}
	}
	for (var i=0; i<oDom.RulesViolated.length; i++) {
		oRule = oDom.RulesViolated[i];
		if (oRule.reasonid == 0) {
			tmpMessage = oRule.createMessage(oDomains);
		} else {
			tmpMessage = oEMsgStr.getMessage(oRule.reasonid);
			if (tmpMessage == null) {
				tmpMessage = oRule.createMessage(oDomains);
			}
		}
		sMessage += tmpMessage+slinefeed;
	}
	return sMessage;
}


function getFormObject(blkindx)
{
	var UNDEFINED;
	var oFormEle = document.getElementById(gConstraintFormID);
	if (oFormEle == null) {
		alert("getFormObject error: getElementById for id="+gConstraintFormID+" returned null.");
	}
	if (oFormEle["dom_"+blkindx] == UNDEFINED) {
		// radio button
		return oFormEle["dom_"+blkindx+"_1"];
	} else {
		return oFormEle["dom_"+blkindx];
	}
	/* The old naming system is no longer used
	if (oFormEle['xblk'+blkindx] === UNDEFINED) {
		//option block is represented by a text field
		return oFormEle["dom_"+blkindx];
	} else {
		//option block is represented by a select or radio button element
		return oFormEle["xblk"+blkindx];
	}
	*/
}


function getFormObjectType(formObject)
{
	var UNDEFINED;
	if (formObject == UNDEFINED) {
		return UNDEFINED;
	} else if (formObject.type === UNDEFINED) {
		return formObject[0].type;
	} else {
		return formObject.type;
	}
}

function getFormObjectValue(objDom, objForm)
{
	var frmValue='';
	switch (getFormObjectType(objForm)) {
	case 'select-one':
		frmValue = objForm.options[objForm.selectedIndex].value;
		break;
	case 'radio':	//Object may be a group of radio buttons or a radio button object that was clicked on.
		if (objForm.type === undefined) {
			var oRadioGroup = objForm; //document.getElementById(gConstraintFormID)['dom_'+objDom.did]
			for (i=0; i<oRadioGroup.length; i++) {
				if (oRadioGroup[i].checked) {
					frmValue = oRadioGroup[i].value;
					break;
				}
			}
		} else {
			frmValue = objForm.value;
		}
		break;
	case 'checkbox':
		//TODO: Rather than using the hidden form values the domain object should be used.
		if (objForm.checked) {
			frmValue = document.getElementById(gConstraintFormID)['valblk1'+objDom.did].value;
		} else {
			frmValue = document.getElementById(gConstraintFormID)['valblk0'+objDom.did].value;
		}
		break;
	case 'text':
		frmValue = objForm.value;
		break;
	default:
		alert('Unimplemented type in setOptionBlock: '+getFormObjectType(objForm));
		break;
	}
	return frmValue;
}


function setFormObjectValue(objForm, strValue)
{
	switch (getFormObjectType(objForm)) {
	case 'select-one':
		for (i=0; i<objForm.options.length; i++) {
			if (strValue == objForm.options[i].value) {
				objForm.options[i].selected = true;
				break;
			}
		}
		break;
	case 'radio':
		for (i=0; i<objForm.length; i++) {
			if (strValue == objForm[i].value) {
				objForm[i].checked = true;
				break;
			}
		}
		break;
	case 'checkbox':
		objForm.checked = (strValue == document.getElementById(gConstraintFormID)['valblk1'+blkindx]);
		break;
	case 'text':
		objForm.value = strValue;
		break;
	default:
		alert('Unimplemented type in setOptionBlock: '+getFormObjectType(objForm));
		break;
	}
}

