// include utilities

// fuzzForm JS stuff
fuzzForm = new Object();

fuzzForm.currentForms = new Object();
fuzzForm.isUploading = false;
fuzzForm.uploadQueue = new Object();
fuzzForm.uploadQueue.uploads = new Array();
fuzzForm.actionQueue = new Array();

fuzzForm.addToMethodQueue = function addToActionQueue(method, $argObj){
	$argObj.method = method;
	fuzzForm.actionQueue.push($argObj);
}

fuzzForm.handleWaitingForms = function handleWaitingForms(){
	for(var i = 0; i < fuzzForm.actionQueue.length; i++){
		if(fuzzForm.actionQueue[i].method == "validateForm"){
			fuzzForm.validateForm(fuzzForm.actionQueue[i].formName,fuzzForm.actionQueue[i].jsCallbackFn,fuzzForm.actionQueue[i].callbackData);
		}
		if(fuzzForm.actionQueue[i].method == "submitAsyncForm"){
			fuzzForm.submitAsyncForm(fuzzForm.actionQueue[i].formName,fuzzForm.actionQueue[i].control,fuzzForm.actionQueue[i].action,fuzzForm.actionQueue[i].submitData,fuzzForm.actionQueue[i].onConfirm, fuzzForm.actionQueue[i].confirmMessage, fuzzForm.actionQueue[i].optionsArr);
		}
	}
	fuzzForm.actionQueue = new Array();
}

fuzzForm.initAsyncForm = function initAsyncForm(fuzzFormName){
	var jsonDiv = document.getElementById("fuzzForm_"+fuzzFormName+"_json_form_div_id");

	var fuzzFormObj = JSON.parse(jsonDiv.innerHTML);
	//var fileInputArr = new Array();

	for(elementName in fuzzFormObj.elements){
		e = fuzzFormObj.elements[elementName];
		// check the type and init js objects
		if(e.type == "date"){
			fuzzForm.initCalendar(fuzzFormObj.formName,e.name);
		}
		else if(e.type == "file"){
			//fileInputArr.push(e);
			//YAHOO.util.Event.OnDomReady(alert,"here");
			//fuzzForm.initFileIFrame(fuzzFormName,e.name);
			tObj = new Object();
			tObj.formName = fuzzFormObj.formName;
			tObj.elementName = e.name;
			YAHOO.util.Event.onContentReady("fuzzForm_"+fuzzFormName+"_"+e.name+"_upload_iframe_container_div_id",fuzzForm_static_initFileIFrame ,tObj);
		}
	}
}

function fuzzForm_static_initFileIFrame(obj){
	fuzzForm.initFileIFrame(obj.formName,obj.elementName);
}

fuzzForm.getFormObject = function getFormObject(fuzzFormName){
	var jsonDiv = document.getElementById("fuzzForm_"+fuzzFormName+"_json_form_div_id");

	var fuzzFormObj = JSON.parse(jsonDiv.innerHTML);
	return fuzzFormObj;
}
fuzzForm.startValidationTracking = function startValidationTracking(formName){
	/*if(fuzzForm.currentForms[formName] && fuzzForm.currentForms[formName].isValidating){
		// make sure the time isn't greater than .... milliseconds
		alert("figure this out, getTime()");
		fuzzForm.currentForms[formName] = "";
		return false;
	}*/
	d = new Date();
	fuzzForm.currentForms[formName] = new Object();
	fuzzForm.currentForms[formName].isValidating = true;
	fuzzForm.currentForms[formName].startTime = d.getTime();
	return true;
}

// keeps track of validating forms
fuzzForm.endValidationTracking = function endValidationTracking(formName){
	if(! fuzzForm.currentForms[formName]){
		alert("Unable to find tracking.");
	}
	
	d = new Date();
	alert(d.getTime() - fuzzForm.currentForms[formName].startTime);
	fuzzForm.currentForms[formName].isValidating = false;
	//fuzzForm.currentForms[formName].startTime = "";
	
	return true;
}

//keeps track of validating forms
fuzzForm.getElementValue = function getElementValue(formName, elementName, type, childElementId){
	
	// get the element
	var isChild = false;
	var eName = "fuzzForm_"+formName+"_"+elementName+"_element_id";
	var value = null;
	if(childElementId){
		eName = "fuzzForm_"+formName+"_"+elementName+"_"+childElementId+"_element_id";
		isChild = true;
	}

	element = document.getElementById(eName);
	if(! type) type = element.type;

	if(! element) return null;

	if(type == 'checkbox' || type == 'checkboxGroup'){

		if(isChild){
			value = element.checked;
		}
		else value = fuzzForm.getSelectedValues(formName, elementName);
	}
	else if(type == 'booleanRadio'){
		if(isChild){
			alert("TODO");
		}
		else{
			name = "fuzzForm_"+formName+"_"+elementName+"_element";
			var radios = document.getElementsByName(name);
			for(var y=0; y<radios.length;y++){
				if(radios[y].checked) value = (radios[y].value == 1);
			}
		}
	}
	else if(type == 'radio'){
		if(isChild){
			value = element.checked;
		}
		else{
			
			name = "fuzzForm_"+formName+"_"+elementName+"_element";
			var radios = document.getElementsByName(name);
			for(var y=0; y<radios.length;y++){
				if(radios[y].checked) value = radios[y].value;
			}
		}
	}
	else if(type == "select"){
			value = getSelectValue(element);
	}
	else{
		value = element.value;
	}

	return value;

	//if(element) return element.value;
	//else alert("Unable to find element (1): "+eName);
}

fuzzForm.getElement = function getElement(formName, elementName, childElementId){
	// get the element
	if(childElementId) eName = "fuzzForm_"+formName+"_"+elementName+"_"+childElementId+"_element_id";
	else eName = "fuzzForm_"+formName+"_"+elementName+"_element_id";
	element = document.getElementById(eName);
	if(element) return element;
	else return null;
}

fuzzForm.setElementChildValues = function setElementChildren(formName, elementName, value, type){
	eName = "fuzzForm_"+formName+"_"+elementName+"_element";

	// get the id of from the id attribute
	prefix = "fuzzForm_"+formName+"_"+elementName+"_";
	postfix = "_element";


	elements = document.getElementsByName(eName);


	retObj = new Object();

	//alert(eName)
	var j;
	for(j = 0; j < elements.length; j++){
		// get the id from the name
		tId = elements[j].id.toString();
		tName = elements[j].name.toString();
		tValue = elements[j].value;
		
		idStart = prefix.length;

		if(type == "checkboxGroup"){
			
			elements[j].checked = value;
		}
		else{
			elements[j].value = value;
		}

	}

}

fuzzForm.getElementChildValues = function getElementChildValues(formName, elementName, type){
	
	eName = "fuzzForm_"+formName+"_"+elementName+"_element";

	// get the id of from the id attribute
	prefix = "fuzzForm_"+formName+"_"+elementName+"_";
	postfix = "_element";


	elements = document.getElementsByName(eName);


	retObj = new Object();

	//alert(eName)
	var j;
	for(j = 0; j < elements.length; j++){

		// get the id from the name
		tId = elements[j].id.toString();
		tName = elements[j].name.toString();
		tValue = elements[j].value;

		idStart = prefix.length;
		// -4 for _id
		idEnd = prefix.length + ((tId.length) - tName.length) - 4;
		id = tId.substring(idStart,idEnd);

		if(type == "checkboxGroup"){
			if(elements[j].checked) retObj[elements[j].value] = true;
			else retObj[elements[j].value] = false;
		}
		else if(type == "select"){
			retObj[id] = getSelectValue(elements[j]);
		}
		else{
			retObj[id] = tValue;
		}

	}

	return retObj;
	
}

fuzzForm.getFormElement = function getFormElement(formName){
	// get the element
	eName = "fuzzForm_"+formName+"_id";
	element = document.getElementById(eName);
	if(element) return element;
	else alert("Unable to find form (1): "+formName);
}

fuzzForm.submitForm = function submitForm(formName){
	fuzzForm.getFormElement(formName).submit();
}

// for checkboxes
fuzzForm.getSelectedValues = function getSelectedValues(formName, elementName){
	// get the element
	eName = "fuzzForm_"+formName+"_"+elementName+"_element";
	elements = document.getElementsByName(eName);
	retArr = new Array();
	for(i = 0; i < elements.length; i++){
		if(elements[i].checked){
			retArr.push(elements[i].value);
		}
	}
	
	return retArr;
}

