var g_el = new Array();

//----- Basic el info (other el types must define these set of properties)
El.prototype.name;
El.prototype.submitName;
El.prototype.dirty;
El.prototype.validator;
El.prototype.preSub;
El.prototype.reqReset;
El.prototype.GetValue = GetHTMLElementValue;
El.prototype.SetValue = SetHTMLElementValue;

function El(name, submitName, dirty, validator, prepareSubmit, reqReset) {
	El_Init(this,name,submitName,dirty,validator,prepareSubmit,reqReset);
}

function El_Init(el, name, submitName, dirty, validator, prepareSubmit, reqReset) {
	el.name = name;

	if (submitName.length > 0)
		el.submitName = submitName;
	else
		el.submitName = name;

	el.dirty = dirty;
	el.validator = g_elementValidator[validator];
	el.preSub = g_prepareSubmitList[prepareSubmit];
	el.reqReset = reqReset;
}

//----- Checkboxes
El_CheckBox.prototype.name;
El_CheckBox.prototype.submitName;
El_CheckBox.prototype.dirty;
El_CheckBox.prototype.validator;
El_CheckBox.prototype.preSub;
El_CheckBox.prototype.reqReset;
El_CheckBox.prototype.GetValue	= El_CheckBox_GetValue;
El_CheckBox.prototype.SetValue	= El_CheckBox_SetValue;
El_CheckBox.prototype.onVal;
El_CheckBox.prototype.offVal;

function El_CheckBox(name, submitName, dirty, validator, prepareSubmit, reqReset, onVal, offVal) {
	El_Init(this,name,submitName,dirty,validator,prepareSubmit, reqReset);
	this.onVal = onVal;
	this.offVal = offVal;
}
function El_CheckBox_GetValue(element) {
	if(element.checked)
		return this.onVal;
	else
		return this.offVal;
}
function El_CheckBox_SetValue(element, value) {
	if(this.onVal == value) {
		element.checked = true;
		return true;
	}
	else if (this.offVal == value) {
		element.checked = false;
		return true;
	}
	return false;
}

//----- Special check box
El_MultiCheck.prototype.name;
El_MultiCheck.prototype.submitName;
El_MultiCheck.prototype.dirty;
El_MultiCheck.prototype.validator;
El_MultiCheck.prototype.preSub;
El_MultiCheck.prototype.reqReset;
El_MultiCheck.prototype.GetValue		= El_MultiCheck_GetValue;
El_MultiCheck.prototype.SetValue		= SetHTMLElementValue;
El_MultiCheck.prototype.codeList;
El_MultiCheck.prototype.textList;
El_MultiCheck.prototype.bCaseSensitive;
El_MultiCheck.prototype.FindOption		= El_MultiCheck_FindOption;
El_MultiCheck.prototype.onKey			= El_MultiCheck_OnKey;
El_MultiCheck.prototype.onDblClick		= El_MultiCheck_OnDblClick;

function El_MultiCheck(name, submitName, dirty, validator, prepareSubmit, reqReset, bCaseSensitive, selList) {
	var i;
	var j;
	var codeTxt;
	
	El_Init(this,name,submitName,dirty,validator,prepareSubmit,reqReset);
	this.bCaseSensitive = bCaseSensitive;
	this.codeList = new Array();
	this.textList = new Array();
	codeTxt = selList.split(",");
	if (codeTxt == null)
		return;

	for (i=0; i < codeTxt.length; i++) {
		var part = codeTxt[i].split(":");
		this.codeList[this.codeList.length] = part[0];
		this.textList[this.textList.length] = part[1];
	}
}
function El_MultiCheck_GetValue(element) {
	var value = GetHTMLElementValue(element);
	var i = this.FindOption(value, false);
	if (i >= 0)
		return this.codeList[i];

	return value;
}

