/*
	ValidationSupport.js
	Define common function for client validation.
	Required include Helpers.js first
*/

if (typeof(DEFINE_HELPERS)=="undefined")
{
	alert("Please include Helpers.js before ValidationSupport.js!");
}

//constants
var VALIDATE_DATE	= 1;	// mm/dd/yyyy format
var VALIDATE_TIME	= 2;	// 24 hours format
var VALIDATE_INT	= 3;	// [-2147483648 ...2147483647]
var VALIDATE_SHORT	= 4;	// [-32768 .... 32767
var VALIDATE_FLOAT	= 5;	//

var HILITE_COLOR = "#FF0000";

var MIN_SHORT_VALUE = -32768;
var MAX_SHORT_VALUE = 32767;
var MIN_INT_VALUE = -2147483648;
var MAX_INT_VALUE = 2147483647;
var MIN_DATE_VALUE = new Date(1753,0,1);
var MAX_DATE_VALUE = new Date(9999,11,31);
var MIN_SMALLDATE_VALUE = new Date(1900,0,1);
var MAX_SMALLDATE_VALUE = new Date(2079,5,6);

var ERROR_MESSAGE = "";
var SHORT_ERROR_MESSAGE = "Integer value must be between -32768 and 32767.";
var INT_ERROR_MESSAGE = "Integer value must be between -2147483648 and 2147483647.";
var POSITIVEINT_ERROR_MESSAGE = "Integer value must be between 0 and 2147483647.";
var DATE_ERROR_MESSAGE = "Date value must be between 1/1/1753 and 12/31/9999.";
var SHORTDATE_ERROR_MESSAGE = "Date value must be between 1/1/1900 and 6/6/2079.";


/*public*/
var UserFormValidate = null;

//
//			FormValidate
//
//  Validate form with call UserFormValidate function if defined
//  Return value:
//    true/false
/*public*/function FormValidate()
{
	if( UserFormValidate == null )
	{
		return true;
	}
	if( typeof(UserFormValidate) == "function" )
	{
		return UserFormValidate();
	}
	return true;
}

//
//			IsControlEmpty
//
//  Check for empty control
//  Arguments:
//    control - control for check
//  Return value:
//    true/false
/*public*/function IsControlEmpty( control )
{
	if (control == null) return true;
	if (typeof(control)=="undefined") return true;
	switch( control.tagName.toUpperCase())
	{
		case "INPUT":
			switch( control.type.toUpperCase())
			{
				case "TEXT":
					return control.value.trim()=="";
					break;
				case "HIDDEN":
					return control.value.trim()=="";
					break;
				case "PASSWORD":
					return control.value.trim()=="";
					break;
				case "FILE":
					return control.value.trim()=="";
					break;
				case "CHECKBOX":
					return !control.checked;
					break;
				case "RADIO":
					return !control.checked;
					break;
			}
			break;
		case "SELECT":
			if (control.multiple )
			{
				for( var i=0; i< control.options.length; i++ )
				{
					if( control.options(i).selected )
					{
						return false;
					}
				}
			}
			else
			{
				return control.selectedIndex < 0 ;
			}
			break;
		case "TEXTAREA":
			return control.value.trim()=="";
			break;
	}
	return true;
}

//
//				IsNumbersOnly
//
//  Check value for numbers only
//  Return empty string if value contains only numbers 0-9
//	  or error message
//	Arguments:
//	  value - checked value
function IsNumbersOnly( value )
{
	var re = new RegExp( "[^\\-+0-9]", "g" );
	var errS = re.exec( value.trim() );
	if( errS != null ) return false;
	return true;
}

