//#?package KICSide
/////-----------------------------------------------------------------------------------------
//#=object Dictionary

//#=method Dictionary()
//#=purpose This instantiates the Dictionary Object
//#+        This object is used internally to marshall the form/sql data.

function Dictionary()
{
this.terms = new Object();
this.cnt = 0;
}

//#=method length()
//#=returns length of the diction object.

Dictionary.prototype.length = function()
{
return this.cnt;
}

//#=method add(a,b)
//#=purpose add the item to the dictionary for ease of retrieval.
//#+        a = fieldname
//#+        b = value
//#+

Dictionary.prototype.add = function(a, b) {
this.terms[a] = b;
this.cnt++;
}

//#=method del(a)
//#=purpose This deletes the record identified by key 'a' from the dictionary.

Dictionary.prototype.del = function(a){
delete this.terms[a];
this.cnt--;
}

//#=method list()
//#=purpose This provides a list of the dictionary items.  This is used primarily for debugging.
Dictionary.prototype.list = function(){
var names = "";
for(var i in this.terms) names += i + " " + this.terms[i] + "\n";
alert(names);
}

//#=method get(key)
//#=purpose get the value for the key.

Dictionary.prototype.get = function(key)
{
return this.terms[key];
}

//#/object
////----------------------------------------------------------------------------------------------
//#=object RecordSet

///  Function RecordSet Below

//#method RecordSet
//#=purpose this is and empty constructor for the RecordSet Object.

function RecordSet()
{
	this.RecNum = 0;
	this.valid = 0;
	this.field = ["a","b"];
	this.data = [["1","2"],["3","4"]];
	this.D = new Dictionary();

	for(var i=0; i < this.field.length-1; i++)
		{
		this.D.add(this.field[i], i);
		}
		
}

//#method RecordSet
//#=purpose this is a constructor for the RecordSet Object.

function RecordSet(field, data)
{
	this.RecNum = 0;
	if(field != null)
	{	this.valid = 1;
		this.field = field;
		this.data = data;
		//this.treestatus = new Array();
	}
	else
	{	this.valid = 0;
		this.field = ["a","b"];
		this.data = [["",""],["",""]];
		//this.treestatus = new Array();
	}
	this.D = new Dictionary();
	for(var i=0; i < this.field.length; i++)
		{
		this.D.add(this.field[i], i);
		//this.treestatus[i] = 0;
		}
		
}

//#method moveNext
//#=purpose this moves the counter to the next record.
//#+
//#+

RecordSet.prototype.moveNext = function()
{
	if (this.RecNum < this.data.length-1)
	{
		this.RecNum = this.RecNum + 1;
	}
}

//#method EOR
//#=purpose this returns true if you are at the last record.
//#+
//#+

RecordSet.prototype.EOR = function()
{
	if (this.RecNum >= this.data.length - 1)
	{
	return true;
	}
	else
	{
	return false;
	}
}

//#method getCursor()
//#=purpose this returns the record number the Object is looking at.
//#+
//#+

RecordSet.prototype.getCursor = function()
{
return this.RecNum;
}

//#method movePrev()
//#=purpose this moves the record counter back one if possible.
//#+
//#+

RecordSet.prototype.movePrev = function()
{
	if (this.RecNum > 0)
	{
		this.RecNum = this.RecNum - 1;
	}
}

//#method getRecord(num)
//#=purpose this returns true if you are at the last record.
//#+
//#=param num = the record number you want returned (as indexed in the array).

RecordSet.prototype.getRecord = function(num)
{
	if (num <= this.data.length - 1)
	{
		this.RecNum = num;
	}
}


//#method moveTo(num)
//#=purpose this moves the cursor to the record with id='num'.
//#+
//#=param num = the record number you want to move to.


RecordSet.prototype.moveTo = function(num)
{
this.moveFirst();
while(this.getItem("id") != num){this.moveNext();}
return this.RecNum;
}





