/*------------------------------------------------------*/
/* Objects:												*/
/* -formValidator										*/
/* -validationContainer									*/
/* -validatedElement									*/
/* -validationObject									*/
/* Version 1.72c										*/
/*------------------------------------------------------*/
var FvVersion = "1.72c";
function handleOnFocus(e)
{
	aElm = aElementHandler.getFunctionCaller(e);
	if (aElm != null)
	{
		if (aElm["p80onfocusfunc"] != null)
		{
			aElm["p80onfocusfunc"](aElm);
		}
	}
}

function handleOnBlur(e)
{
	if (typeof(handleInvalidOnBlur) != 'undefined')
	{
		aElm = aElementHandler.getFunctionCaller(e);
		if (aElm != null)
		{
			var thisValidation = (aElm["p80Container"].isRadio) ? validator.validateContainer(aElm["p80Container"],true) : validator.validateElement(aElm["p80Element"],true);
			handleInvalidOnBlur(aElm,thisValidation);
		}
	}
}

function formValidator(aName,aForm,aValidator)
{
	this.name = aName;
	this.form = aForm;
	this.elementonfocus = null;
	this.validateonblur = false;
	this.validator = aValidator;
	this.validationContainers = new Array;
	this.testAttr = new Array(3);
	this.sections = new Array();
	this.testAttr[0] = 'p80fv:required';
	this.testAttr[1] = 'p80fv:dependencieswhen';
	this.testAttr[2] = 'p80fv:domain';
	
	this.initFromForm = function()
	{
		this.elementonfocus = this.setElementOnFocus();
		this.validateonblur = aElementHandler.getBooleanAttribute(this.form,'p80fv:validateonblur');
		for(var i=0,aFrmElm;aFrmElm = this.form.elements[i];i++)
		{
			if (this.isP80fvObject(aFrmElm))
			{
				this.addContainer(aFrmElm);
			}
			var thisOnFocus = this.findOnFocus(aFrmElm);
			aFrmElm["p80onfocusfunc"] = thisOnFocus;
			if (thisOnFocus != null)
			{
				aElementHandler.attachOnFocusFunction(aFrmElm,handleOnFocus)
			}
		}
	}
	
	this.setElementOnFocus = function()
	{
		var aFuncName = aElementHandler.getNullableAttribute(this.form,'p80fv:onfocus');
		if (aFuncName != null)
		{
			try
			{
				return eval("window."+aFuncName);
			}
			catch(e)
			{
				debugTrace("setElementOnFocus: "+e.description,true);
			}
		}
		return null;
	}
	
	this.isP80fvObject = function(aElement)
	{
		var Retval = false;
		for (var i=0,aAttr;aAttr=this.testAttr[i];i++)
		{
			var thisAttr = aElementHandler.getNullableAttribute(aElement,aAttr);
			if (thisAttr != null)
			{
				Retval = true;
				break;
			}
		}
		Retval = ((Retval) && (aElementHandler.getNullableAttribute(aElement,"p80fv:dependson") == null));
		return Retval;
	}
	
	this.addContainer = function(aFormElement)
	{
		var aContainer = null;
		for (var i=0,aContainer;aContainer=this.validationContainers[i];i++)
		{
			if (aContainer.name == aFormElement.name)
			{
				break;
			}
		}
		if (aContainer == null)
		{
			aContainer = new validationContainer(aFormElement.name,this.validateonblur);
			aContainer.isRadio = (aFormElement.type == 'radio');
			this.validationContainers[this.validationContainers.length] = aContainer;
		}
		if (!aContainer.hasFormElement(aFormElement))
		{
		    aContainer.setRequiredCount(aFormElement);
		    var newElm = new validatedElement(this.form,aFormElement,aContainer);
		    newElm.initialise();
		    aContainer.addElement(newElm);
		}
	}
	
	this.findOnFocus = function(aFormElm)
	{
		var Retval = aElementHandler.getNullableAttribute(aFormElm,'p80fv:onfocus');
		if (Retval == null)
		{
			Retval = this.elementonfocus;
		}
		else
		{
			debugTrace(this.name+' has onfocus attribute');
			try
			{
				Retval = eval("window."+Retval);
			}
			catch(e)
			{
				debugTrace("findOnFocus:"+e.description,true);
			}
		}
		return Retval;
	}

	this.validate = function()
	{
		debugTrace('Form who called onsubmit: '+this.name);
		try
		{
			for (var i=0,aContainer;aContainer=this.validationContainers[i];i++)
			{
				debugTrace('Validating container:'+aContainer.name);
				Retval = this.validator.validateContainer(aContainer);
				if (!Retval)
				{
					debugTrace('INVALID!',true);
					return false;
					break;
				}
			}
		}
		catch(e)
		{
			debugTrace("validate: "+e.description,true);
		}
		return true;
	}
	
	this.validateSection = function(aSectionName)
	{
		debugTrace('Validating section: '+aSectionName);
		for (var i=0,aContainer;aContainer=this.validationContainers[i];i++)
		{
		    if (aContainer.isInSection(aSectionName))
		    {
			    debugTrace('Validating container:'+aContainer.name);
			    Retval = this.validator.validateContainer(aContainer);
			    if (!Retval)
			    {
				    debugTrace('INVALID!',true);
				    return false;
				    break;
			    }
			}
		}
		return true;
	}
}

