/*
 * inputobj - manadatory - Form Input Item to validate
 *
 * alertstring - mandatory - message to show if validation fails
 *
 * fieldtype - optional - one of:
 *  select-one- one item in list/combobox must be selected
 *  date - must be a date dd/mm/yyyy
 *  usdate - must be a date mm/dd/yyyy
 *  time - must be a time hh:mm
 *  timeap - must be a time hh:mm a
 *  email - must be an email address
 *  numeric - must be a float
 *  integer - must be a whole number
 *  alpha - must be an alpha character
 *  alphanumeric - must be an alpha or number
 *  alphaspace - must be an alpha or number
 *  phone - valid phone
 *  url - valid url
 *  ccnumber - valid cc number
 *  ccexpiry - not expired
 *
 * maxvalue - optional -  max range of value (only applies to Integer and Numeric at the moment)
 *
 * minvalue - optional - min range of value (only applies to Integer and Numeric at the moment)
 *
 * 03/10/2005 - max and min values now apply to the date & usdate types. 
 *
 * Not specifying a type on a textfield will perform a blank check
 * not specifying a type on anything else will perform a "checked" check e.g. radiobuttons
 * specifying a type but not a range will just validate the type
 * specifying a max or min range will perfomr a range check
 *
 */

function setFocus(inputobj)
{
	try{
	   inputobj.setAttribute("autocomplete","OFF");
	   inputobj.focus();
	   inputobj.select();
	}catch(e){}
}

function InputItem(inputobj, alertstring, fieldtype, maxvalue, minvalue)
{
	this.inputobj = inputobj;
	this.alertstring = alertstring;
	this.fieldtype = fieldtype;
	this.maxvalue = maxvalue; // string - max allowed range
	this.minvalue = minvalue; // string - min allowed range
}

function validateformItems(inputItemArray)
{
	for(var i=0; i<inputItemArray.length; i++)
	{
		if(!validateInputItem(inputItemArray[i]))
		{
			alert(inputItemArray[i].alertstring);

			return(false);
		}
	}
	return(true);
}

function validateInputItem(inputitem)
{
	if(typeof(inputitem.inputobj.type) == "undefined" && typeof(inputitem.inputobj.length) != "undefined")
	{
		if(inputitem.inputobj[0].type == "checkbox")
		{
			return(validateisChecked(inputitem.inputobj));
		}
		else if(inputitem.inputobj[0].type == "radio")
		{
			return(validateisChecked(inputitem.inputobj));
		}
		else
		{
			return(validateAtLeastOne(inputitem));
		}
	}
	else if(inputitem.inputobj.type == "select-one")
	{
		return(validateisSelected(inputitem.inputobj));
	}
	else if(inputitem.inputobj.type == "select-multiple")
	{
		return(validateisSelectedMulti(inputitem.inputobj));
	}
	else if(inputitem.fieldtype && inputitem.fieldtype.length != 0)
	{
		//alert(inputitem.fieldtype);
		if(inputitem.inputobj.value.length != 0)
		{
			if(inputitem.fieldtype == "date")
			{
                if(validatecheckDate(inputitem.inputobj)) 
				{
                    if(validatecheckDateRange(inputitem)) 
					{
                        return true;
                    }
                }
                setFocus(inputitem.inputobj);
                return false;
			} 
			else if(inputitem.fieldtype == "usdate")
			{
				if(validatecheckUSDate(inputitem.inputobj)) 
				{
                    if(validatecheckUSDateRange(inputitem)) 
					{
                        return true;
                    }
                }
                setFocus(inputitem.inputobj);
                return false;
			}
			else if(inputitem.fieldtype == "time")
			{
				return(validatecheckTime(inputitem.inputobj));
			}
			else if(inputitem.fieldtype == "timeap")
			{
				return(validatecheckTimeAP(inputitem.inputobj));
			}
			else if(inputitem.fieldtype == "email")
			{
				return(validatecheckEmail(inputitem.inputobj));
			}
			else if(inputitem.fieldtype == "emails")
			{
				return(validatecheckEmails(inputitem.inputobj));
			}
			else if(inputitem.fieldtype == "numeric")
			{
                /*
                 * do the type check
                 *
                 * if that works do the range check
                *
                * if all fails set the focus to the control and exit
                */
                if(validatecheckNumeric(inputitem.inputobj)) {
                    if(validatecheckNumericRange(inputitem)) {
                        return true;
                    }
                }
                setFocus(inputitem.inputobj);
                return false;
         }
         else if(inputitem.fieldtype == "integer")
         {
             /*
             * do the type check
             *
             * if that works do the range check
             *
             * if all fails set the focus to the control and exit
             */
             if(validatecheckInteger(inputitem.inputobj)) {
                 if(validatecheckNumericRange(inputitem)) {
                     return true;
                 }
             }
             setFocus(inputitem.inputobj);
             return false;
         }			
         else if(inputitem.fieldtype == "alpha")
         {
             return(validatecheckAlpha(inputitem.inputobj));
         }
         else if(inputitem.fieldtype == "alphanumeric")
         {
             return(validatecheckAlphanumeric(inputitem.inputobj));
         }	
         else if(inputitem.fieldtype == "alphaspace")
         {
             return(validatecheckAlphaWithSpace(inputitem.inputobj));
         }		
         else if(inputitem.fieldtype == "phone")
         {
             return(validatecheckPhoneNumber(inputitem.inputobj));
         }	         
         else if(inputitem.fieldtype == "url")
         {
             return(validatecheckURL(inputitem.inputobj));
         }				
         else if(inputitem.fieldtype == "ccnumber")
         {
             return(validatecheckCCNumber(inputitem.inputobj));
         }
         else if(inputitem.fieldtype == "ccexpiry")
         {
             return(validatecheckCCExpiry(inputitem.inputobj));
         }				
		}
      else		
      {
			return(true);	
		}
	}
	else if(inputitem.inputobj.type == "text" || inputitem.inputobj.type == "textarea" 
	         || inputitem.inputobj.type == "password" || inputitem.inputobj.type == "file"
	         || inputitem.inputobj.type == "hidden")
	{	
		if(inputitem.maxvalue && inputitem.maxvalue.length != 0)
		{ 
			return(validateLength(inputitem));
		}
		else
		{
			return(validatenotEmpty(inputitem.inputobj));
		}
	}	
	else if(inputitem.inputobj.type == "checkbox")
	{
		return(validateisCheckedSingle(inputitem.inputobj));			
	}
	else if(inputitem.inputobj.type == "radio")
	{
		return(validateisCheckedSingle(inputitem.inputobj));			
	}
}