// if jsCallbackFn is defined, it will not submit, it will call that function with the callback data
fuzzForm.validateForm = function validateForm(formName, jsCallbackFn, callbackData){
	// first, make sure we don't need to wait
	if(fuzzForm.isUploading){
		tObj = new Object();
		tObj.formName = formName;
		tObj.jsCallbackFn = jsCallbackFn;
		tObj.callbackData = callbackData;
		fuzzForm.addToMethodQueue("validateForm",tObj);
		fuzzForm.displayWaitDiv(formName, "Finishing Uploads... Please Wait.");
		return;
	}

	form = fuzzForm.updateFormJSON(formName);
	//fuzzAsync.sendAsyncJSRequest(JSON.stringify(form),"class/fuzzAsync/asyncTest.php",testCallback);
	argArr = new Array();
	//dump(form);
	argArr[0] = form;
	
	cbkArr = new Array();
	if(jsCallbackFn){
		cbkArr[0] = jsCallbackFn;
		if(callbackData) cbkArr[1] = callbackData;
			
	}
	// track form and time it takes
	//fuzzForm.startValidationUI(formName);
	
	fuzzForm.displayWaitDiv(formName, "Validating... Please Wait.");
	
	fuzzAsync.callAction("fuzzForm", "validate", argArr, fuzzForm.validateCallback,cbkArr);
}

fuzzForm.validateChildElementsById = function validateChildElementsByArr(form, childElementNameValueArr, jsCallbackFn, callbackData, callbackOptions){
	//getElementChildValues(formName, elementName, type)
	if(! form.formName){
		form = fuzzForm.getFormJSON(form);
	}

	// go through and get each child element and it's value
	// remove any unused element's or values
	var tChildElements = new Object();
	var tElements = new Object();
	var cElementName = "";
	
	for(cElementName in childElementNameValueArr){

		if(! form.elements[cElementName]){
			throw("validateChildElementsById error: Unable to find element "+eName);
		}
		else if(! form.elements[cElementName].hasChildElements){
			throw("validateChildElementsById error: "+cElementName+" is not a child element.");
		}

		tElements[cElementName] = form.elements[cElementName];

		tVal = fuzzForm.getElementValue(form.formName,cElementName,tElements[cElementName].type,childElementNameValueArr[cElementName]);

		if(tElements[cElementName].childElements && tElements[cElementName].childElements[childElementNameValueArr[cElementName]]){
		
			tChildElements[cElementName] = form.elements[cElementName].childElements[childElementNameValueArr[cElementName]];
			tChildElements[cElementName].value = tVal;
		}
		else{
			tChildElements[cElementName] = new Object();
			tChildElements[cElementName].value = newValue
		}

		tElements[cElementName].childElements = new Object();
		tElements[cElementName].childElements[childElementNameValueArr[cElementName]] = tChildElements[cElementName];
	}

	form.elements = tElements;

	var argArr = new Array();
	argArr[0] = form;

	var cbkArr = new Array();

	if(jsCallbackFn){
		cbkArr[0] = jsCallbackFn;
		if(callbackData) cbkArr[1] = callbackData;
		if(callbackOptions) cbkArr[2] = callbackOptions;
	}

	fuzzAsync.callAction("fuzzForm", "validate", argArr, fuzzForm.validateCallback,cbkArr);
}

//if jsCallbackFn is defined, it will not submit, it will call that function with the callback data
fuzzForm.validateFormByArr = function validateFormByArr(formName, elementNameArr, jsCallbackFn, callbackData,callbackOptions){
	form = fuzzForm.updateFormJSON(formName);
	//fuzzAsync.sendAsyncJSRequest(JSON.stringify(form),"class/fuzzAsync/asyncTest.php",testCallback);
	
	for (var elementName in form.elements){
		form.elements[elementName].isRequired = false;
	}
	
	for(i = 0; i < elementNameArr.length; i++){
		if(form.elements[elementNameArr[i]]) form.elements[elementNameArr[i]].isRequired = true;
	}
	
	argArr = new Array();
	argArr[0] = form;
	
	cbkArr = new Array();
	
	if(jsCallbackFn){
		cbkArr[0] = jsCallbackFn;
		if(callbackData) cbkArr[1] = callbackData;
		if(callbackOptions) cbkArr[2] = callbackOptions;
	}
	
	// track form and time it takes
	//fuzzForm.startValidationUI(formName);
	waitContainerId = null;
	if(callbackOptions && callbackOptions.waitDivContainerId) waitContainerId = callbackOptions.waitDivContainerId;
	fuzzForm.displayWaitDiv(formName, "Validating... Please Wait.",waitContainerId);
	
	fuzzAsync.callAction("fuzzForm", "validate", argArr, fuzzForm.validateCallback,cbkArr);
}
	
fuzzForm.validateCallback = function validateCallback(response){

	if(response.isError){
		alert("in response.isError");
		dump(response);
		//fuzzForm.displayErrorDiv(response.callbackData.formName,response.errorDescription,response.errorDetails);
		return;
	}
	
	//
	
	// update the fuzz form based on the form that was returned

	var fuzzFormObj = response.returnObject;
	var isValid = false;
	var argArr = new Array();

	var formDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_div_id");
	//var errorDiv = document.getElementById("fuzzForm_"+fuzzForm.formName+"_error_div_id");
	var waitDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_wait_div_id");
	var textContainerDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_wait_text_container_div_id");

	// update the form elements to show error sand see if this is valid
	isValid = fuzzForm.updateForm(fuzzFormObj);

	// handle function callback



	if(response.callbackData){
		if(response.callbackData[1]) argArr.push(response.callbackData[1]);


		if(response.callbackData[2]){
			if(response.callbackData[2].returnResponse) argArr.push(response);
			if(response.callbackData[2].returnIsValid) argArr.push(isValid);
		}
	}
	if (isValid){
		fuzzForm.displayWaitDiv(fuzzFormObj.formName,"Sending Data...");

		// TODO MAKE SURE THIS IS THE BEST PLACE FOR THIS
		formElement = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_id");
		if(fuzzFormObj.target && fuzzFormObj.target != ""){
			formElement.setAttribute("target","_blank");
		}

		// first, checkfor callback data
		if(response.callbackData[0] && window[response.callbackData[0]]){
			hideElement(waitDiv);

			cbFn = window[response.callbackData[0]];
			cbFn.apply(this,argArr);
			//eval(response.callbackData[0]+"("+argArr.join(",")+")");
			return;
		}

		// Otherwise submit
		if(fuzzFormObj.forwardType == 'post'){
			formElement.submit();
		}
		else if(fuzzFormObj.forwardType == 'async'){
			
			// Get submit data and put it back into an array
			submitData = new Object();

			for (var i in fuzzFormObj.submitData){
				submitData[i] = fuzzFormObj.submitData[i];
			}

			submitData['fuzzForm'] = fuzzForm.minimizeFuzzFormObj(fuzzFormObj);
			
			hideElement(waitDiv);
			
			fuzzController.displayContainer(fuzzFormObj.forwardControl,fuzzFormObj.forwardAction,submitData,null,null,fuzzFormObj.jsCallbackFn);
		}
		else alert('Error submitting form.');

	}
	else{
		hideElement(waitDiv);
		//hideElement(errorDiv);
		showElement(formDiv);
		// first, checkfor callback data
		if(response.callbackData[0] && window[response.callbackData[0]] && response.callbackData[2] && response.callbackData[2].forceCallback){
			//response.callbackData[0](response);
			cbFn = window[response.callbackData[0]];
			cbFn.apply(this,argArr);
			//eval(response.callbackData[0]+"("+ argArr.join(",")+")");
			return;
		}
		
	}
}



fuzzForm.minimizeFuzzFormObj = function minimizeFuzzFormObj(fuzzFormObj){
	ret = new Object();
	ret['elements'] = new Object();
	
	for (var i in fuzzFormObj.elements){
		ret['elements'][i] = new Object();
		ret['elements'][i].value = fuzzFormObj.elements[i].value;
		ret['elements'][i].name = fuzzFormObj.elements[i].name;
		ret['elements'][i].type = fuzzFormObj.elements[i].type;

	}
	
	return ret;
}

// submit the form to any control and action you want without validation
fuzzForm.submitAsyncForm = function submitAsyncForm(formName,control,action,submitData,onConfirm, confirmMessage, optionsArr){
	if(onConfirm){
		if(confirmMessage) m = confirmMessage;
		else m = "Are you sure?";
		if(! confirm(m)) return;
	}

	if(fuzzForm.isUploading){
		tObj = new Object();
		tObj.formName = formName;
		tObj.control = control;
		tObj.action = action;
		tObj.submitData = submitData;
		tObj.onConfirm = onConfirm;
		tObj.confirmMessage = confirmMessage;
		tObj.optionsArr = optionsArr;
		fuzzForm.addToMethodQueue("submitAsyncForm",tObj);
		fuzzForm.displayWaitDiv(formName, "Finishing Uploads... Please Wait.");
		return;
	}

	// see if we need to close the modal
	if(optionsArr && optionsArr.closeModal){
		fuzzController.closeModal();
	}

	form = fuzzForm.updateFormJSON(formName);

	for(var x in form.elements){
		form.elements[x].isRequired = false;
	}
	
	argArr = new Array();
	argArr[0] = form;


	callbackData = new Object();
	callbackData.control = control;
	callbackData.action = action;
	if(optionsArr) callbackData.optionsArr = optionsArr;
	else callbackData.optionsArr = "";
	if(submitData){
		for(var i in submitData){
			callbackData[i] = submitData[i];
		}
	}
	
	fuzzForm.displayWaitDiv(formName, "Validating... Please Wait.");
	
	fuzzAsync.callAction("fuzzForm", "validate", argArr, fuzzForm.submitAsyncFormCallback,callbackData);

}