/*----------------------------------------------------------------------*/

function validationContainer(aName,aValidateonblur)
{
	this.name = aName;
	this.validateonblur = aValidateonblur;
	this.validationElements = new Array();
	this.required = false;
	this.isRadio = false;
	this.ReqCount = null;
	debugTrace('Container created:'+aName);
	
	this.setRequiredCount = function(aFormElm)
	{
	    this.ReqCount = (this.ReqCount == null)  ? this.findRequiredCount(aFormElm) : this.ReqCount;
	}
	
	this.findRequiredCount = function(aFormElm)
	{
		var Retval = aElementHandler.getNumberAttribute(aFormElm,'p80fv:reqcount');
		if (Retval != null)
		{
            debugTrace('required count found:' + Retval);
		}
		return Retval;
	}
	
	this.findRequired = function(aFormElm)
	{
		this.required = aElementHandler.getBooleanAttribute(aFormElm,'p80fv:required');
		if (this.required == true)
		{
			debugTrace(this.name+' is required');
		}
	}

	this.findOnBlur = function(aFormElm)
	{
		var Retval = aElementHandler.getNullableAttribute(aFormElm,'p80fv:validateonblur');
		Retval = (Retval == null) ? this.validateonblur : (Retval == 'true');
		return Retval;
	}
	
	this.hasFormElement = function(aFormElement)
	{
	    for(var i=0,aElm;aElm=this.validationElements[i];i++)
	    {
	        if (aElm.formElement == aFormElement)
	        {
	            return true;
	        }
	    }
	    return false;
	}
	
	this.isInSection = function(aSectionName)
	{
	    var aParentNode = this.validationElements[0].formElement.parentNode;
	    while(aParentNode != null)
	    {
	        if (aParentNode.attributes)
	        {
	            var thisId = null;
                for(var i=0,aAttr;aAttr=aParentNode.attributes[i];i++) {
	                if(aAttr.nodeName.toLowerCase() == 'id' ) {
	                    thisId = aAttr.nodeValue.toLowerCase();
	                    break;
	                }
                }
	            if (thisId == aSectionName.toLowerCase())
	            {
	                return true;
	            }
	        }
	        aParentNode = aParentNode.parentNode;
	    }
	    return false;
	}
	
	this.addElement = function(aElement)
	{
		aElement.formElement["p80Container"] = this;
		this.validationElements[this.validationElements.length] = aElement;
		this.findRequired(aElement.formElement);
		var thisOnBlur = this.findOnBlur(aElement.formElement);
		if ((this.validateonblur) && (this.validateonblur == thisOnBlur) || ((!this.validateonblur) && (this.validateonblur != thisOnBlur)))
		{
		    aElementHandler.attachOnBlurFunction(aElement.formElement,handleOnBlur);
		}
	}
}

/*----------------------------------------------------------------------*/