function validatecheckDate(textobj) {
	if(textobj.value == "NULL" || textobj.value == "TODAY" || textobj.value == "NOW" || textobj.value == "THISWEEK" || textobj.value == "THISMONTH" || textobj.value == "OVERDUE")
	{
		return(true);	
	}
	var dateregex = new RegExp("^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4,}$");
	if(dateregex.test(textobj.value))
	{
		var datenums = textobj.value.split("/");
		if(datenums[0]>0 && datenums[0]<32 && datenums[1]>0 && datenums[1]<13 && datenums[2]>1000 && datenums[2]< 9999)
		{
			return(true);	
		}
	}
	setFocus(textobj);
	return(false);	
   return  false;
}

function validatecheckUSDate(textobj)
{
	if(isDate(textobj))
	{
		var datenums = textobj.value.split("/");
		if(datenums[0]>0 && datenums[0]<13 && datenums[1]>0 && datenums[1]<32 && datenums[2]>1000 && datenums[2]< 9999)
		{
			return(true);	
		}
	}
   setFocus(textobj);
	return(false);	
}

/*
 * Validates that a string is of the form hh:mm with the max being 23:59 and the min being 00:00
 */
function validatecheckTime(textobj)
{
	if(textobj.value == "NULL")
	{
		return(true);	
	}
	var dateregex = new RegExp("^[0-9]{2}:[0-9]{2}$");
	if(dateregex.test(textobj.value))
	{
		var datenums = textobj.value.split(":");
		if(datenums[0]>=0 && datenums[0]<24 && datenums[1]>=0 && datenums[1]<60)
		{
			return(true);	
		}
	}
   setFocus(textobj);
	return(false);	
}
function validatecheckTimeAP(textobj)
{
	if(textobj.value == "NULL")
	{
		return(true);	
	} 

	// allows for h:mm a & hh:mm a 

	var ampm = textobj.value.substring(textobj.value.length-2, textobj.value.length); 
	var time = textobj.value.substring(0, textobj.value.length-3); 

	if ((ampm == "AM" || ampm == "PM") && (time.length==4 || time.length==5))
	{
		var dateregex = new RegExp("^[0-9]{"+(time.length-3)+"}:[0-9]{2}$");
		if(dateregex.test(time))
		{
			var datenums = time.split(":");
			if(datenums[0]>=1 && datenums[0]<13 && datenums[1]>=0 && datenums[1]<60)
			{
				return(true);	
			} 
		} 
	}
    setFocus(textobj);
	return(false);	
}