function El_MultiCheck_FindOption(txt, bByCode) {
	var val;
	var txtVal;
	var i;
	var list;

	if (bByCode)
		list = this.codeList;
	else
		list = this.textList;

	val = txt;
	if (this.bCaseSensitive != 1) {
		val = val.toUpperCase();
		for (i=0; i < list.length; i++)
			list[i] = list[i].toUpperCase();
	}

	for (i=0; i < list.length; i++) {
		if (val == list[i])
			return i;
	}
	return -1;
}
function El_MultiCheck_OnKey(element, keyVal) {
	var value = GetHTMLElementValue(element);
	var txtVal;
	var i;

	// If char is space, cycle through the values
	if (keyVal == ' ') {
		i = this.FindOption(value, false);
		if (i >= 0) {
			i = (i+1) % this.textList.length;
			this.SetValue(element, this.textList[i]);
		}
		else
			this.SetValue(element, this.textList[0]);

		return true;
	}
	
	// No space, so use actual char pressed
	i = this.FindOption(keyVal, false);
	if (i >= 0) {
		this.SetValue(element, this.textList[i]);
		return true;
	}
	return false;
}
function El_MultiCheck_OnDblClick(element) {
	return this.onKey(element, ' ');
}

//----- Helper functions for code generation
function newEl(name, submitName, dirty, validator, prepareSubmit,reqReset) {
	g_el[g_el.length] = new El(name, submitName, dirty, validator, prepareSubmit, reqReset);
}
function newChkBx(name, submitName, dirty, validator, prepareSubmit, reqReset, onVal, offVal) {
	g_el[g_el.length] = new El_CheckBox(name, submitName, dirty, validator, prepareSubmit, reqReset, onVal, offVal);
}
function newMChkBx(name, submitName, dirty, validator, prepareSubmit, reqReset, bCaseSensitive, selList) {
	g_el[g_el.length] = new El_MultiCheck(name, submitName, dirty, validator, prepareSubmit, reqReset, bCaseSensitive, selList);
}
function newElData(name, submitName, dirty, validator, prepareSubmit, reqReset, value) {
	g_el[g_el.length] = new El_Data(name, submitName, dirty, validator, prepareSubmit, reqReset, value);
}

function onChg(element) {
	El_SetDirty(element);
}

function onKey(element, e)
{
	var el;
	var elIndex;
	var charCode = Event_GetCharCode(e);

	elIndex = El_Find(element);
	if (elIndex < 0)
		return false;

	el = g_el[elIndex];

	if ( el.onKey(element, String.fromCharCode(charCode)) ) {
		El_SetDirtyByIndex(elIndex);
		return true;
	}
	return false;
}

function onDblClk(element) {
	var el;
	var elIndex;

	elIndex = El_Find(element);
	if (elIndex < 0)
		return false;

	el = g_el[elIndex];
	if ( el.onDblClick(element) ) {
		El_SetDirtyByIndex(elIndex);
		return true;
	}
	return false;
}

function onMi(element) {
	elIndex = El_Find(element);
	if(elIndex < 0)
		return;

	var idParts = g_el[elIndex].name.split("-");
	var sdHelp = HelpText_Find("sd_" + idParts[0]);
	var elHelpTxt = "";
	var sdHelpTxt = "";
	var str = "";

	if (sdHelp != null)
		sdHelpTxt = sdHelp.text;

	if(g_el[elIndex].validator != null) {
		elHelpTxt = g_el[elIndex].validator.getHelpText(element);
		str = elHelpTxt.replace(/\n/g, "<br />");
	}

	if (str.length > 0)
		str += "<br /><br />" + sdHelpTxt;
	else
		str = sdHelpTxt;

	WriteToLayer("helpText2", str);
}

//---- Helper fuctions for mapping HTML element to g_el[] element
function El_Find(element) {
	for (var i=0; i < g_el.length; i++) {
		if (g_el[i].name == element.name)
			return i;
	}
	return -1;
}

function El_SetDirtyByIndex(elIndex) {
	document.forms["theDataForm"].elements["hasDataChanged"].value = 1;
	g_el[elIndex].dirty = 1;
}