function validatedElement(aForm,frmElm,aContainer)
{
	this.name = frmElm.name;
	this.container = aContainer;
	this.formElement = frmElm;
	this.parentForm = aForm;
	this.dependedObjects = null;
	this.validateDependenciesWhen = null;
	this.defaultValue = null;
	this.domain = null;
	this.Params = new Array();
	this.required = false;
	this.message = null;
	this.errorMessage = null;
	this.ommissionMessage = null;
	this.dependsOn = false;
	frmElm["p80Element"] = this;

	this.initialise = function()
	{
		this.validateDependenciesWhen = aElementHandler.getNullableAttribute(this.formElement,'p80fv:dependencieswhen');
		if (this.validateDependenciesWhen != null)
		{
			this.validateDependenciesWhen = new Boolean(this.validateDependenciesWhen == 'true');
			this.findDependedElements(this.formElement.id);
		}
		this.defaultValue	= aElementHandler.getNullableAttribute(this.formElement,'p80fv:default');
		this.required		= aElementHandler.getBooleanAttribute(this.formElement,'p80fv:required');
		this.domain			= this.setDomain();
		this.Params			= this.setParams();
		this.message		= this.setMessage();
		this.errorMessage	= this.setErrorMessage();
		this.ommissionMessage= this.setOmmissionMessage();
		this.dependsOn		= (aElementHandler.getNullableAttribute(this.formElement,'p80fv:dependson') != null) ? true : false;
		if ((this.required == true) && (this.validateDependenciesWhen != null))
		{
			debugTrace('Required field with dependencies: ' + this.name,true);
		}
	}

	this.setParams = function()
	{
		var RetVal = aElementHandler.getNullableAttribute(this.formElement,'p80fv:params');
		if (RetVal != null)
		{
			return RetVal.split(',');
		}
	}
	
	this.getConstantsMessage = function(aDomain,aType)
	{
        if (errorMessages)
        {
            var aMsg = errorMessages[aDomain];
            if ((aType == "")&&(typeof(aMsg) != 'object'))
            {
                return aMsg;
            }
            else
            {
                return (aMsg[aType]) ? aMsg[aType] : null;
            }
        }
        else
        {
            debugTrace('errorMessages object wasn\'t found, include validationConstants.js properly!',true);
            return null;
        }
	}
	
	this.setMessage = function()
	{
		var RetVal = aElementHandler.getNullableAttribute(this.formElement,'p80fv:message');
		if (RetVal != null)
		{
			debugTrace('Custom message found: ' + RetVal);
		}
		else
		{
		    return this.getConstantsMessage(this.domain,'');
		}
		return RetVal;
	}

	this.setErrorMessage = function()
	{
		var RetVal = aElementHandler.getNullableAttribute(this.formElement,'p80fv:errormessage');
		if (RetVal != null)
		{
			debugTrace('Custom error message found: ' + RetVal);
			return RetVal;
		}
		else
		{
			if (this.message != null){
				return this.message;
			}
			else
		    return this.getConstantsMessage(this.domain,'error');
			
		}
	}
	
	this.setOmmissionMessage = function()
	{
		var RetVal = aElementHandler.getNullableAttribute(this.formElement,'p80fv:ommissionmessage');
		if (RetVal != null)
		{
			debugTrace('Custom ommission message found: ' + RetVal);
			return RetVal;
		}
		else
		{
			if (this.message != null){
				return this.message;
			}
			else
		    return this.getConstantsMessage(this.domain,'omitted');
		}
	}

	this.setDomain = function()
	{
		var RetVal = aElementHandler.getNullableAttribute(this.formElement,'p80fv:domain');
		if (RetVal == null)
		{
			RetVal = this.formElement.type;
			debugTrace('standard domain found: ' + RetVal);
		}
		else
		{
			debugTrace('custom domain found: ' + RetVal);
		}
		loadDomain(RetVal);
		return RetVal;
	}
	
	this.findDependedElements = function(aID)
	{
		this.dependedObjects = new Array();
		var aValElm = null;
		debugTrace('Looking for depended objects for element with ID: ' + aID);
		for(var i=0,aElm;aElm = this.parentForm.elements[i];i++)
		{
			var thisDependsOnID = aElementHandler.getNullableAttribute(aElm,'p80fv:dependson');
			if (thisDependsOnID == aID)
			{
				var aValContainer = this.findDependedObjectContainer(aElm);
				aValElm = new validatedElement(this.parentForm,aElm,this.container);
				aValElm.initialise();
				if (aValContainer.required)
				{
					debugTrace('Depended object with required attribute! : '+aElm.name,true);
				}
				aValContainer.addElement(aValElm);
				debugTrace('Found depended object: '+aElm.name);
			}
		}
	}

	this.findDependedObjectContainer = function(aFormElement)
	{
		var retVal = null;
		for (var i,aValElm;aValElm=this.dependedObjects[i];i++)
		{
			if (aValElm.name == aFormElement.name)
			{
				retVal = aValElm;
				break;
			}
		}
		if (retVal == null)
		{
			retVal = new validationContainer(aFormElement.name,this.container.validateonblur);
			this.dependedObjects[this.dependedObjects.length] = retVal;
		}
		return retVal;
	}
}