//#method moveLast
//#=purpose this moves to the last record in the RecordSet.
//#+
//#+

RecordSet.prototype.moveLast = function()
{
	this.RecNum = this.data.length-1;
}

//#method moveFirst
//#=purpose this moves to the First record in the RecordSet.
//#+
//#+

RecordSet.prototype.moveFirst = function()
{
	this.RecNum = 0;
}

//#method getSingleItem(num, name)
//#=purpose this returns the single item requested.
//#+
//#=param num=the index number from the array.
//#=param name=the name of the field to pull from.
//#+
//#+

RecordSet.prototype.getSingleItem = function(num, name)
{
	if (this.valid == 0){anitem = "";}
	else {anitem = this.data[num][this.D.get(name)];}
	return anitem;
}

//#method getItem(name)
//#=purpose this returns the item from the current RecordSet.
//#+
//#=param name= the name of the field to pull from.
//#+
//#+

RecordSet.prototype.getItem = function(name)
{
	if (this.valid == 0){anitem = "";}
	if (this.data.length != 0)
	{
	//alert("RecNum: " + this.RecNum + "\nname: " + name + "\nD.get: " + this.D.get(name));
	anitem = this.data[this.RecNum][this.D.get(name)];
	
	}
	else{anitem = "";}
	return anitem;
}


//#method editList(funct, fieldName)
//#=purpose this returns a menu of the Recordset Items pointing to a function call.
//#+
//#+

RecordSet.prototype.editList = function(funct, fieldName)
	{
	document.write("<menu>");
	this.moveFirst();
	for(var i=0; i < this.data.length; i++)
		{
		document.write("<li><a href='" + funct + "(" + i+ ")'>" + this.getItem(fieldName) + "</a>\n");
		this.moveNext();
		}
	document.write("</menu>");
	}	

//#method length
//#=purpose this returns the number of Records in the RecordSet.
//#+
//#+

RecordSet.prototype.length = function()
{
	return this.data.length;
}

//#method get(key)
//#=purpose this returns the item from the RecordSet at the current counter.
//#+
//#=param key = the name of the field to pull from.
//#+
//#+

RecordSet.prototype.get = function(key)
	{
	return this.getItem(key);
	}

//#/object
	
///----------------------------------------------------------------------------------------------

//#=object mpform

//#=method mpform(name, action, color, theKey)
//#=purpose this instantiates the KIForm2 object
//#+
//#+        name - the name of the array that belongs to this form object.
//#+
//#+        //action - the url for the form on submission.
//#+        color - the color to be used for erroneous data validation.
//#+		//theKey - the primary key to the associated database table.

function mpform(name, color, theKey)
{var undefined;
this.QName = new Dictionary();
this.QValue = new Dictionary();
this.tableKey = theKey;
this.q = -1;
this.extra = new Dictionary();
this.vars = new Dictionary();
this.type = new Dictionary();
this.num = new Dictionary();
this.list = new Dictionary();
this.key = new Dictionary();
this.validate = new Dictionary();
this.name = name;
if (eval(this.name) != undefined){
//alert(eval(this.name).toString());
this.rs = eval(this.name);
}
//this.action = act;
this.cnt = -1;
//this.lcnt = -1;
this.color = color;
//this.ecnt = -1;
this.acnt = -1;
this.table = "";
var undefined;
//this.aid = "";
this.tableBind(name);
}

//#=method bind(name, type, validation)
//#=purpose this function binds the data elements to the form for
//#+        data submission and data validation.
//#+        name - the name of the data
//#+        type - the data type (char or num) this identifies whether
//#+               the sql statement needs quotes around the data.
//#+               0 - num     1 - text (need quotes)
//#+
//#+		validation - validation based on the validation number entered.
//#+
//#+		0 = no validation
//#+		1 = simple field validation
//#+		2 = check for email address
//#+		3 = check for proper date
//#+    4 = make sure checkbox is checked
//#+
//#+
//#+
//#+
//#+
//#+