function El_SetDirty(element) {
	var i;
	i = El_Find(element);
	if (i < 0)
		return;

	El_SetDirtyByIndex(i);
}

function GetPageSdList(valSep) {
	var idParts;
	var sdList = new Array();

	for (var i=0; i < g_el.length; i++) {
		idParts = g_el[i].name.split("-");

		// Only add it if its not in our list
		for (var j=0; j < sdList.length; j++) {
			if (sdList[j] == idParts[0]) break;
		}
		if (j == sdList.length)
			sdList[sdList.length] = idParts[0];
	}

	return sdList.join(valSep);
}

//----- Basic el info (other el types must define these set of properties)
El_Data.prototype.name;
El_Data.prototype.submitName;
El_Data.prototype.dirty;
El_Data.prototype.validator;
El_Data.prototype.preSub;
El_Data.prototype.reqReset;
El_Data.prototype.GetValue = El_Data_GetValue;
El_Data.prototype.SetValue = El_Data_SetValue;
El_Data.prototype.value;

function El_Data(name, submitName, dirty, validator, prepareSubmit, reqReset, value) {
	El_Init(this,name,submitName,dirty,validator,prepareSubmit,reqReset);
    this.value = value;
}

function El_Data_SetValue(element, value) {
    this.value = value;
    return true;
}

function El_Data_GetValue(element) {
    return this.value;;
}

function FindElementByName(name) {
    var dataForm = document.forms["theDataForm"];
	for (var i=0; i < dataForm.elements.length; i++) {
		if (dataForm.elements[i].name == name)
			return dataForm.elements[i];
	}
	return -1;
}

function El_FindByName(name) {
	for (var i=0; i < g_el.length; i++) {
		if (g_el[i].name == name)
			return i;
	}
	return -1;
}

function onChgMode(element) {
    // Get sdName format M_<SDNAME>-<KEY1>
    var mode = element.value;
    var sdName = element.name.split("_");
    
    // Get INPUT element index
    var name = sdName[1] + "-0-0";
    var i_el = FindElementByName(name);

    // Get Data element index
    name = sdName[1] + "-" + mode + "-0";
    var i = El_FindByName(name);

    // Change INPUT value by mode
    i_el.value = g_el[i].GetValue(i_el);
}

function onChgValue(element) {
    // Get sdName <SDNAME>-<KEY1>-0-0
    var sdName = element.name.split("-");
    
    // Get MODE element index
    var name = "M_" + sdName[0] + "-" + sdName[1];
    var m_el = FindElementByName(name);
    var mode = m_el.value;
    
    // Get Data element index
    name = sdName[0] + "-" + sdName[1] + "-" + mode + "-0";
    i = El_FindByName(name);
    El_SetDirtyByIndex(i);

    // Set element value by INPUT
    g_el[i].SetValue(element, element.value);
}

function elSelCompactReg(sdId,elPos) {
    g_elSelCompactRegister[g_elSelCompactRegister.length++] = new Pair(sdId, elPos);
}

function elSelCompactPopulate(theForm) {
	var element;
	var elIndex;
	
	// Validate each element in the form
	for(i=0 ; i < theForm.length; i++) {
		element = theForm.elements[i];
		
		switch(element.type)
		{
		case "combobox":
	    case "select-one":
	    case "select-multiple":	    
	        break;
	    default:
	        continue;
		}
		
        var currentVal = GetHTMLElementValue(element);
		for (j=0; j < g_elSelCompactRegister.length; j++) {
		    if (!elMatchName(element.name, g_elSelCompactRegister[j].a,"","",g_elSelCompactRegister[j].b) )
		        continue;

		    // Found match
		    var elSelCompact = eval("g_elSelCompact_" + g_elSelCompactRegister[j].a + "_" + g_elSelCompactRegister[j].b);
		    for (k=0; k < elSelCompact.length; k++) {
		        element.options[k] = new Option(elSelCompact[k].a, elSelCompact[k].b);
		    }
		    SetHTMLElementValue(element, currentVal);
		    break;
		}
	}    
}