/*----------------------------------------------------------------------*/

function validationObject(aName)
{
	this.instanceName = aName;
	this.validationFunctions = new Object();

	this.validationResults = new Array();
	this.validationResults[0] = 'valid';
	this.validationResults[1] = 'invalid';
	this.validationResults[2] = 'empty';
	this.validationResults[3] = 'ignore';
}

validationObject.prototype.trim = function(str)
{
  str=str.replace(/^\s*(.*)/, "$1");
  str=str.replace(/(.*)\s*$/, "$1");
  return str;
}

validationObject.prototype.elementHasDefaultValue = function(aElement)
{
 	return ((aElement.defaultValue != null) && (aElement.formElement.value == aElement.defaultValue));
}

validationObject.prototype.formElementIsUsed = function(aElement)
{
	var aFormElement = aElement.formElement;
	if (aFormElement.type)
	{
		switch(aFormElement.type)
		{
			case 'radio':
			case 'checkbox':
				return aFormElement.checked;
				break;
			case 'hidden':
			case 'file':
			case 'password':
			case 'text':
				return ((this.trim(aFormElement.value).length > 0) && (!this.elementHasDefaultValue(aElement)));
				break;
			case 'textarea':
				return ((this.trim(aFormElement.value).length > 0) && (!this.elementHasDefaultValue(aElement)));
				break;
			case 'select':
			case 'select-one':
			case 'select-multiple':
				return ((aFormElement.options.selectedIndex > -1) && (!this.elementHasDefaultValue(aElement)));
				break;
			default:
				return false;
				break;
		}
	}
	else
	{
		var Retval = false;
		for(var i=0,aBtn;aBtn=aFormElement[i];i++)
		{
			if (this.formElementIsUsed(aBtn))
			{
				Retval = true;
				break;
			}
		}
		return Retval;
	}
}

validationObject.prototype.validateContainer = function(aContainer,executeSilent)
{
	var thisValidation = this.validationResults[1]; //invalid;
    var validationscount = 0;
	for (var i=0,aValElm;aValElm=aContainer.validationElements[i];i++)
	{
		thisValidation = this.validateElement(aValElm);
		if (thisValidation == this.validationResults[0]){ validationscount++; }
		if (((thisValidation == this.validationResults[0]) && (aContainer.isRadio))
		    || ((thisValidation != this.validationResults[0]) && (aContainer.ReqCount == null) && (!aContainer.isRadio))
		    || ((thisValidation == this.validationResults[0]) && (validationscount == aContainer.ReqCount)  && (!aContainer.isRadio)))
		{
			break;
		}
	}

	if (i == aContainer.validationElements.length){ i--; }

	if (typeof(executeSilent) == 'undefined')
	{
		if (thisValidation ==  this.validationResults[1]) //invalid
		{
			this.reportValidationError(aContainer.validationElements[i]);
		}
		else if (thisValidation ==  this.validationResults[2]) //empty
		{
			this.reportOmmissionError(aContainer.validationElements[i]);
		}
	}

	return (thisValidation == this.validationResults[0]); //valid
}