fuzzForm.submitAsyncFormCallback = function submitAsyncFormCallback(response){
	if(response.isError){
			
		dump(response);
		//fuzzForm.displayErrorDiv(response.callbackData.formName,response.errorDescription,response.errorDetails);
		return;
	}
	
	// update the fuzz form based on the form that was returned
	
	var fuzzFormObj = response.returnObject;
	var isValid = false;

	var formDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_div_id");
	//var errorDiv = document.getElementById("fuzzForm_"+fuzzForm.formName+"_error_div_id");
	var waitDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_wait_div_id");
	var textContainerDiv = document.getElementById("fuzzForm_"+fuzzFormObj.formName+"_wait_text_container_div_id");


	// update the form elements to show error and see if this is valid
	isValid = fuzzForm.updateForm(fuzzFormObj);
	
	// end tracking and wait if going to quickly to limit bandwidth
	//fuzzForm.endValidationTracking(fuzzFormObj.formName);
	fuzzForm.displayWaitDiv(fuzzFormObj.formName,"Sending Info...");
	
	if (isValid){
			submitData = response.callbackData;
			for (var i in fuzzFormObj.submitData){
				submitData[i] = fuzzFormObj.submitData[i];
			}
			submitData['fuzzForm'] = fuzzForm.minimizeFuzzFormObj(fuzzFormObj);
			
			hideElement(waitDiv);
			fuzzController.displayContainer(response.callbackData.control,response.callbackData.action,submitData,false,false,"",callbackData.optionsArr);
	}
	else{
		hideElement(waitDiv);
		//hideElement(errorDiv);
		showElement(formDiv);
	}
}

fuzzForm.relateSelects = function releateSelects(formName,elementName,element1, element2, dboName, methodName, defaultOptionValue, defaultEmptyOptionValue){
	// first see if it is the default option
	elementValue = fuzzForm.getElementValue(formName, elementName);
	if(elementValue == ""){
		select = fuzzForm.getElement(formName,element2);
		// clear the select
		select.innerHTML = "";
		appendOption(select,defaultEmptyOptionValue,"");
		return;
	}
	
	//fuzzAsync.sendAsyncJSRequest(JSON.stringify(form),"class/fuzzAsync/asyncTest.php",testCallback);
	argArr = new Array();
	argArr[0] = fuzzForm.getElementValue(formName, elementName);
	//argArr[1] = element2;
	
	
	argArr[1] = dboName;
	argArr[2] = methodName;
	//argArr[4] = defaultOptionValue;
	
	callbackData = new Object();
	callbackData["formName"] = formName;
	callbackData["element1"] = element1;
	callbackData["element2"] = element2;
	callbackData["dboName"] = dboName;
	callbackData["methodName"] = methodName;
	callbackData["defaultOptionValue"] = defaultOptionValue;
	callbackData["defaultEmptyOptionValue"] = defaultEmptyOptionValue;
	
	// track form and time it takes
	//fuzzForm.startValidationUI(formName);
	
	//fuzzForm.displayWaitDiv(formName, "Validating... Please Wait.");
	
	// disable the select
	fuzzForm.getElement(formName, element1).disabled = "disabled";
	fuzzForm.getElement(formName, element2).disabled = "disabled";
	
	fuzzAsync.callAction("fuzzForm", "relateSelects", argArr, fuzzForm.relateSelectsCallback,callbackData);

}

fuzzForm.relateSelectsCallback = function releateSelectsCallback(response){

	callbackData = response.callbackData;

	select1 = fuzzForm.getElement(callbackData.formName,callbackData.element1);
	select = fuzzForm.getElement(callbackData.formName,callbackData.element2);


	// clear the select
	select.innerHTML = "";
	// add the defaultOptionValue
	
	if(response.returnObject && response.returnObject.length > 0){
		if(callbackData.defaultOptionValue != ""){
			appendOption(select,callbackData.defaultOptionValue,"");
		}
	
		for(var i in response.returnObject){
			appendOption(select,response.returnObject[i].name,response.returnObject[i].value);
		}
	}
	else{
		appendOption(select,"N/A","");
		//if(callbackData.defaultEmptyOptionValue) appendOption(select,callbackData.defaultEmptyOptionValue,"");
		//else appendOption(select,"N/A","");
	}


	
	// enable the select

	select.disabled = "";
	select1.disabled = "";
	select1.focus();
	
}

fuzzForm.currentDisplayError = "";

fuzzForm.hideElementError = function hideElementError(formName, element, errorType){
		errorDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+"_element_error_id");
		eObj = document.getElementById("fuzzForm_"+formName+"_"+element.name+"_element_id");
		errorLinkDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+"_element_label_error_id");
		labelDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+"_element_label_id");

		if(! errorType) errorType = label;

		if(errorType == "error") hideElement(errorDiv);
		else{
			if(element.type=="file"){
				selectfileDiv = parent.document.getElementById("fuzzForm_"+formName+"_"+element.name+"_upload_selectfile_container_div_id");
				selectfileDiv.style.backgroundColor = "";
			}
			else eObj.style.backgroundColor = "";

			if(errorLinkDiv && errorLinkDiv.childNode) errorLinkDiv.removeChild(errorLink.childNode);
			hideElement(errorLinkDiv);
			showElement(labelDiv);
		}
}

fuzzForm.displayElementError = function displayElementError(formName, element, error, errorType,childElementId){

		cEPrefix = "";
			isChild = false;

		if(childElementId){
			cEPrefix = "_"+childElementId;
			isChild = true;
		}

		errorDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_error_id");
		eObj = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_id");
		errorLinkDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_label_error_id");
		labelDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_label_id");

		if(! errorType) errorType = label;

		if(errorType == "error"){

			if(errorDiv){
				errorDiv.innerHTML = "<i>"+error+"</i>";
				errorDiv.style.display = "block";
			}
		}
		else{
			tLink = document.createElement('a');
			tLinkText = document.createTextNode(element.displayName+" *");
			tLink.appendChild(tLinkText);
			tLink.setAttribute('href', 'javascript:fuzzForm.hideErrorLink(event);');
			tLink.setAttribute('name', error);
			tLink.onmouseover = function(event){
				fuzzForm.displayErrorLink(event);
			};
			tLink.onmouseout =  function(){fuzzForm.hideErrorLink();};
			tLink.className = 'error-link';

			//tLink.setAttribute('onMouseOver', 'javascript:fuzzForm.displayErrorLink("'+error+'",event);');
			//tLink.setAttribute('onMouseOut', 'javascript:fuzzForm.hideErrorLink();');
			//tLink.setAttribute('class', 'error-link');

			// if this is a file object, we need to make a differant element red
			if(element.type=="file"){
				selectfileDiv = parent.document.getElementById("fuzzForm_"+formName+"_"+element.name+"_upload_selectfile_container_div_id");
				selectfileDiv.style.backgroundColor = "#FFEFEF";
			}
			else eObj.style.backgroundColor = "#FFEFEF";

			errorLinkDiv.innerHTML = "";
			errorLinkDiv.appendChild(tLink);
			showElement(errorLinkDiv);
			hideElement(labelDiv);
		}
}

fuzzForm.updateFormElement = function updateFormElement(fuzzFormObj, element, childElementId){
	var valid = true;
	var cEPrefix = "";
	var error = "";
	var isChild = false;
	var hasError = element.hasValidationError;
	var formName = fuzzFormObj.formName;
	var value = element.value;


	if(childElementId && element.childElements[childElementId]){
		cEPrefix = "_"+childElementId;
		isChild = true;
		//dump(element);
		if(element.childElements[childElementId].hasValidationError) hasError = element.childElements[childElementId].hasValidationError;

		value = element.childElements[childElementId].value;

	}

	var errorDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_error_id");
	var eObj = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_id");
	var errorLinkDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_label_error_id");
	var labelDiv = document.getElementById("fuzzForm_"+formName+"_"+element.name+cEPrefix+"_element_label_id");

	// Figure out which error to show, always show system error first
	if(isChild && element.childElements[childElementId].systemErrorMessage){
		error = element.childElements[childElementId].systemErrorMessage;
	}
	else if (element.systemErrorMessage != "") error = element.systemErrorMessage;
	else error = element.errorMessage;

	// make sure that the validation method will work

	var validationDisplayMethod = fuzzFormObj.validationDisplayMethod;
	if(! errorLinkDiv || ! labelDiv) validationDisplayMethod = "error";

	if(hasError){

		fuzzForm.displayElementError(formName, element, error, validationDisplayMethod, childElementId);

		valid = false;
		// see if we had applied an keypress submit to an error
		if(canChangeKeypress){
			eObj.onkeypress = new Function("event","fuzzForm.submitOnReturn('"+formName+"','"+element.name+"',event);");
		}

	}
	else {

		if(element.type != 'checkboxGroup' && element.type != 'booleanRadio') if(eObj.value != value){
			eObj.value = value;
		}

		if(validationDisplayMethod == "error"){
			if(errorDiv) errorDiv.style.display = "none";
		}
		else{
			showElement(labelDiv);
			hideElement(errorLinkDiv);
			eObj.style.backgroundColor = "#FFF";
		}

		// see if we had applied an keypress submit to an error
		if(canChangeKeypress){
			eObj.onkeypress = "";
		}

	}
	return valid;
}