mpform.prototype.bind = function(a, b, c)
{
	this.cnt++;
	this.vars.add(this.cnt, a);
	this.type.add(this.cnt, b);
	this.num.add(a,this.cnt);
	this.validate.add(this.cnt, c);

}

mpform.prototype.setKey = function(a)
{
this.tableKey = a;
}

mpform.prototype.getKey = function()
{
	return this.tableKey;
}



mpform.prototype.tableBind = function(a)
{
	this.table = a;
}

mpform.prototype.getTable = function()
{
	return this.table;
}


//#=method changeColor(item)
//#=purpose this is used to change the color of the data element.
//#+        it will handle ME and NS browsers, but NS colors will not change.
//#+        The color change is a result of errors on data validation.

mpform.prototype.changeColor = function(item)
{

		if(navigator.appName.indexOf("Microsoft") != -1)
		{
			document.forms[this.name].insertAdjacentHTML("AfterEnd", strTxt);
		}

		if (navigator.appName.indexOf("Netscape") != -1)
		{
			document.write(strTxt);
		}
}

//#=method getRecordNumber()
//#=purpose this will return the current record number
//#+
//#+

mpform.prototype.getRecordNumber = function()
{
return this.rs.getCursor();

}

//#=method gotoRecord(int j)
//#=purpose this will move a record set to a particular record
//#+
//#+        int j = the number of the record to go to.

mpform.prototype.gotoRecord = function(j)
{
this.rs.getRecord(j);
this.fillForm();
}

mpform.prototype.getKeyRecord = function(j)
{
var it;
it = 0;
this.rs.moveFirst();
while (it< this.rs.length())
	{
	if(j != this.rs.getItem(this.tableKey))
		{
		this.rs.moveNext();
		}
	it++;
	}
	if(j == this.rs.getItem(this.tableKey))
		{
		this.fillForm();
		}
	else
		{
		alert("No Match"); //\nj=" + j + "\nkey = " + this.rs.getItem(this.tableKey));
		}


}







//#=method fillSelect(formElement, rs, field)
//#=purpose fill a select box from a recordset
//#+
//#+
mpform.prototype.fillSelect = function(formElement, field)
{
	rst = this.rs;
	var lnth;
	lnth = 0;
	rst.moveFirst();
	//alert("rst has " + rst.getItem(field));
	while ( lnth < rst.length())    ///!rst.EOR())
	{       
                        s =  rst.getItem(field) + "                                ";
                        formElement.options[lnth] = new Option(s.substring(0,20), rst.getItem(this.getKey()));
                        //alert("text = " + formElement.options[lnth].text + "\nValue = " + formElement.options[lnth].value);
	rst.moveNext();
	lnth++;
	}
//alert("done");
//formElement.options[0].defaultSelected = true;
return 0;
}



//#=method fillForm()
//#=purpose this will fill the form with the current record.
//#+
//#+

mpform.prototype.fillForm = function()
{

	for(i=0; i < this.vars.length(); i++)
	{
		this.setValue(document.forms[this.name].elements[this.vars.get(i)]);
		this.fill = 1;
	}
}


//#=method firstRecord()
//#=purpose this positions the RecordSet object rs to the first record.  All bound items
//#+        will reflect the change.
//#+        rs - a RecordSet object.

mpform.prototype.firstRecord = function()
{
//alert('in here');
this.rs.moveFirst();
for(i=0; i < this.vars.length(); i++)
{
//alert(document.forms[this.name].elements[this.vars.get(i)].name);
this.setValue(document.forms[this.name].elements[this.vars.get(i)]);
}
//alert(document.forms[this.name].elements[this.vars.get(i)].name);

}

//#=method lastRecord()
//#=purpose this positions the RecordSet object rs to the last record.  All bound items
//#+        will reflect the change.
//#+        rs - a RecordSet object.