function validatecheckNumeric(textobj)
{
	var dateregex = new RegExp("^[0-9\\.]+$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
	/* now allows for negetive numbers, ie long/lat */ 
	if(textobj.value.indexOf("-")==0) { 
		if(dateregex.test(textobj.value.substring(1,textobj.value.length)))
		{
			return(true);
		}
	} 
   setFocus(textobj);
		return(false);	
}

function validatecheckPhoneNumber(textobj)
{
	var dateregex = new RegExp("^\\({0,1}\\d{0,3}\\){0,1}\\s{0,1}\\d{2,4}\\s{0,1}\\d{3,4}\\s{0,1}\\d{3,4}$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
   setFocus(textobj);
		return(false);	
}

function validatecheckAlpha(textobj)
{
	var dateregex = new RegExp("^[A-Za-z]+$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
   setFocus(textobj);
		return(false);	
}

function validatecheckAlphanumeric(textobj)
{
	var dateregex = new RegExp("^[0-9A-Za-z]+$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
   setFocus(textobj);
	return(false);	
}

function validatecheckAlphaWithSpace(textobj)
{
	var dateregex = new RegExp("^[A-Za-z\\s]+$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
	setFocus(textobj);
	return(false);	
}

function validatecheckAlphanumericWithSpace(textobj)
{
	var dateregex = new RegExp("^[0-9A-Za-z\\s]+$");
	if(dateregex.test(textobj.value))
	{
		return(true);
	}
   setFocus(textobj);
	return(false);	
}

function validatecheckURL(textobj) {

   var urlregex = new RegExp("^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk|au)(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$");
   var textobjval = textobj.value;
   	if(urlregex.test(textobj.value) ||  textobjval.substring(0,6) == "file:\\")
   	{
   		return(true);
   	}
      setFocus(textobj);
   	return(false);	  
}

function isInteger(str)
{
	var dateregex = new RegExp("^[0-9]+$");
	return(dateregex.test(str))
}

function validatecheckInteger(textobj)
{
	if(isInteger(textobj.value))
	{
		return(true);
	}
   setFocus(textobj);
	return(false);	
}

/*
 * Will check if the values in the input object of inputitem, once parsed as a 
 * Number is within the range specified by inputitem.minvalue and 
 * inputitem.maxvalue inclusive
 */
function validatecheckNumericRange(inputitem)
{
    var max = null;
    var min = null;
    var val = null;
    if(inputitem.maxvalue && (inputitem.maxvalue.length != 0))
        max = parseFloat(inputitem.maxvalue);
    if(inputitem.minvalue && (inputitem.minvalue.length != 0))
        min = parseFloat(inputitem.minvalue);
    if(inputitem.inputobj.value.length != 0)
        val = parseFloat(inputitem.inputobj.value);

    var ret = true;
    if( ( max != null) && (val > max) )
        ret = false;
    if( ( min != null) && (val < min) )
        ret = false;
    return ret;
}

function validatecheckDateRange(inputitem) { 

	// uses the date format dd/mm/yyyy
	var max = null;
    var min = null;
    var val = null;

    if(inputitem.maxvalue && (inputitem.maxvalue.length != 0)) { 
		max = new Date(); 
		max.setFullYear(getThirdDateField(inputitem.maxvalue)); 
		max.setDate(getFirstDateField(inputitem.maxvalue));
		max.setMonth(getSecondDateField(inputitem.maxvalue)); 		
	}
    if(inputitem.minvalue && (inputitem.minvalue.length != 0)) { 
		min = new Date(); 
		min.setFullYear(getThirdDateField(inputitem.minvalue)); 
		min.setDate(getFirstDateField(inputitem.minvalue));
		min.setMonth(getSecondDateField(inputitem.minvalue)); 
	} 
    if(inputitem.inputobj.value.length != 0) { 
       	val = new Date(); 
		val.setFullYear(getThirdDateField(inputitem.inputobj.value)); 
		val.setDate(getFirstDateField(inputitem.inputobj.value));
		val.setMonth(getSecondDateField(inputitem.inputobj.value)); 
	} 

	var ret = true; 
    if( ( max != null) && (val.getTime()>max.getTime()) ) {
        ret = false;
	}
    if( ( min != null) && (val.getTime()<min.getTime()) ) {
        ret = false;
	}

	return ret;
} 

function validatecheckUSDateRange(inputitem) { 
	
	// uses the date format mm/dd/yyyy
	var max = null;
    var min = null;
    var val = null;

    if(inputitem.maxvalue && (inputitem.maxvalue.length != 0)) { 
		max = new Date(); 
		max.setFullYear(getThirdDateField(inputitem.maxvalue)); 
		max.setDate(getSecondDateField(inputitem.maxvalue));
		max.setMonth(getFirstDateField(inputitem.maxvalue)); 		
	}
    if(inputitem.minvalue && (inputitem.minvalue.length != 0)) { 
		min = new Date(); 
		min.setFullYear(getThirdDateField(inputitem.minvalue)); 
		min.setDate(getSecondDateField(inputitem.minvalue));
		min.setMonth(getFirstDateField(inputitem.minvalue)); 
	} 
    if(inputitem.inputobj.value.length != 0) { 
       	val = new Date(); 
		val.setFullYear(getThirdDateField(inputitem.inputobj.value)); 
		val.setDate(getSecondDateField(inputitem.inputobj.value));
		val.setMonth(getFirstDateField(inputitem.inputobj.value)); 
	} 

	var ret = true; 
    if( ( max != null) && (val.getTime()>max.getTime()) ) {
        ret = false;
	}
    if( ( min != null) && (val.getTime()<min.getTime()) ) {
        ret = false;
	}

	return ret;
} 



function getFirstDateField(str) { 
	var days = ''; 
	days = str.substring(0,str.indexOf("/")); 
	return days; 
} 

function getSecondDateField(str) { 
	var month = ''; 
	month = str.substring(str.indexOf("/")+1,str.indexOf("/",str.indexOf("/")+1)); 
	return month; 
} 

function getThirdDateField(str) { 
	var year = ''; 
	var start = str.indexOf("/",str.indexOf("/")+1)+1; 
	year = str.substring(start,str.length); 

	return year; 
} 

function validateLength(inputitem)
{
	var max = new Number(inputitem.maxvalue);
	var val = inputitem.inputobj.value;
	if(val.length > max)
	{
	   if (inputitem.inputobj.type != "hidden") {
   		setFocus(inputitem.inputobj);
		}
    	return(false);
	}
	return(true);
}

function validatecheckEmail(textobj)
{
	var emailregex = new RegExp("^[^\\f\\n\\r\\t]*<{0,1}[^@ \\f\\n\\r\\t]+@[^@ \\f\\n\\r\\t]+\\.[^@\\. \\f\\n\\r\\t]+[a-zA-Z]>{0,1}$");
	if(emailregex.test(textobj.value))
	{
		return(true);	
	}
	setFocus(textobj);
		return(false);		
}

function validatecheckEmails(textobj)
{
	var emailstring = textobj.value;
	var emailaddresses = emailstring.split(",");
	var emailregex = new RegExp("^[^\\f\\n\\r\\t]*<{0,1}[^@ \\f\\n\\r\\t]+@[^@ \\f\\n\\r\\t]+\\.[^@\\. \\f\\n\\r\\t]+[a-zA-Z]>{0,1}$");

	for(var i=0; i<emailaddresses.length; i++)
	{
		if(!emailregex.test(emailaddresses[i]))
		{
	      setFocus(textobj);
			return(false);
		}
	}
	return(true);		
}

function validatecheckCCNumber(textobj)
{
	var CardNumber = textobj.value;

	if (!isInteger(CardNumber))
	{
		return false;
  	}

	var no_digit = CardNumber.length;
	var oddoeven = no_digit & 1;
	var sum = 0;

	for (var count = 0; count < no_digit; count++)
	{
		var digit = parseInt(CardNumber.charAt(count));
		if (!((count & 1) ^ oddoeven))
		{
			digit *= 2;
			if (digit > 9)
			{
				digit -= 9;
			}
		}
		sum += digit;
	}
	
	if (sum % 10 == 0)
	{
		return true;
	}

	return false;
}

function validatecheckCCExpiry(textobj)
{
	var expiry = textobj.value;
	var year = null;
	var month = null;
	if(expiry.length == 4)
	{ // MMYY format
		month = expiry.substring(0,2);
		year = expiry.substring(2,4);
	}
	else if(expiry.length == 5 && expiry.indexOf('/')>0)
	{ // MM/YY format
		month = expiry.substring(0,2);
		year = expiry.substring(3,5);
	}
	
	if (!isInteger(year) || !isInteger(month))
	{
		return false;
	}
	
	month = new Number(month);
	
	if(month < 1 || month > 12)
	{
		return false;
	}	

	today = new Date();
	var cyear = today.getFullYear();
	cyear = "" + cyear;
	cyear = cyear.substring(0,2);
	year = new Number(cyear + year); //YYYY format
	
	expiry = new Date();
	expiry.setMonth(month - 1); //jan is 0
	expiry.setFullYear(year)
	
	if (today.getTime() > expiry.getTime())
	{
		return false;
	}
	else
	{
		return true;
	}
}

function validatenotEmpty(textobj)
{
	if(textobj.value.length != 0)
	{
		return(true);
	}
	
   if (textobj.type != "hidden") {
	   setFocus(textobj);
	}
		
	return(false);	
}

function validateisCheckedSingle(checkobj)
{
	if(checkobj.checked=="1" || (checkobj.checked && checkobj.checked!="1"))
	{
		return(true);
	}
	try{
		checkobj.focus();
	}catch(e){}
	return(false);
}


function validateisChecked(checkobj)
{
	for (var i=0; i<checkobj.length; i++)
	{
		if (checkobj[i].checked=="1" || (checkobj[i].checked && checkobj[i].checked!="1"))
		{
			return(true);
		}
	}
	try{
		checkobj[0].focus();
	}catch(e){}
	return(false);
}

function validateAtLeastOne(inputitem)
{
	for(var i=0; i<inputitem.inputobj.length; i++)
	{
		if(validateInputItem(new InputItem(inputitem.inputobj[i], inputitem.alertstring, inputitem.fieldtype)))
		{
			return(true);
		}
	}
	return(false);
}

function validateisSelected(selectobj)
{
	var sindex = selectobj.selectedIndex;
	var selectedoption = selectobj.options[sindex];
	if(selectedoption.value!="" && selectedoption.value!="NONE")
	{
		return(true);
	}
	try{
		selectobj.focus();
	}catch(e){}
	return(false);
}

function validateisSelectedMulti(selectobj)
{
	var sindex = selectobj.selectedIndex;
	if(sindex!=-1)
	{
		var selectedoption = selectobj.options[sindex];
		if(selectedoption.value!="" && selectedoption.value!="NONE")
		{
			return(true);
		}
	}
	try{
		selectobj.focus();
	}catch(e){}
	return(false);
}

function getElementsByInputObj(inputobj)
{
	var elementname = inputobj.name;
	var thislistform = inputobj.form;
	var nameelements = new Array();

	for(var i=0; i<thislistform.elements.length; i++)
	{
		if(thislistform.elements[i].name == elementname)
		{
			nameelements[nameelements.length] = thislistform.elements[i];
		}
	}
	return(nameelements);
}

function getElementsByName(formobj, inputname)
{
	var elementname = inputname;
	var thislistform = formobj;
	var nameelements = new Array();

	for(var i=0; i<thislistform.elements.length; i++)
	{
		if(thislistform.elements[i].name == elementname)
		{
			nameelements[nameelements.length] = thislistform.elements[i];
		}
	}
	return(nameelements);
}

function getFirstCheckedValue(formobj, inputname)
{
	var inputs = getElementsByName(formobj, inputname);
	for(var i=0; i<inputs.length; i++)
	{
		if(inputs[i].checked)
		{
			return(inputs[i].value);
		}
	}

	return("");
}

function isDateConstant(value)
{
	if((value.indexOf("NEXT")==0 || value.indexOf("LAST")==0) && (value.indexOf("DAYS")>0 || value.indexOf("WEEKS")>0 || value.indexOf("MONTHS")>0))
	{
		return(true);
	}
	else
	{
		for(var i=0; i<dataconstants.length; i++)
		{
			if(dataconstants[i] == value)
			{
				return(true);
			}
		}
	}
	return(false);
}

var dataconstants = new Array(
		"NOW",
		"TODAY",
		"THISWEEK",
		"THISMONTH",
		"FUTURE",
		"OVERDUE",
		"CURRENTMONTH",
		"CURRENTYEAR",
		"CURRENTWEEK",
		"LASTWEEK",
		"LASTMONTH",
		"LASTYEAR"
	);