//
//			IsFloat
//
//  Check for float value
//  Error if value contain more digits then prec
//  Arguments:
//		value - string value for check
//		prec - number of places after point
//  Return:
//		true/false
function IsFloat( value, prec )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var v = value.trim();
	var ErrSymEx = new RegExp("[^\\-+0-9\\.]");
	var sym = ErrSymEx.exec( v );
	if( sym != null )
	{
		ERROR_MESSAGE = "Invalid symbol in value.";
		return false;
	}
	var formatRE = new RegExp("^(\\+|-)?\\d+\\.?\\d*$|^(\\+|-)?\\d*\\.\\d+$");
	if (!formatRE.test(v))
	{
		ERROR_MESSAGE = "Invalid float value.";
		return false;
	}
	if( prec != null && prec != -1 && typeof(prec)!= "undefined")
	{
		var sfCheckFloat = "^(\\+|-)?\\d+\\.?\\d{0,#0#}$|^(\\+|-)?\\d*\\.\\d{1,#0#}$";
		ErrSymEx = new RegExp(sfCheckFloat.format(prec));
		sym = ErrSymEx.exec( v );
		if( sym == null )
		{
			ERROR_MESSAGE = "Invalid precision in float value.";
			return false;
		}
	}
	return true;
}

//
//			IsIntPositive
//
//  Check for float value > 0
//  Error if value contain more digits then prec
//  Arguments:
//		value - string value for check
//		prec - number of places after point
//  Return:
//		true/false
function IsFloatPositive( value, prec )
{
	var result = IsFloat( value, prec );
	if (result)
	{
		result = result && (value >= 0);
		ERROR_MESSAGE = "Float value must be greater then 0.";
	}
	return result;
}

//
//			IsInt
//
//  Check for int value
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsInt( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	if(!IsNumbersOnly(value))
	{
		ERROR_MESSAGE = "Invalid symbol in value.";
		return false;
	}
	var iVal = parseInt( value.trim(), 10 );
	if(isNaN(iVal))
	{
		ERROR_MESSAGE = "Invalid int value";
		return false;
	}
	if (iVal != value.trim())
	{
		ERROR_MESSAGE = "Invalid int value.";
		return false;
	}
	if( iVal>=MIN_INT_VALUE && iVal <= MAX_INT_VALUE ) return true;
	ERROR_MESSAGE = INT_ERROR_MESSAGE;
	return false;
}

//
//			IsIntPositive
//
//  Check for int value > 0
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsIntPositive( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	if(!IsNumbersOnly(value))
	{
		ERROR_MESSAGE = "Invalid symbol in value.";
		return false;
	}
	var iVal = parseInt( value.trim(), 10 );
	if(isNaN(iVal))
	{
		ERROR_MESSAGE = "Invalid int value";
		return false;
	}
	if (iVal != value.trim())
	{
		ERROR_MESSAGE = "Invalid int value.";
		return false;
	}
	if( iVal>=0 && iVal <= MAX_INT_VALUE ) return true;
	ERROR_MESSAGE = POSITIVEINT_ERROR_MESSAGE;
	return false;
}

//
//			IsShort
//
//  Check for short value
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsShort( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	if(!IsNumbersOnly(value))
	{
		ERROR_MESSAGE = "Invalid symbol in value.";
		return false;
	}
	var iVal = parseInt( value.trim(), 10 );
	if(isNaN(iVal))
	{
		ERROR_MESSAGE = "Invalid short value.";
		return false;
	}
	if (iVal != value.trim())
	{
		ERROR_MESSAGE = "Invalid short value.";
		return false;
	}
	if( iVal>=-32768 && iVal <= 32767 ) return true;
	ERROR_MESSAGE = SHORT_ERROR_MESSAGE;
	return false;
}