validationObject.prototype.dispatchValidation = function(aElement)
{
	var aValidationFunc = this.validationFunctions[aElement.domain];
	if (typeof(aValidationFunc) == 'function')
	{
		return aValidationFunc(aElement);
	}
	else
	{
		debugTrace("No valid function found for "+aElement.domain+" validation!<br/>script file was probably not found, check p80fv:scriptpath attribute",true);
		alert("No valid function found for "+aElement.domain+" validation!\nscript file was probably not found, check p80fv:scriptpath attribute if path to javascript directory exists!!");
		return false;
	}
}

validationObject.prototype.validateElement = function(aElement)
{
	debugTrace('validating element ' + aElement.name + ', type is ' + aElement.domain);
	var thisValidation = false;
	if (aElement.validateDependenciesWhen == null)
	{
		if ((aElement.required == true) && (!this.formElementIsUsed(aElement)))
		{
			return this.validationResults[2]; //empty
		}
		else if ((aElement.required == true) && (this.formElementIsUsed(aElement)))
		{
			 thisValidation = this.dispatchValidation(aElement);
			 return (thisValidation) ? this.validationResults[0] : this.validationResults[1]; // valid/invalid
		}
		else if (aElement.dependsOn == true)
		{
			 thisValidation = this.dispatchValidation(aElement);
			 return (thisValidation) ? this.validationResults[0] : this.validationResults[1]; // valid/invalid
		}
		else if (this.formElementIsUsed(aElement))
		{
			thisValidation = this.dispatchValidation(aElement);
			return (thisValidation) ? this.validationResults[0] : this.validationResults[1]; // valid/invalid
		}
		else
		{
			return this.validationResults[0];
		}
	}
	else if (aElement.validateDependenciesWhen != null)
	{
		thisValidation = this.dispatchValidation(aElement);
		if (((aElement.validateDependenciesWhen == true) && (thisValidation == true)) || ((aElement.validateDependenciesWhen == false) && (!this.formElementIsUsed(aElement))))
		{
			if (aElement.dependedObjects != null)
			{
				for(var i=0,aElm;aElm=aElement.dependedObjects[i];i++)
				{
					if(this.validateContainer(aElm) == false)
					{
						return this.validationResults[3]; //ignore
					}
				}
				return this.validationResults[0]; //valid
			}
			else
			{
				debugTrace(aElement.name + ' has no depended object list!',true);
				return this.validationResults[0]; //valid
			}
		}
		else
		{
			return this.validationResults[0]; //valid
		}
	}
	else
	{
		return this.validationResults[0]; //valid
	}
}

validationObject.prototype.selectOrFocus = function(aFormElement)
{
    try
    {
        if (aFormElement.select)
        {
	        aFormElement.select();
	    }
	    else
	    {
	        aFormElement.focus();
	    }
    }
    catch(e)
    {
	    debugTrace("reportValidationError: "+e.description,true);
    }
}

validationObject.prototype.reportValidationError = function(aValidationElement)
{
	if (typeof(handleValidationError) == 'undefined')
	{
		if (aValidationElement.errorMessage == null)
		{
		    debugTrace("errorMessage is null!!",true);
		}
		else
		{
			alert(aValidationElement.errorMessage);
		}
		this.selectOrFocus(aValidationElement.formElement);
	}
	else
	{
		handleValidationError(aValidationElement);
	}
	return false;
}

validationObject.prototype.reportOmmissionError = function(aValidationElement)
{
	if (typeof(handleOmmissionError) == 'undefined')
	{
		if (aValidationElement.ommissionMessage == null)
		{
		    debugTrace("ommissionMessage is null!!",true);
		}
		else
		{
			alert(aValidationElement.ommissionMessage);
		}
		this.selectOrFocus(aValidationElement.formElement);
	}
	else
	{
		handleOmmissionError(aValidationElement);
	}
	return false;
}

validationObject.prototype.registerValidationFunction = function(aKey,funcPtr)
{
	this.validationFunctions[aKey] = funcPtr;
	debugTrace('Function registered for <strong>'+aKey+'</strong>');
}