mpform.prototype.lastRecord = function()
{
this.rs.moveLast();
for(i=0; i < this.vars.length(); i++)
{
this.setValue(document.forms[this.name].elements[this.vars.get(i)]);
}
}


//#=method nextRecord()
//#=purpose this positions the RecordSet object rs to the next record.  All bound items
//#+        will reflect the change.
//#+        rs - a RecordSet object.

mpform.prototype.nextRecord = function()
{
this.rs.moveNext();
for(i=0; i < this.vars.length(); i++)
{
this.setValue(document.forms[this.name].elements[this.vars.get(i)]);
}
}

//#=method getItem(key)
//#=purpose This will return the item from the current recordset.
//#+
//#+

mpform.prototype.getItem = function(key)
{
return this.rs.getItem(key);
}

//#=method prevRecord()
//#=purpose this positions the RecordSet object rs to the previous record.  All bound items
//#+        will reflect the change.
//#+        rs - a RecordSet object.

mpform.prototype.prevRecord = function()
{
this.rs.movePrev();
for(i=0; i < this.vars.length(); i++)
{
this.setValue(document.forms[this.name].elements[this.vars.get(i)]);
}
}



//#=method checkFields()
//#=purpose this method steps through all bound fields and checks for
//#+        proper data validations.

mpform.prototype.checkFields = function()
{
theErrorColor = this.color;
 if (!theErrorColor) {
	theErrorColor = "yellow";}
	//alert(this.validate.length());
	for(i=0; i < this.validate.length(); i++)
	{	//alert(this.validate.get(i));
		if(this.validate.get(i)==1)
		{
		//alert("checking for simple validation");
		if(document.forms[this.name].elements[this.vars.get(i)].value == "")
			{
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
			alert("Please provide data in all required fields."); // + this.vars.get(i));
			document.forms[this.name].elements[this.vars.get(i)].focus();
			return false;
			}
			else
			{
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = "white";}
			}
		}
		
		if(this.validate.get(i)==4)
		{
		//alert("checking for checkbox selection");
		if(document.forms[this.name].elements[this.vars.get(i)].checked != true)
			{
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
			alert("Please provide data in all required fields."); // + this.vars.get(i));
			document.forms[this.name].elements[this.vars.get(i)].focus();
			return false;
			}
			else
			{
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = "white";}
			}
		}



		if(this.validate.get(i)==2)
		{
		//alert("checking for email validation");
			var emailStr = document.forms[this.name].elements[this.vars.get(i)].value;
			// checks if the e-mail address is valid
			var emailPat = /^(\".*\"|[A-Za-z]\w*)@(\[\d{1,3}(\.\d{1,3}){3}]|[A-Za-z]\w*(\.[A-Za-z]\w*)+)$/;
			var matchArray = emailStr.match(emailPat);
			if (matchArray == null)
			{
				if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
				alert("Your email address seems incorrect.  Please try again (check the '@' and '.'s in the email address)");
				document.forms[this.name].elements[this.vars.get(i)].focus();
				return false;
			}
			else
			{
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = "white";}
			}
		}


		// Checks for the following valid date formats:
		// MM/DD/YY   MM/DD/YYYY   MM-DD-YY   MM-DD-YYYY
		// Also separates date into month, day, and year variables
		if(this.validate.get(i)==3)
		{
		//alert("checking for date validation");
			var dateStr = document.forms[this.name].elements[this.vars.get(i)].value;
			var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;

			// To require a 4 digit year entry, use this line instead:
			// var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;
			var matchArray = dateStr.match(datePat); // is the format ok?
			if (matchArray == null)
			{
				if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
				alert("Date is not in a valid format.\n Use mm/dd/yy or mm-dd-yy");
				document.forms[this.name].elements[this.vars.get(i)].focus();
				return false;
			}
			month = matchArray[1]; // parse date into variables
			day = matchArray[3];
			year = matchArray[4];
			if (month < 1 || month > 12)
			{ // check month range
				if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
				alert("Month must be between 1 and 12.");
				document.forms[this.name].elements[this.vars.get(i)].focus();
				return false;
			}
			if (day < 1 || day > 31)
			{
				if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
				alert("Day must be between 1 and 31.");
				document.forms[this.name].elements[this.vars.get(i)].focus();
				return false;
			}
			if ((month==4 || month==6 || month==9 || month==11) && day==31)
			{
				if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = theErrorColor;}
				alert("Month "+month+" doesn't have 31 days!");
				document.forms[this.name].elements[this.vars.get(i)].focus();
				return false;
			}
			if (month == 2)
			{ // check for february 29th
				var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
				if (day>29 || (day==29 && !isleap))
				{
					alert("February " + year + " doesn't have " + day + " days!");
					document.forms[this.name].elements[this.vars.get(i)].focus();
					return false;
				}
   			}
			if(navigator.appName.indexOf("Microsoft") != -1){document.forms[this.name].elements[this.vars.get(i)].style.backgroundColor = "white";}
		}
	}
	return true;  // fields are valid
}