//
//			IsDate
//
//  Check value for date (format mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy)
//  Possible enter one or two digits for day/month but only four digits for year
//  Check for range 1753 year - 9999 year
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsDate(value)
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	//					 space  0    1-9 or 1[0-2]sep   0     1-9 or1-2[0-9]or3[0-1] sep  4dig
	//var re = new RegExp("^\\s*(0{0,1}[1-9]|1[0-2])/(0{0,1}[1-9]|[1-2]\\d|3[0-1])/(\\d{4}||\\d{2})\\s*$");
	var re = new RegExp("^\\s*(\\d{0,1}\\d)/(\\d{0,1}\\d)/(\\d{4}||\\d{2})\\s*$");
	var m = value.trim().match(re);
	if(m == null)
	{
		ERROR_MESSAGE = "Invalid symbol in value or invalid date format.";
		return false;
	}
	if( m.length != 4 )
	{
		ERROR_MESSAGE = "Invalid date format.";
		return false;
	}
	var month = parseInt(m[1], 10);
	if (month>12)
	{
		ERROR_MESSAGE = "Invalid month in date value.";
		return false;
	}
	month--;
	var d = parseInt(m[2], 10);
	if (d>31)
	{
		ERROR_MESSAGE = "Invalid day in date value.";
		return false;
	}
	var year = parseInt(m[3], 10);
	if (year<100)
	{
		year += (year>=50) ? 1900 : 2000;
	}
	var date = new Date( year, month, d );
	if( date.getDate() != d )
	{
		ERROR_MESSAGE = "Invalid day in date value.";
		return false;
	}
	if( date.getMonth() != month )
	{
		ERROR_MESSAGE = "Invalid month in date value.";
		return false;
	}
	if( date.getFullYear() != year )
	{
		ERROR_MESSAGE = "Invalid year in date value.";
		return false;
	}
	if (date < MIN_DATE_VALUE || date>MAX_DATE_VALUE)
	{
		ERROR_MESSAGE = DATE_ERROR_MESSAGE;
		return false;
	}
	return true;
}

//
//			IsDate
//
//  Check value for date (format mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy)
//  Possible enter one or two digits for day/month but only four digits for year
//  Check for range 1753 year - 9999 year
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsDateMinused(value)
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	//					 space  0    1-9 or 1[0-2]sep   0     1-9 or1-2[0-9]or3[0-1] sep  4dig
	var re = new RegExp("^\\s*(0{0,1}[1-9]|1[0-2])-(0{0,1}[1-9]|[1-2]\\d|3[0-1])-(\\d{4}|\\d{2})\\s*$");
	var m = value.trim().match(re);
	if(m == null)
	{
		ERROR_MESSAGE = "Invalid symbol in value or date format.";
		return false;
	}
	if( m.length != 4 )
	{
		ERROR_MESSAGE = "Invalid date format.";
		return false;
	}
	var year = parseInt(m[3],10);
	if (year<100)
	{
		year += (year>=50) ? 1900 : 2000;
	}
	var date = new Date( year, m[1]-1, m[2] );
	if( date.getDate() != parseInt(m[2],10) )
	{
		ERROR_MESSAGE = "Invalid day in date value.";
		return false;
	}
	if( date.getMonth()+1 != parseInt(m[1],10) )
	{
		ERROR_MESSAGE = "Invalid month in date value.";
		return false;
	}
	if( date.getFullYear() != year )
	{
		ERROR_MESSAGE = "Invalid year in date value.";
		return false;
	}
	if (date < MIN_DATE_VALUE || date>MAX_DATE_VALUE)
	{
		ERROR_MESSAGE = DATE_ERROR_MESSAGE;
		return false;
	}
	return true;
}

//
//			IsShortDate
//
//  Check value for date (format mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy)
//  Possible enter one or two digits for day/month but only four digits for year
//  Check for range 1900 year - 2079 year
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsShortDate(value)
{
	RangeError = false;
	var result = IsDate(value);
	if (!result) return false;
	var date = new Date(value);
	if (date < MIN_SMALLDATE_VALUE || date>MAX_SMALLDATE_VALUE)
	{
		ERROR_MESSAGE = SHORTDATE_ERROR_MESSAGE;
		return false;
	}
	return true;
}