fuzzForm.updateForm = function updateForm(fuzzFormObj){
	var valid = true;
	
	var elements = fuzzFormObj.elements;
	
	for(var x in elements){
		if(elements[x].hasChildElements){
			for(var y in elements[x].childElements){
				tValid = fuzzForm.updateFormElement(fuzzFormObj,elements[x],y);
			}
		}
		else tValid = fuzzForm.updateFormElement(fuzzFormObj,elements[x]);

		if(! tValid) valid = false;
	}

	return valid;
}

function canChangeKeypress(fuzzFormObj, element){
	if(fuzzFormObj.doSubmitOnReturn && ! element.submitOnReturn && ! fuzzFormObj.returnSubmitAllElements && element.onKeyPress == "" && (element.type != "select" && element.type != "textarea" && element.type != "textarea-spellcheck")){
		return true;
	}
	else return false;
}


fuzzForm.formatElementValue = function formatElementValue(element, value){
	// format by type


	if(element.type == "booleanRadio"){
		if((! value) || (value == 0) || (value == "0") || (value == "false") || (value == false)) return false;
		else return true;	
	}
	else return value;
	
}

// updates the fuzzFormJSON using client inputed values
// returns the newly updated fuzzForm
fuzzForm.updateFormJSON  = function updateFormJSON(fuzzFormName){
	//var jsonDiv = document.getElementById("fuzzForm_"+fuzzFormName+"_json_form_div_id");
	
	//dump(jsonDiv.innerHTML);

	var fuzzFormObj = fuzzForm.getFormJSON(fuzzFormName);

	

	var elements = fuzzFormObj.elements;
	var type = 'hidden';
	var id = "";
	var name = "";
	var value = "";

	for(elementName in elements){

		if(elements[elementName].hasChildElements){
			// get the values
			tValues = fuzzForm.getElementChildValues(fuzzFormName, elementName, elements[elementName].type);

			return;
		}


		value = "";
		element = document.getElementById("fuzzForm_"+fuzzFormName+"_"+elementName+"_element_id");
		
		if(! element){
			alert('Unable to find element: '+elementName);
			return false;
		}



		if(element.type == 'checkbox' || element.type == 'checkboxGroup'){
			value = fuzzForm.getSelectedValues(fuzzFormName, elementName);
		}
		else if(element.type == 'radio'){
			name = "fuzzForm_"+fuzzFormName+"_"+elementName+"_element";
			var radios = document.getElementsByName(name);
			for(var y=0; y<radios.length;y++){
				if(radios[y].checked) value = radios[y].value;
			}
		}
		else{
			value = element.value;
			
		}

		if(value == null){
				alert("null");
			}
			if(value == undefined){
				alert("undef");
			}
		
		//alert(typeof value);
			if(! value && typeof value == "string"){
				value = "";
			}
		
		if(fuzzFormObj.fuzzDataGrids[elementName]){
			// try to get the actual data
			stateData = document.getElementById("fuzzDataGrid_"+fuzzFormObj.fuzzDataGrids[elementName]+"_stateInfo_div_id");
			// set the actual element value so it will be submitted post and async
			if(stateData){
				element.value = stateData.innerHTML;
				value = stateData.innerHTML;
			}
		}
		
		// check for differant variable types
		elements[elementName].value = fuzzForm.formatElementValue(elements[elementName],value);
		
	}

	fuzzFormObj.elements = elements;
	// set it and return it
	//dump(fuzzFormObj);
	fuzzForm.setFormJSON(fuzzFormName, fuzzFormObj);

	//jsonStr = JSON.stringify(fuzzFormObj);
	//dump(jsonStr);
	//jsonDiv.innerHTML = jsonStr;
	//
	return(fuzzFormObj);
}

fuzzForm.setFormJSON = function setFormJSON(fuzzFormName, formObj){
	var jsonDiv = document.getElementById("fuzzForm_"+fuzzFormName+"_json_form_div_id");
	jsonStr = JSON.stringify(formObj);
	//dump(jsonStr);
	jsonDiv.innerHTML = jsonStr;
}

fuzzForm.getFormJSON = function getFormJSON(fuzzFormName){
	var jsonDiv = document.getElementById("fuzzForm_"+fuzzFormName+"_json_form_div_id");
	var fuzzFormObj = JSON.parse(jsonDiv.innerHTML);

	return fuzzFormObj;
}

fuzzForm.displayWaitDiv = function displayWaitDiv(formName, text, waitDivContainerId){
	//var waitDiv = document.getElementById("fuzzForm_"+formName+"_wait_div_id");
	//var errorDiv = document.getElementById("fuzzForm"+formName+"_error_div_id");
	//var height = 100;

	//if(isHiddenElement(waitDiv)){
		fuzzAsync.util.displayProgressDiv("fuzzForm_"+formName,text,null,null,null,waitDivContainerId);
		// display wait div
		//showElement(waitDiv);
		// hide form
		//hideElement(formContainerDiv);
		//hideElement(errorDiv);
	//}
}

fuzzForm.displayErrorLink = function displayErrorLink(e) {
	error = "Please insert a valid value.";
	
	if (!e) var e = window.event;
	if(e.target && e.target.name) error = e.target.name; 
	else if(e.srcElement && e.srcElement.name) error = e.srcElement.name;
	
	fuzzForm.displayInfoLink(error, e, true);
}

fuzzForm.hideErrorLink = function hideErrorLink() {
	return fuzzForm.hideInfoLink(true)
}

fuzzForm.displayInfoLink = function displayInfoLink(message, e, isError) {
	// hide any open ones
	
	if(isError){
		tipLinkDiv = document.getElementById("fuzzForm_errorLink_div_id");
		messageDiv = document.getElementById("fuzzForm_errorLink_message_div_id");
	}
	else{
		tipLinkDiv = document.getElementById("fuzzForm_infoLink_div_id");
		messageDiv = document.getElementById("fuzzForm_infoLink_message_div_id");
	}

	
	showElement(tipLinkDiv);
	
	messageDiv.innerHTML = message;
	
	// get the even target
	// so we can figure out wehre to put the link
	target = getEventTarget(e);

	ePos = YAHOO.util.Dom.getXY(target);
	ePos[1] = ePos[1] - tipLinkDiv.offsetHeight;
	// move to top right first
	//ePos[0] = ePos[0];
	
	// see if we are in the viewport
	viewportXY = getViewportXY();
	scrollXY = getScrollXY();
	
	actualWidth = ePos[0] + tipLinkDiv.offsetWidth;

	if(actualWidth >= viewportXY[0]){
		// put it the other way
		//diff = actualWidth - viewportXY[0] + 10; 
		ePos[0] = ePos[0] - tipLinkDiv.offsetWidth + target.offsetWidth;
		
		
	}
	
	YAHOO.util.Dom.setXY(tipLinkDiv, ePos);
	if(fuzzForm.infoLinkPendingHide){
		clearTimeout(fuzzForm.infoLinkPendingHide);
		fuzzForm.infoLinkPendingHide = false;
	}
}

fuzzForm.hideInfoLink = function hideInfoLink(isError) {
	isErrStr = "";
	if(isError) isErrStr = "true";
	else isErrStr = "false";
	
	if(! fuzzForm.infoLinkPendingHide){
		fuzzForm.infoLinkPendingHide = true;
		fuzzForm.infoLinkPendingHide = setTimeout("fuzzForm.doHideInfoLink("+isErrStr+")",225);
	}
}

fuzzForm.doHideInfoLink = function doHideInfoLink(isError){

	tipLinkDiv = document.getElementById("fuzzForm_errorLink_div_id");
	hideElement(tipLinkDiv);
	
	tipLinkDiv = document.getElementById("fuzzForm_infoLink_div_id");
	hideElement(tipLinkDiv);
}

fuzzForm.currentImagePopup = "";