///###this function returns the value of an input element.

mpform.prototype.getSingleValue = function(formElement)
{
var undefined;
	//alert("Element: " + formElement.name);
	if ((formElement.type == "text")||(formElement.type == "hidden")||(formElement.type == "password")||(formElement.type == "textarea"))
		{
			return formElement.value;

		}

	if (formElement.type == "select-one")
		{
		//theValue = this.rs.getItem(formElement.name)
		for(k=0;k<formElement.options.length;k++)
			{
			if(formElement.options[k].selected == true)
				{
				return formElement.options[k].value;

				}
			}
		}


	if(formElement.length > 0)
		{
			if(formElement.type == undefined )
			{
				for(m = 0;m < formElement.length;m++)
				{
				if (formElement[m].type == "radio")
					{
					//alert("name: " + formElement[m].name + "\nvalue: " + formElement[m].value);

				//theValue = this.rs.getItem(formElement[m].name)
					if(formElement[m].checked == true)
						{
						return formElement[m].value;
						}
					}
				}
			}
			else
			{
				if(formElement.checked == true)
				{
					return formElement.value;

				}
			}
		}

	if (formElement.type == "checkbox")
		{
		if(formElement.checked == true)
				{ return true;}
		else	{ return false; }
		}

}


mpform.prototype.setSingleValue = function(formElement, theValue)
{
var undefined;
var theValue;
if ((formElement.type == "text")||(formElement.type == "hidden")||(formElement.type == "password")||(formElement.type == 'textarea'))
	{
		formElement.value = theValue.replace(/'([^']*)'/g,"\"$1\"");
	}

	if (formElement.type == "select-one")
		{
		//theValue = this.rs.getItem(formElement.name)
		for(k=0;k<formElement.options.length;k++)
			{
			if(formElement.options[k].value.toString() == theValue)
				{formElement.selectedIndex = k;
				formElement.options[k].selected = true;
				}
			else
				{
				formElement.options[k].selected = false;
				}
			}
		}


	if(formElement.length > 0)
	{
		//alert(formElement.type);
		if(formElement.type == undefined )
		{
		//var True; var False; True = 1; False = 0;
			//if (formElement[0].type != undefined)
			//{
			for(m = 0;m < formElement.length;m++)
			{
			if (formElement[m].type == "radio")
				{
				//theValue = this.rs.getItem(formElement[m].name)
				if(formElement[m].value == theValue)
					{
					formElement[m].checked = true;
					}
				else
					{
					formElement[m].checked = false;
					}
				}
			else
				{
				if(formElement.value == theValue)
					{
					formElement.checked = true;
					}
				else
					{
					formElement.checked = false;
					}
				}
			}
	
		}

		if (formElement.type == "checkbox")
		{
		//theValue = this.rs.getItem(formElement.name)
		//True = 1; False = 0;
			if((theValue == 'true')||(theValue == 'True'))
			{
				formElement.checked = true;
			}
			if((theValue == 'false') || (theValue == 'False'))
			{
				formElement.checked = false;
			}
		}
	}
}