//
//			IsTime
//
//  Check time value HH:MM (24 hours) 
//  Arguments:
//		value - string value for check
//  Return:
//		true/false
function IsTime( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var re = new RegExp("^\\s*([0-1]{0,1}\\d|2[0-3]):([0-5]{0,1}\\d)\\s*$");
	var m = value.trim().match(re);
	if (m == null)
	{
		ERROR_MESSAGE = "Invalid time value. Should be in format HH:MM.";
		return false;
	}
	if (m.length != 3)
	{
		ERROR_MESSAGE = "Invalid time value or time format. Should be in format HH:MM.";
		return false;
	}
	return true;
}

// Check value on negative
// true - negative
// false - positive or zero
function IsNegative( value )
{
	var result = false;
	var val = value.trim();
	if (val.length > 0 && val.charAt(0) == "-")
	{
		result = true;
	}
	return result;
}

//
//				IsUSZipCode
//
// Return string with error message if value is invalid
//  US zip cde. If code is OK - return empty string.
//	Arguments:
//	  value - checked value
function IsUSZipCode( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var re = new RegExp( "^\\d{5}$|^\\d{9}$|^\\d{5}-\\d{4}$", "g" );
	var result = re.exec( value );
	if( result != null ) return true;
	re = new RegExp( "[^\\d|-]", "g" );
	var errS = re.exec( value );
	if( errS != null )
	{	
		sfErrorCharacterInZip = "Input can contain only numbers 0-9 and '-'. The incorrect entry is '#0#'.";
		ERROR_MESSAGE = sfErrorCharacterInZip.format( errS );
	}
	else
	{
		ERROR_MESSAGE = "Zip Code for U.S. must be in format XXXXX, XXXXXXXXX or XXXXX-XXXX.";
	}
	return false;
}

//
//				IsUSPhoneNumber
//
// Return string with error message if value is invalid
//  US phone number. If phone is OK - return empty string.
//	Arguments:
//	  value - checked value
function IsUSPhoneNumber( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var ErrSymEx = new RegExp("[^\\d \\(\\)\\-]");
	var sym = ErrSymEx.exec( value );
	if( sym != null )
	{
		sfErrorCharacterInPhone = "Input can contain only numbers 0-9, '(', ')', and '-'. The incorrect entry is '#0#'.";
		ERROR_MESSAGE = sfErrorCharacterInPhone.format( sym );
		return false;
	}
	// (xxx)/xxx/xxxx    xxx/xxx/xxxx
	var numEx = new RegExp( "^\\(\\d{3}\\)[ -]{0,1}\\d{3}[ -]{0,1}\\d{4}$|^\\d{3}[ -]{0,1}\\d{3}[ -]{0,1}\\d{4}$", "g");
	sym = numEx.exec( value );
	if( sym != null )
	{
		return true;
	}
	ERROR_MESSAGE = "Phone number for U.S. must be in format (xxx)/xxx/xxxx or xxx/xxx/xxxx where '/' mean space or '-' character.";
	return false;
}

function IsPhoneNumber( value )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var ErrSymEx = new RegExp("[^\\d \\(\\)\\-]");
	var sym = ErrSymEx.exec( value );
	if( sym != null )
	{
		sfErrorCharacterInPhone = "Input can contain only numbers 0-9, '(', ')', and '-'. The incorrect entry is '#0#'.";
		ERROR_MESSAGE = sfErrorCharacterInPhone.format( sym );
		return false;
	}
	return true;
}

function parseDate(dtString)
{
	var arr = dtString.split(' ');
	var dateArr = arr[0].split('/');

	var month = parseInt(dateArr[0], 10);
	var days  = parseInt(dateArr[1], 10);
	var year  = parseInt(dateArr[2], 10);
	if (year<100)
	{
		year += (year>=50) ? 1900 : 2000;
	}
	
	var min = 0;
	var h = 0;
	if (arr.length==2)
	{
		var timeArr = arr[1].split(':');
		h = parseInt(timeArr[0], 10);
		min = parseInt(timeArr[1], 10);
	}
	return new Date(year, month-1, days, h, min);
}