fuzzForm.displayImagePopup = function displayImagePopup(imgSrc, comment, thumbDivId) {
	
	if(fuzzForm.currentImagePopup == imgSrc){
		fuzzForm.hideImagePopup();
		return;
	}
	
	imageDiv = document.getElementById("fuzzForm_imagePopup_div_id");
	thumbDiv = document.getElementById(thumbDivId);
	messageDiv = document.getElementById("fuzzForm_imagePopup_message_div_id");
	imgDiv = document.getElementById("fuzzForm_imagePopup_img_div_id");
	showElement(imageDiv);
	messageDiv.innerHTML = comment;
	imgDiv.innerHTML = "<img class='fuzzForm-imagePopup-img' src='"+imgSrc+"' />";
	
	ePos = YAHOO.util.Dom.getXY(thumbDiv);
	
	// set horizontal pos
	ePos[0] += thumbDiv.offsetWidth + 5; 
	
	// set vertical
	vPos = ePos[1];
	
	// refresh img div
	vLenTemp = imgDiv.clientHeight;
	vLen = imgDiv.offsetHeight;
	
	
	if(vLenTemp > vLen) vLen = vLenTemp;
	if(vLen < 100) vLen = 274;
	
	viewportXY = getViewportXY();
	scrollXY = getScrollXY();
	
	//scrollXY[1] = where we are on the screen
	//viewportXT[1] = the total space we have
	
	// if the total len with screen pos is greater than viewport, move it up
	
	//alert((vPos - scrollXY[1])  + vLen);
	//alert(viewportXY[1]);
	//alert(vPos);
	//alert((vPos - scrollXY[1])  + vLen);
	
	vY = viewportXY[1] - 35;
	
	if(((vPos - scrollXY[1])  + vLen) > (vY)){
		ePos[1] = (vY + scrollXY[1]) - vLen;
	}

	YAHOO.util.Dom.setXY(imageDiv, ePos);
	if(fuzzForm.imagePopupPendingHide){
		clearTimeout(fuzzForm.imagePopupPendingHide);
		fuzzForm.imagePopupPendingHide = false;
	}
	
	// set current and show
	fuzzForm.currentImagePopup = imgSrc
	
}

fuzzForm.hideImagePopup = function hideImagePopup() {
	if(! fuzzForm.imagePopupPendingHide){
		fuzzForm.imagePopupPendingHide = true;
		fuzzForm.imagePopupPendingHide = setTimeout("fuzzForm.doHideImagePopup()",225);
	}
}

fuzzForm.doHideImagePopup = function doHideImagePopup(){
	fuzzForm.currentImagePopup = "";
	imageDiv = document.getElementById("fuzzForm_imagePopup_div_id");
	imageDiv.style.display = "none";
}

// load and initialize all fuzzForms on a view

// Handle current fuzzform objects
fuzzForm.formatCurrentFormsObj = function formatCurrentFormsObj(formName){
	fuzzForm.formatFuzzFormElement(formName);
}
// If the fuzzForm or element doesn't exist it is initialized
fuzzForm.formatFuzzFormElement = function formatFuzzFormElement(formName, elementName){
	if(fuzzForm.currentForms[formName] && fuzzForm.currentForms[formName].elements && fuzzForm.currentForms[formName].elements[elementName]) return;
	if(! fuzzForm.currentForms[formName]){
		fuzzForm.currentForms[formName] = new Object();
		fuzzForm.currentForms[formName].elements = new Object();
		fuzzForm.currentForms[formName].isWaiting = false;
	}
	if(! fuzzForm.currentForms[formName].elements){
		fuzzForm.currentForms[formName].elements = new Object();
	}
	if(elementName && ! fuzzForm.currentForms[formName].elements[elementName]){
		fuzzForm.currentForms[formName].elements[elementName] = new Object();
	}
	
}

// CALENDARS!
fuzzForm.initCalendar = function initCalendar(formName, elementName){
	// make sure we have this fuzzform in js memory

	fuzzForm.formatFuzzFormElement(formName, elementName);
	// init the calendar
	calendar = new Object();
	calendar.divId = "fuzzForm_"+formName+"_"+elementName+"_calendar_div_id";

	calendar.imageDivId = "fuzzForm_"+formName+"_"+elementName+"_calendar_img_div_id";
	calendar.inputId = "fuzzForm_"+formName+"_"+elementName+"_element_id";
	calendar.id = "fuzzForm_"+formName+"_"+elementName+"_calendar_object";
	calendar.object = new YAHOO.widget.Calendar(calendar.id,calendar.divId);
	calendar.object.cfg.setProperty("iframe",true);

	calendar.object.render();
	calendar.object.hide();
	calendar.object.selectEvent.subscribe(fuzzForm.handleCalendarSelect, calendar, true);

	fuzzForm.currentForms[formName].elements[elementName].calendar = calendar;	

}

fuzzForm.handleCalendarSelect = function handleCalendarSelect(type,args,calInfo){
	var dates = args[0];
	var date = dates[0];
	var year = date[0], month = date[1], day = date[2];
	var dateInput = document.getElementById(calInfo.inputId);
	dateInput.value = month + "/" + day + "/" + year;
	dateInput.focus();
	calInfo.object.hide();
}

fuzzForm.handleCalendarInput = function handleCalendarInput(formName, elementName, e){
	element = fuzzForm.getElement(formName, elementName);
	if(e.type == "click") alert('here');
	if(trim(element.value) == ""){
		fuzzForm.showCalendar(formName, elementName)
	}
	else if(e.type == "keypress"){
		// check for key press other than delete
		if(window.event) keyCode = e.keyCode;
		else if(e.which) keyCode = e.which;
		if(keyCode != 8){
			element.value = "";
			fuzzForm.showCalendar(formName, elementName);
		}
	}
}

fuzzForm.checkCalendarPointer = function checkCalendarPointer(formName, elementName){
	element = fuzzForm.getElement(formName, elementName);
	if(trim(element.value) == ""){
		element.style.cursor = "pointer";
	}
	else element.style.cursor = "text";
}

fuzzForm.checkCalendarInput = function checkCalendarInput(val){
	isValid = true;
	vArr = val.split('/');
	
	if(vArr.length != 3) return false;
	
	if(vArr[0] < 0 || vArr[0] > 12) return false;
	if(vArr[1] < 0 || vArr[1] > 31) return false;
	if(vArr[2] < 1900 || vArr[2] > 2100) return false;
	
	return true;
}

fuzzForm.handleCalendarKeyDown = function handleCalendarKeyDown(formName, elementName,e){
	var keyCode = fuzzForm.getKeyCode(e);

	var element = fuzzForm.getElement(formName,elementName);
	var tVal = element.value;

	if(! fuzzForm.currentForms[formName] || ! fuzzForm.currentForms[formName].elements[elementName]){
		fuzzForm.initCalendar(formName, elementName);
	}

	fuzzForm.currentForms[formName].elements[elementName].calendar.currentValue = tVal;

	return false;
}

fuzzForm.handleCalendarKeyUp = function handleCalendarKeyUp(formName, elementName,e){

	element = fuzzForm.getElement(formName,elementName);
	if(! fuzzForm.currentForms[formName] || ! fuzzForm.currentForms[formName].elements[elementName]){
		fuzzForm.initCalendar(formName, elementName);
		//fuzzForm.currentForms[formName].elements[elementName].calendar.currentValue = element.value;
	}
	if(! fuzzForm.currentForms[formName] || ! fuzzForm.currentForms[formName].elements[elementName] || ! fuzzForm.currentForms[formName].elements[elementName].calendar) return;

	//element.value = fuzzForm.currentForms[formName].elements[elementName].calendar.currentValue;

	var currDateStr = fuzzForm.currentForms[formName].elements[elementName].calendar.currentValue;
	var keyCode = fuzzForm.getKeyCode(e);
//if(keyCode != 16) alert(keyCode);
	if(keyCode == 107 || keyCode == 61 || keyCode == 187){
		var newDate = new Date(currDateStr);
		if(newDate != "Invalid Date"){
			newDate.setDate(newDate.getDate() + 1);
			element.value = fuzzForm.calendarDateToStr(newDate);
		}
		else element.value = currDateStr;
	}
	else if(keyCode == 109 || keyCode == 189){
		var newDate = new Date(currDateStr);
		if(newDate != "Invalid Date"){
			newDate.setDate(newDate.getDate() - 1);
			element.value = fuzzForm.calendarDateToStr(newDate);
		}
		else element.value = currDateStr;
	}
}

fuzzForm.calendarDateToStr = function calendarDateToStr(nDate){
	m = nDate.getMonth();
	m++;
	if(m < 10) m = "0"+m.toString();

	d = nDate.getDate();
	if(d < 10) d = "0"+d.toString();
	
	y = nDate.getFullYear().toString();

	return m+"/"+d+"/"+y;
}


fuzzForm.getCalendarPagedate = function getCalendarPagedate(val){
	vArr = val.split('/');
	return vArr[0]+"/"+vArr[2];
}