mpform.prototype.setValue = function(formElement)
{
var undefined;
var theValue;
	//alert(formElement.type);
	if ((formElement.type == "text")||(formElement.type == "hidden")||(formElement.type == "password")||(formElement.type=="textarea"))
		{
			theValue = this.rs.getItem(formElement.name)
			//alert("theValue=" + formElement.value);
                        formElement.value = theValue.replace("/'{1}([^']*)'{1}/g", "\"$1\"");
		}


	if (formElement.type == "select-one")
		{
		theValue = this.rs.getItem(formElement.name)
		for(k=0;k<formElement.length;k++)
			{//alert(formElement.options[k].value + ", " + theValue);
			if(formElement.options[k].value == theValue)
				{//alert("setting to true");
				formElement.selectedIndex = k;
				formElement.options[k].selected = true;
				}
			else
				{//alert("setting to false");
				
				formElement.options[k].selected = false;
				}
			//alert(formElement.options[k].selected);
			}
		}


	if(formElement.length > 0)
	{
	//alert(formElement.type);
		if(formElement.type == undefined )
		{ //alert(formElement.name);
		//var True; var False; True = 1; False = 0;
			for(m = 0;m < formElement.length;m++)
			{
			if (formElement[m].type == "radio")
				{
				theValue = this.rs.getItem(formElement[m].name)
				if(formElement[m].value == theValue)
					{
					formElement[m].checked = true;
					}
				else
					{
					formElement[m].checked = false;
					}
				}
			else
				{
				theValue = this.rs.getItem(formElement.name)

				if(formElement.value == theValue)
					{alert(formElement.type + "\n" + formElement.value);
					formElement.checked = true;
					}
				else
					{
					formElement.checked = false;
					}
				}
			}
		}

		if (formElement.type == "checkbox")
		{
		theValue = this.rs.getItem(formElement.name)
		True = 1; False = 0;
			if((theValue == 'true')||(theValue == 'True'))
			{
				formElement.checked = true;
			}
			if((theValue == 'false') || (theValue == 'False'))
			{
				formElement.checked = false;
			}
		}
	}
}


//#=method fillSelect(formElement, field)
//#=purpose fill a select box from a recordset
//#+
//#+
mpform.prototype.fillSelect = function(formElement, field)
{   //alert(formElement);
	rst = this.rs;
	var lnth;
	lnth = -1;
	rst.moveFirst();
	//alert("rst has " + rst.getItem(field));
	while ( lnth < rst.length()-1)    ///!rst.EOR())
	{       lnth++;
                        s =  rst.getItem(field) + "                                ";
                        formElement.options[lnth] = new Option(s.substring(0,20), rst.getItem(this.getKey()));
                        //alert("text = " + formElement.options[lnth].text + "\nValue = " + formElement.options[lnth].value);
	rst.moveNext();
	}

}





//#/object

////--------------------------------------------------------------------------------------------
//#=object mpmultiform

//#=method mpmultiform(act)
//#=purpose this instantiates the mpmultiform object
//#+
//#+
//#+
function mpmultiform()
{
	this.vars = new Diction();
	this.num = new Diction();
	this.cnt = -1;
}

//#=method bind(a)
//#=purpose this binds the mpform objects
//#+        a - the name of the mpform Object.
//#+
//#+

mpmultiform.prototype.bind = function(a)
{
	this.cnt++;
	this.vars.add(this.cnt, a);
	this.num.add(a,this.cnt);
}

//#=method validate()
//#=purpose This method sequentially validates all the mpform Objects that are bound
//#+        to the mpmultiform Object.
//#+
//#+

//mpmultiform.prototype.validate = function()
//{
//for(a=0;a<this.vars.length();a++)
//{
//if(!(this.vars.get(a).checkFields()))
//	{
//	return false;
//	}
//}
//return true;
//}

//#/object