//
// IsPercent
//
// Check for Percent value
// Error if value contain more digits then prec
// Arguments:
// value - string value for check
// prec - number of places after point
// Return:
// true/false
function IsPercent( value, prec )
{
	ERROR_MESSAGE = "";
	if( value.trim() == "" ) return true;
	var v = value.trim();
	var ErrSymEx = new RegExp("[^\\0-9\\.]");
	var sym = ErrSymEx.exec( v );
	if( sym != null )
	{
		ERROR_MESSAGE = "Invalid symbol in value.";
		return false;
	}
	if( v.indexOf('.') != v.lastIndexOf('.') )
	{
		ERROR_MESSAGE = "Invalid Percent value.";
		return false;
	}
	if( prec != null && prec != -1 && typeof(prec)!= "undefined")
	{
		var sfCheckFloat = "^([0]{1}|[1-9]{1}\\d{0,2})(\\.\\d{1,#0#}){0,1}$";
		ErrSymEx = new RegExp(sfCheckFloat.format(prec));
		sym = ErrSymEx.exec( v );
		if( sym == null )
		{
			ERROR_MESSAGE = "Invalid precision in Percent value.";
			return false;
		}
	}
	if( parseFloat(v) > 100)
	{
		ERROR_MESSAGE = "Invalid Percent value.";
		return false;
	}
	return true;
}

//
//			IsEmail
//
//  Check Email address
//  Arguments:
//	  value - email string for check
//  Return value:
//	  true/false
function IsEmail(value)
{
  var regEx = new RegExp("^[a-zA-Z][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$");
  regEx.ignoreCase = false;
  ERROR_MESSAGE = "";
  var b = regEx.test(value.trim());
  if (!b)
  {
	ERROR_MESSAGE = "Invalid email address.";
  }
  return b;
}

//
//			ValidateEmailList
//
// Validate string with several email
// Arguments:
//		strList - string with list of emails
//		sep - separator character
//	Example:
//	  "my@email.free.com;my@work.email.gov" - separator = ';'
//  Return value:
//	  empty string if all emails is ok
//	  or string with bad email address
function ValidateEmailList(strList, sep)
{
	if (strList.trim()=="") return "";
	var arr = strList.trim().split(sep);
	for (var i=0; i<arr.length; i++)
	{
		if (arr[i] != "")
		{
			if (!IsEmail(arr[i])) return arr[i];
		}
	}
	return "";
}

/*private bool*/function PresentEmail(eList, sep)
{
	if (eList.trim()=="")return false;
	var arr = eList.trim().split(sep);
	for (var i=0; i<arr.length; i++)
	{
		if (arr[i] != "")
		{
			return true;
		}
	}
	return false;
}

/*private bool*/function PresentEmptyEmail(eList, sep)
{
	if (eList.trim()=="")return false;
	return eList.indexOf(sep+sep)!=-1;
}

var _controlToFlash = null;

function FlashControl( control )
{
	if (control == null) return;
	if (_controlToFlash != null) return;
	if (typeof(control)=="undefined") return;
	try
	{
		control.focus();
	}
	catch(ex)
	{
		return;
	}
	_controlToFlash = control;
	_number = 5;
	_originalBackground = _controlToFlash.style.backgroundColor;
	if (_controlToFlash.tagName.toUpperCase() == "SELECT")
	{
		_controlToFlash.disabled = true;
	}
	timerID = window.setInterval( "FlashTimerFunc()", 300 );
}

function FlashTimerFunc()
{
	if (_number == 0)
	{
		window.clearInterval( timerID );
		_controlToFlash.style.backgroundColor = _originalBackground;
		timerID = null;
		if (_controlToFlash.tagName.toUpperCase() == "SELECT")
		{
			_controlToFlash.disabled = false;
		}
		_controlToFlash = null;
		return;
	}
	_number--;
	if (_number%2==0)
	{
		_controlToFlash.style.backgroundColor = HILITE_COLOR;
	}
	else
	{
		_controlToFlash.style.backgroundColor = "window";
	}
}

// raising alert function
function RaiseAlert(message, control)
{
	alert(message);
	FlashControl(control);
	return false;
}