fuzzForm.showCalendar = function showCalendar(formName, elementName) {
	
	if(! fuzzForm.currentForms[formName] || ! fuzzForm.currentForms[formName].elements[elementName]){
		fuzzForm.initCalendar(formName, elementName);
	}
	//alert(elementName);
	if(fuzzForm.currentForms[formName].elements[elementName].calendar){
		
		inputVal = fuzzForm.getElementValue(formName,elementName);
		if(fuzzForm.checkCalendarInput(inputVal)){
			fuzzForm.currentForms[formName].elements[elementName].calendar.object.cfg.setProperty("selected",inputVal,false);
			fuzzForm.currentForms[formName].elements[elementName].calendar.object.cfg.setProperty("pagedate",fuzzForm.getCalendarPagedate(inputVal),false); 
			fuzzForm.currentForms[formName].elements[elementName].calendar.object.render(); 
		}
		fuzzForm.currentForms[formName].elements[elementName].calendar.object.show();
		
		xy = YAHOO.util.Dom.getXY(fuzzForm.currentForms[formName].elements[elementName].calendar.imageDivId);
		YAHOO.util.Dom.setXY(fuzzForm.currentForms[formName].elements[elementName].calendar.divId, xy);
		
		dateInput = document.getElementById(fuzzForm.currentForms[formName].elements[elementName].calendar.inputId);
		dateInput.blur();
		
	}
	else alert("Unable to find calendar. Please report this problem to the website administrator.");
}

fuzzForm.isKeypressReturn = function isKeypressReturn(e) {
	
	//var nav4 = window.Event ? true : false;
	//if (nav4) var whichCode = e.which
	whichcode = -1;
	if(window.event){
		if(!e) whichCode = window.event.keyCode;
		else{
			if(e.keyCode) whichCode = e.keyCode;
			else if(e.which) whichCode = e.which;
		}
	}
	else if (e && e.type == "keypress") var whichCode = e.keyCode
	
	if ( whichCode == "13" ) {
		return true;
	}
	return false;

}


fuzzForm.submitOnReturn = function submitOnReturn(formName, elementName, e) {
	if(fuzzForm.isKeypressReturn(e)){
		elementValue = fuzzForm.getElementValue(formName, elementName);
		//alert(elementValue);
		setTimeout("fuzzForm.submitOnReturnCallback('"+formName+"','"+elementName+"','"+elementValue+"');",100)
		//fuzzForm.validateForm(formName);
	}
}

fuzzForm.submitOnReturnCallback = function submitOnReturnCallback(formName, elementName, elementValue, e) {
	elementValue2 = fuzzForm.getElementValue(formName, elementName);
	// make sure the element value hasn't changed
	// during the timeout. If it has, this is probably 
	// an autofill problem
	if(elementValue2 == elementValue){
		fuzzForm.validateForm(formName);
	}
}

fuzzForm.initImageSubmit = function initImageSubmitOver(formName){
	if(! fuzzForm.currentForms[formName]){
		fuzzForm.currentForms[formName] = new Object();
	}
	if(! fuzzForm.currentForms[formName].imgSubmitObj){
		fuzzForm.currentForms[formName].imgSubmitObj = new Object();
		fuzzForm.currentForms[formName].imgSubmitObj.doSwitch = false;
		fuzzForm.currentForms[formName].imgSubmitObj.hasFocus = false;
	}

}

fuzzForm.handleImageSubmitOver = function handleImageSubmitOver(formName) {

	fuzzForm.initImageSubmit(formName);
	
	fuzzForm.currentForms[formName].imgSubmitObj.doSwitch = false;
	fuzzForm.currentForms[formName].imgSubmitObj.isOver = true;
	
	imgId = "fuzzForm_"+formName+"_submit_img_div_id";
	hoverImgId = "fuzzForm_"+formName+"_submit_img_hover_div_id";
	showAndHide(hoverImgId, imgId);

}

fuzzForm.handleImageSubmitFocus = function handleImageSubmitFocus(formName) {

	fuzzForm.initImageSubmit(formName);

	fuzzForm.currentForms[formName].imgSubmitObj.doSwitch = false;
	fuzzForm.currentForms[formName].imgSubmitObj.hasFocus = true;

	imgId = "fuzzForm_"+formName+"_submit_img_div_id";
	hoverImgId = "fuzzForm_"+formName+"_submit_img_hover_div_id";

	showAndHide(hoverImgId, imgId);

	hover = document.getElementById(hoverImgId);
	//hover.focus();
}

fuzzForm.handleImageSubmitTimeout = function handleImageSubmitTimeout(formName) {
	
	//alert(fuzzForm.currentForms[formName].imgSubmitObj.doSwitch);
	imgId = "fuzzForm_"+formName+"_submit_img_div_id";
	hoverImgId = "fuzzForm_"+formName+"_submit_img_hover_div_id";
	
	if(fuzzForm.currentForms[formName].imgSubmitObj){
		var isOver = fuzzForm.currentForms[formName].imgSubmitObj.isOver;
		var hasFocus = fuzzForm.currentForms[formName].imgSubmitObj.hasFocus;

		if(!isOver && !hasFocus){
			fuzzForm.handleImageSubmitOut(formName);
			showAndHide(imgId,hoverImgId);
		}
	}
}

fuzzForm.handleImageSubmitOut = function handleImageSubmitOut(formName) {
	imgId = "fuzzForm_"+formName+"_submit_img_div_id";
	hoverImgId = "fuzzForm_"+formName+"_submit_img_hover_div_id";
	
	if(fuzzForm.currentForms[formName].imgSubmitObj){
		if(fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal) clearTimeout(fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal);
		fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal = setTimeout("fuzzForm.handleImageSubmitTimeout('"+formName+"');",200);
		fuzzForm.currentForms[formName].imgSubmitObj.doSwitch = true;
		fuzzForm.currentForms[formName].imgSubmitObj.isOver = false;
	}
}

fuzzForm.handleImageSubmitBlur = function handleImageSubmitBlur(formName) {
	imgId = "fuzzForm_"+formName+"_submit_img_div_id";
	hoverImgId = "fuzzForm_"+formName+"_submit_img_hover_div_id";
//alert("here");
	if(fuzzForm.currentForms[formName].imgSubmitObj){
		if(fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal) clearTimeout(fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal);

		fuzzForm.currentForms[formName].imgSubmitObj.timeoutVal = setTimeout("fuzzForm.handleImageSubmitTimeout('"+formName+"');",200);
		fuzzForm.currentForms[formName].imgSubmitObj.doSwitch = true;
		fuzzForm.currentForms[formName].imgSubmitObj.hasFocus = false;
	}
}

// Richtext

fuzzForm.richtext = new Object();
fuzzForm.richtext.tracking = new Object();

fuzzForm.richtext.handleKeypress = function handleKeypress(formName,elementName, e) {
	
	var nav4 = window.Event ? true : false;
	if (nav4) var whichCode = e.which
	else if (e.type == "keypress") var whichCode = e.keyCode
	
	
	
	//dump(e);
	if(whichCode>20){
		alert(whichCode);
	}
	
	return false;
	
	//alert(getSelectedText());

}

fuzzForm.richtext.test = function test(e){
	alert(e.target.innerHTML);
	dump(e.target);
}

fuzzForm.richtext.init = function init(formName,elementName){
	inputName = "fuzzForm_" + formName + "_" + elementName + "_element_id";
	editName = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_edit_div_id";
	overlayName = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_overlay_div_id";
	
	editArea = document.getElementById(editName);
	overlay = document.getElementById(overlayName);

	overlay.style.width = editArea.offsetWidth+"px";
	overlay.style.height = editArea.offsetHeight+"px";
	
	ePos = YAHOO.util.Dom.getXY(editArea);
	YAHOO.util.Dom.setXY(overlay,ePos);
	
}

fuzzForm.richtext.handleMouseDown = function handleMouseDown(formName,elementName,e) {
	//t = getSelectedText();
	
	//document.onkeypress = fuzzForm.richtext.test;
	
	fuzzForm.richtext.tracking['formName'] = new Object();
	fuzzForm.richtext.tracking['formName'].startPos = e.target.id;
	fuzzForm.richtext.tracking['formName'].endPos = "";
	
	fuzzForm.richtext.init(formName,elementName);
	
}

fuzzForm.richtext.handleMouseUp = function handleMouseUp(formName,elementName,e) {
	//t = getSelectedText();
	fuzzForm.richtext.tracking['formName'].endPos = e.target.id;
	//dump(fuzzForm.richtext.tracking['formName']);
	
	// get the input
	eName = "fuzzForm_" + formName + "_" + elementName + "_element_id";
	inputElement = document.getElementById(eName);
	inputElement.focus();
}

// Spelling
fuzzForm.spellcheck = new Object();

fuzzForm.spellcheck.checkSpelling = function checkSpelling(formName, elementName){
	
	text = fuzzForm.getElementValue(formName, elementName);
	if(trim(text) == "") return;
	
	fuzzForm.displayWaitDiv(formName, "Checking Spelling...");
	
	// check the spelling
	argArr = new Array();
	argArr[0] = formName;
	argArr[1] = elementName;
	argArr[2] = text;
	fuzzAsync.callAction("fuzzForm", "checkSpelling", argArr, fuzzForm.spellcheck.checkSpellingCallback);	
}

fuzzForm.spellcheck.checkSpellingCallback = function checkSpellingCallback(response){
	if(response.isError){
		alert("in response.isError");
		dump(response);
		//fuzzForm.displayErrorDiv(response.callbackData.formName,response.errorDescription,response.errorDetails);
		return;
	}
	var sData = response.returnObject;
	var formName = sData.formName;
	var elementName = sData.elementName;
	var waitDiv = document.getElementById("fuzzForm_"+formName+"_wait_div_id");
	
	// see if we have a spelling mistake
	if(! sData.hasSpellingError){
		hideElement(waitDiv);
		return;
	}
	
	// display the annotated edit div
	var textDivId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_div_id";
	var textDiv = document.getElementById(textDivId);
	
	var tAID = "fuzzForm_"+formName+"_"+elementName+"_element_id";
	var tA = document.getElementById(tAID);
	
	var textEditDivId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_div_id";
	var textEditDiv = document.getElementById(textEditDivId);
	
	var editAreaId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_edit_div_id";
	var editAreaDiv = document.getElementById(editAreaId);
	
	var hiddenJSON = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_json_div_id";
	var hiddenJSON = document.getElementById(hiddenJSON);
	
	// set the text area to the annotated text
	editAreaDiv.innerHTML = sData.annotatedText;
	
	
	// set the hidden json information
	// hack because of weird js and links problem
	sData.annotatedText = "inEditMode";
	hiddenJSON.innerHTML = JSON.stringify(sData);
	
	// if there are spelling errors, show the edit area
	showElement(textEditDiv);
	hideElement(textDiv);
	hideElement(waitDiv);
}

fuzzForm.spellcheck.resumeEditing = function resumeEditing(formName, elementName){
	// display the annotated edit div
	var textDivId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_div_id";
	var textDiv = document.getElementById(textDivId);
	
	var textEditDivId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_div_id";
	var textEditDiv = document.getElementById(textEditDivId);
	
	var hiddenJSON = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_json_div_id";
	var hiddenJSON = document.getElementById(hiddenJSON);
	// clear the json div
	hiddenJSON.innerHTML = "";
	
	// show the element
	showElement(textDiv);
	hideElement(textEditDiv);
}


fuzzForm.spellcheck.displaySpellingSuggestions = function displaySpellingSuggestions(formName, elementName, linkId){
	//alert(linkId);
	var suggestDivId = "fuzzForm_"+formName+"_spellcheck_suggest_div_id";
	//var suggestDiv = document.getElementById(suggestDivId);
	//fuzzForm_{$this->formName}_spellcheck_suggest_div_id
	
	var suggestDiv = document.getElementById(suggestDivId);
	if(! suggestDiv){ 
		suggestDiv = document.createElement('div');
		suggestDiv.setAttribute('id', suggestDivId);
		suggestDiv.setAttribute('class', "fuzzform-spellcheck-suggest-div");
		suggestDiv.setAttribute('className', "fuzzform-spellcheck-suggest-div");
		
		suggestDiv.setAttribute('onMouseOver', "fuzzForm.handleFloatingElementOver('"+suggestDivId+"')");
		suggestDiv.onmouseover = new Function("fuzzForm.handleFloatingElementOver('"+suggestDivId+"')");
		
		suggestDiv.setAttribute('onMouseOut', "fuzzForm.handleFloatingElementOut('"+suggestDivId+"', event, true)");
		suggestDiv.onmouseout = new Function("fuzzForm.handleFloatingElementOut('"+suggestDivId+"', event, true)");
		
		
		//onMouseOver="fuzzForm.handleFloatingElementOver('{$suggestDivId}'
		document.body.appendChild(suggestDiv);
	}
	
	var linkElementId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_link_"+linkId+"_id";
	var link = document.getElementById(linkElementId);
	
	var hiddenJSONId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_json_div_id";
	var hiddenJSON = document.getElementById(hiddenJSONId);
	
	var sData = JSON.parse(hiddenJSON.innerHTML);

	var i = 0;
	
	for(i = 0; i < sData.words.length; i++){
		if(linkId == sData.words[i].id){
			var hasChanged = false;
			if(sData.words[i]['word'] != sData.words[i]['currentSuggestion']) hasChanged = true;
			
			suggestDiv.innerHTML = "";
			showElement(suggestDiv);
			
			// show current selection
			tLink = document.createElement('a');
			tLinkText = document.createTextNode(sData.words[i]['currentSuggestion']);
			
			tLink.appendChild(tLinkText);
			tLink.setAttribute('href', 'javascript:fuzzForm.spellcheck.selectSuggestion("'+formName+'", "'+elementName+'", '+linkId+', "'+sData.words[i]['currentSuggestion']+'");');
			
			if(hasChanged){
				tLink.setAttribute('class', 'fuzzform-suggestion-link');
				tLink.setAttribute('className', 'fuzzform-suggestion-link');
			}
			else{
				tLink.setAttribute('class', 'fuzzform-spellcheck-error-link');
				tLink.setAttribute('className', 'fuzzform-spellcheck-error-link');
			}
			suggestDiv.appendChild(tLink);
			
			tDiv = document.createElement('div');
			tDiv.setAttribute('class', 'fuzzform-suggestion-text');
			tDiv.setAttribute('className', 'fuzzform-suggestion-text');
			tDiv.appendChild(document.createTextNode("Suggested Words:"));
			suggestDiv.appendChild(tDiv);
			
			// create columns
			rDiv = document.createElement('div');
			rDiv.setAttribute('class', 'fuzzform-suggestions-col');
			rDiv.setAttribute('className', 'fuzzform-suggestions-col');
			
			lDiv = document.createElement('div');
			lDiv.setAttribute('class', 'fuzzform-suggestions-col');
			lDiv.setAttribute('className', 'fuzzform-suggestions-col');
			
			clearDiv = document.createElement('div');
			clearDiv.setAttribute('class', 'clear');
			clearDiv.setAttribute('className', 'clear');
			
			var j = 0;
			for(j = 0; j < sData.words[i]['suggestions'].length; j++){
				// create the link
				
				
				tDiv = document.createElement('div');
				tLink = document.createElement('a');
				tLinkText = document.createTextNode(sData.words[i]["suggestions"][j]);
				tLink.appendChild(tLinkText);
				tLink.setAttribute('href', 'javascript:fuzzForm.spellcheck.selectSuggestion("'+formName+'", "'+elementName+'", '+linkId+', "'+sData.words[i]["suggestions"][j]+'");');
				tLink.setAttribute('class', 'fuzzform-suggestion-link');
				tLink.setAttribute('className', 'fuzzform-suggestion-link');
				
				tDiv.appendChild(tLink);
				// add to the suggest box
				
				
				if(j % 2) rDiv.appendChild(tDiv);
				else lDiv.appendChild(tDiv);

			}
			
			
			
			
			suggestDiv.appendChild(lDiv);
			suggestDiv.appendChild(rDiv);
			suggestDiv.appendChild(clearDiv);
			
			//dump(lDiv.offsetWidth);
			// fix widths
			// get the margin, border, 
			//dump(suggestDiv.style);
			
			if(hasChanged){
				tDiv = document.createElement('div');
				tDiv.setAttribute('class', 'fuzzform-suggestion-text');
				tDiv.setAttribute('className', 'fuzzform-suggestion-text');
				tDiv.appendChild(document.createTextNode("Original Text:"));
				suggestDiv.appendChild(tDiv);
				
				tLink = document.createElement('a');
				tLinkText = document.createTextNode(sData.words[i]['word']);
				tLink.appendChild(tLinkText);
				tLink.setAttribute('href', 'javascript:fuzzForm.spellcheck.selectSuggestion("'+formName+'", "'+elementName+'", '+linkId+', "'+sData.words[i]['word']+'");');
				tLink.setAttribute('class', 'fuzzform-spellcheck-error-link');
				tLink.setAttribute('className', 'fuzzform-spellcheck-error-link');
				suggestDiv.appendChild(tLink);
			}
			else{			
				tDiv = document.createElement('div');
				tDiv.setAttribute('class', 'fuzzform-add-text');
				tDiv.setAttribute('className', 'fuzzform-add-text');
				tDiv.appendChild(document.createTextNode("Options:"));
				suggestDiv.appendChild(tDiv);
				
				tLink = document.createElement('a');
				tLinkText = document.createTextNode("add to dictionary");
				tLink.appendChild(tLinkText);
				tLink.setAttribute('href', 'javascript:fuzzForm.spellcheck.addToDictionary("'+formName+'", "'+elementName+'", '+linkId+', "'+sData.words[i]["word"]+'");');
				tLink.setAttribute('class', 'fuzzform-suggestion-link');
				tLink.setAttribute('className', 'fuzzform-suggestion-link');

				suggestDiv.appendChild(tLink);
			}
			xy = YAHOO.util.Dom.getXY(link);
			xy[0] = xy[0] - 11;
			xy[1] = xy[1] - 11;
			YAHOO.util.Dom.setXY(suggestDiv, xy);
			
			//dump(sData.words[i]);
		}
	}
}

fuzzForm.spellcheck.selectSuggestion = function selectSuggestion(formName, elementName, linkId, suggestedWord){
	var suggestDivId = "fuzzForm_"+formName+"_spellcheck_suggest_div_id";
	var suggestDiv = document.getElementById(suggestDivId);
	
	var linkElementId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_link_"+linkId+"_id";
	var link = document.getElementById(linkElementId);
	
	var hiddenJSONId = "fuzzForm_"+formName+"_"+elementName+"_element_textarea_spellcheck_json_div_id";
	var hiddenJSON = document.getElementById(hiddenJSONId);
	
	var sData = JSON.parse(hiddenJSON.innerHTML);
	
	var eTextElement = fuzzForm.getElement(formName, elementName);
	var eText = eTextElement.value;

	var i = 0;
	var posOffset = 0;
	for(i = 0; i < sData.words.length; i++){
		if(linkId == sData.words[i].id){
			
			// Get the original text that is in the hidden text area element.
			//alert(sData.words[i]['pos']);
			startStr = eText.substr(0,sData.words[i]['pos']);
			endStr = eText.substr(sData.words[i]['pos']+sData.words[i]['currentSuggestion'].length, eText.length);
			// create the new text
			newEText = startStr+suggestedWord+endStr;
			// set the element to the new string
			eTextElement.value = newEText;
			
			// set the offset that will be applied to the rest of the words
			posOffset = suggestedWord.length - sData.words[i]['currentSuggestion'].length;
			
			
			// set the link attrubutes in the main edit div
			// they become blue and show the newly picked word.
			if(suggestedWord == sData.words[i]["word"]) link.setAttribute("class","fuzzform-spellcheck-error-link");
			else link.setAttribute("class","fuzzform-suggestion-link");
			link.innerHTML = suggestedWord;
			
			// record the change in the JSON data
			sData.words[i]['currentSuggestion'] = suggestedWord;
			
		}
		else if (posOffset != 0){
			// fix the changed offsets
			sData.words[i]['pos'] += posOffset;
		}
	}
	// save the new JSON
	hiddenJSON.innerHTML = JSON.stringify(sData);
	
	hideElement(suggestDiv);
}

fuzzForm.spellcheck.addToDictionary = function addToDictionary(formName, elementName, linkId, word){
	
	var suggestDivId = "fuzzForm_"+formName+"_spellcheck_suggest_div_id";
	var suggestDiv = document.getElementById(suggestDivId);
	// hide the sugggest div
	hideElement(suggestDiv);
	
	fuzzForm.displayWaitDiv(formName, "Adding Custom Dictionary Word... Please Wait.");
	
	submitData = new Object();
	submitData.formName = formName;
	submitData.elementName = elementName;
	submitData.linkId = linkId;
	
	// check the spelling
	argArr = new Array();
	argArr[0] = word;
	fuzzAsync.callAction("fuzzForm", "addToDictionary", argArr, fuzzForm.spellcheck.addToDictionaryCallback, submitData);
}

fuzzForm.spellcheck.addToDictionaryCallback = function addToDictionaryCallback(response){
	callbackData = response.callbackData;
	
	if(response.isError){
		dump(response);
		//alert("Sorry an error has occured while adding the custom dictionary word. If this problem continues please contact the genInvoice administrator.");
	}
	fuzzForm.spellcheck.resumeEditing(callbackData.formName, callbackData.elementName);
	fuzzForm.spellcheck.checkSpelling(callbackData.formName, callbackData.elementName);
	
}


//handle open and close of a div
fuzzForm.floatingElements = new Object();

fuzzForm.isInDiv = function isInDiv(eId, e){
	// first let's see if the mouse is inside the div
	// 0 w
	// 1 h
	
	eDiv = document.getElementById(eId);
	eHeight = eDiv.offsetHeight;
	eWidth = eDiv.offsetWidth;
	ePos = YAHOO.util.Dom.getXY(eDiv);
	mPos = YAHOO.util.Event.getXY(e);
	
	ret = false;
		
	if(mPos[0] >= ePos[0] && mPos[0] < (ePos[0]+eWidth)){
		if(mPos[1] >= ePos[1] && mPos[1] < (ePos[1]+eHeight)){
			ret = true;
		}
	}

	return ret;
}

fuzzForm.hideFloatingElement = function hideFloatingElement(eId){
	hide(eId);
	if(fuzzForm.floatingElements[eId]){
		fuzzForm.floatingElements[eId] = null;
	}
}

fuzzForm.handleFloatingElementOut = function handleFloatingElementOut(eId, e, removeDiv){
	
	if(! removeDiv) removeDiv = false
	else removeDiv = true;
	
	if(! fuzzForm.isInDiv(eId, e)){
		if(! fuzzForm.floatingElements[eId]){
			fuzzForm.floatingElements[eId] = new Object();
		}
		fuzzForm.floatingElements[eId].pendingHide = setTimeout("fuzzForm.hideFloatingElement('"+eId+"', '"+removeDiv+"');",225);
	}

}

fuzzForm.handleFloatingElementOver = function handleFloatingElementOver(eId){
	//clear the timeout
	if(fuzzForm.floatingElements[eId] && fuzzForm.floatingElements[eId].pendingHide){
		clearTimeout(fuzzForm.floatingElements[eId].pendingHide);
	}
}

fuzzForm.toggleCheckboxes = function toggleCheckboxes(formName, elementName, isChecked){
	elements = document.getElementsByName("fuzzForm_"+formName+"_"+elementName+"_element");
	for(x = 0; x < elements.length; x++){
		elements[x].checked = isChecked;
	}
}

fuzzForm.insertAtCursor = function insertAtCursor(formName, elementName, value){
	insertAtCursorUtil(fuzzForm.getElement(formName, elementName), value);
}

// File Uploads
fuzzForm.reloadFileIFrame = function reloadFileIFrame(formName,elementName){
	// show the correct elements
	selectfileDiv = parent.document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_selectfile_container_div_id");
	fileDiv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_file_container_div_id");
	iFrame = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_iframe_id");
	showElement(selectfileDiv);
	hideElement(fileDiv);

	// set the formElement to the uid
	formElement = parent.fuzzForm.getElement(formName,elementName);
	if(formElement){
		formElement.value = "";
	}
	// first see if it exists
	iframediv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_iframe");
	if(iframediv){
		iframediv.src = fuzzFrameworkBaseURL + "/fuzzForm/uploadController.php?formName=" + formName + "&elementName=" + elementName;
	}
	else fuzzForm.initFileIFrame(formName,elementName,true);

}

// File Uploads
fuzzForm.initFileIFrame = function initFileIframe(formName,elementName,forceInit){
	//in init
	if(forceInit && forceInit === true) forceInit = true;
	else forceInit = false;

	doInit = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_doInit_div_id");

	iframeName = "fuzzForm_"+formName+"_"+elementName+"_upload_iframe";

	cDiv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_iframe_container_div_id");

	if(cDiv){
		if(! forceInit && ( ! doInit || doInit.innerHTML == 0)){
			hideElement(cDiv);
			return;
		}

		src = fuzzFrameworkBaseURL + "/fuzzForm/uploadController.php?formName=" + formName + "&elementName=" + elementName;
		iframe = document.createElement("iframe");
		iframe.setAttribute("name", iframeName);
		iframe.setAttribute("id", iframeName+"_id");
		iframe.setAttribute("src", src);
		
		iframe.setAttribute("SCROLLING", "no");
		iframe.setAttribute("MARGINWIDTH", "0");
		iframe.setAttribute("MARGINHEIGHT", "0");
		iframe.setAttribute("FRAMEBORDER", "0");

		cDiv.appendChild(iframe);
		showElement(cDiv);


	}

}

fuzzForm.runFuzzFormUpload = function runFuzzFormUpload(formName, elementName) {

	//fElement = document.getElementById("fuzzFormUploadController_form_file_id");
	//alert(fElement.value);
		// set filename
	fileNameDiv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_fileDescription_div_id");

	if(fileNameDiv) fileNameDiv.innerHTML = "Uploading file, please wait...";

	selectfileDiv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_selectfile_container_div_id");
	fileDiv = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_file_container_div_id");
	iFrame = document.getElementById("fuzzForm_"+formName+"_"+elementName+"_upload_iframe_id");

	hideElement(selectfileDiv);
	showElement(fileDiv);

	// set the error
	fObj = fuzzForm.getFormObject(formName);
	fuzzForm.hideElementError(formName, fObj.elements[elementName], fObj.validationDisplayMethod);

	iframe.getElementById("fuzzFormUploadController_form_id").submit();

}

fuzzForm.handleFileInputFocus = function handlFileInputFocus(formName, elementName){
	//te = fuzzForm.getElement(formName,"description").focus();
	//first, let them know they have focus
}

fuzzForm.getKeyCode = function getKeyCode(e) {

	//var nav4 = window.Event ? true : false;
	//if (nav4) var whichCode = e.which

	if(window.event) // IE
	{
	keynum = e.keyCode
	}
	else if(e.which) // Netscape/Firefox/Opera
	{
	keynum = e.which
	}
	return keynum;

}
