
//Global variables
var SV_counter=0;
var SV_arrMsg = [];
var SV_arrCtl = [];
var Validators = [];

//Constants
var SV_HEADING = "";
var SV_Extra ="";

function CValidator(obj_target)
{
	//assign validation methods
	this.ValidateRequired = SV_ValidateRequired;
	this.ValidateMaxLength=SV_ValidateMaxLength;
	this.ValidateRange=SV_ValidateRange;
	this.ValidateCompare=SV_ValidateCompare;
	this.CustomMessage=SV_CustomMessage;
	
	//Added by Apurva Kaushal
	this.ValidateMinLength=SV_ValidateMinLength;
	
	//this.ValidateExtension=VS_ValidateExtension;
	this.ParseDate=SV_ParseDate;
	this.Trim = SV_Trim;
	this.Validate = SV_Validate;
	this.IsInvalid = SV_IsInvalid;
	this.DisplayMessage= SV_DisplayMessage;
	
	//validate input parameters
	//if (!obj_target)
	//	return SV_error("Error calling the CValidator: no target control specified");
	
	this.target  = obj_target;
	//this.arrMsg  = SV_arrMsg;
	//this.arrCtl  = SV_arrCtl;
	this.arrMsg  = [];
	this.arrCtl  = [];
	this.counter = 0;
	this.heading = SV_HEADING;
	this.Extra   = "";
	this.ShowAlert=true;
	this.Scroll=true;
	
	// register in global collections
	this.id = Validators.length;
	Validators[this.id] = this;	

}

//========================================================
//Validation Controls Starts Here....
//========================================================

function SV_CustomMessage(ctrlId,Msg)
{
	if(this.IsInvalid(ctrlId))
	{
		this.arrMsg[this.counter]= Msg;
		this.arrCtl[this.counter]=ctrlId;
		this.counter++;
	}
}

//Required Field Validator
function SV_ValidateRequired(ctrlId,Msg)
{
	ctl = document.getElementById(ctrlId);
	blnFlag=false;
	switch(ctl.type)
	{
		case "text":  //textbox,password,file,textarea
		case "password":
		case "file":
		case "textarea":		
			if(this.Trim(ctl.value)=="")
				blnFlag=true;	
		break;
		case "select-one": //dropdown
			if(ctl.selectedIndex ==0 || ctl.selectedIndex ==-1 )
				blnFlag=true;
		break;
		case "select-multiple": //listbox
			if(ctl.selectedIndex==-1)
				blnFlag=true
		break;
		case "checkbox":
		case "radio":
			if(!ctl.checked)
				blnFlag=true;		
		break;
	}
	
	if(blnFlag)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;
	}
	else
		return true;
}

/*
function SV_ValidateMaxLength(ctrlId,Msg,maxLength)
{
	ctl = document.getElementById(ctrlId);

	if(ctl.value.length > maxLength)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;
	}
	else
		return true;	
}
*/
function SV_ValidateMaxLength(ctrlId,Msg,maxLength,blnRequired,reqMsg)
{
	ctl = document.getElementById(ctrlId);

	//Check if the control is required.
	if(blnRequired)
	{
		if(!this.ValidateRequired(ctrlId,reqMsg))
			return false;
	}
	else //if not required some value should be there.
	{
		if(this.Trim(ctl.value)=="")
			return true;
	}
	
	if(ctl.value.length > maxLength)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;
	}
	else
		return true;	
}

//***************************************************
//Added by Apurva Kaushal
//Function to check the minimum characters.
//***************************************************

function SV_ValidateMinLength(ctrlId,Msg,minLength)
{
	ctl = document.getElementById(ctrlId);

	//Check if the control is required.
	/*if(blnRequired)
	{
		if(!this.ValidateRequired(ctrlId,reqMsg))
			return false;
	}
	else //if not required some value should be there.
	{
		if(this.Trim(ctl.value)=="")
			return true;
	}*/
	
	if(ctl.value.length < minLength)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;
	}
	else
		return true;	
}


function SV_ValidateCompare(ctrlId_1,operator,ctrlId_2,type,Msg)
{

	var regEx;
	var blnFlag=false;
	
	ctl_1 = document.getElementById(ctrlId_1);
	ctl_2 = document.getElementById(ctrlId_2);
	ctl_1_val = this.Trim(ctl_1.value);
	ctl_2_val = this.Trim(ctl_2.value);
			
	switch(type)
	{
		case "STRING":
			if( ctl_1_val=="")return true;
			fromStart=ctl_1_val;
			toEnd=ctl_2_val;
			break;
		case "DATE":
			if( ctl_1_val=="" || ctl_2_val=="")return true;
			fromStart=Date.parse(ctl_1_val)/60/60/60/24;
			toEnd=Date.parse(ctl_2_val)/60/60/60/24;
			break;
		case "DOUBLE":
			if( ctl_1_val=="" || ctl_2_val=="")return true;
			fromStart=parseFloat(ctl_1_val);
			toEnd=parseFloat(ctl_2_val);
			break;
		case "INTEGER":
			if( ctl_1_val=="" || ctl_2_val=="")return true;
			fromStart=parseInt(ctl_1_val);
			toEnd=parseInt(ctl_2_val);
			break;
	}	//end of outer switch
	
	switch(operator)
	{
		case "=":
			if(fromStart==toEnd)
				blnFlag=true;
			break;
		case "<=":
			if(fromStart<=toEnd)
				blnFlag=true;
			break;
		case ">=":
			if(fromStart>=toEnd)
				blnFlag=true;
			break;
		case "<":
			if(fromStart<toEnd)
				blnFlag=true;
			break;
		case ">":
			if(fromStart>toEnd)
				blnFlag=true;
			break;
	} 
		
	if(!blnFlag)
	{
		if(this.IsInvalid(ctrlId_1))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId_1;
			this.counter++;
		}
		return false;	
	}
	else
		return true;
}

function SV_ValidateRange(ctrlId,Msg,from,to,type,blnRequired,reqMsg)
{
	ctl = document.getElementById(ctrlId);

	//Check if the control is required.
	if(blnRequired)
	{
		if(!this.ValidateRequired(ctrlId,reqMsg))
			return false;
	}
	else //if not required some value should be there.
	{
		if(this.Trim(ctl.value)=="")
			return true;
	}
		
	var regEx;
	var blnFlag=false;
	
	switch(type)
	{
		case "DOUBLE":
			regEx = /^((\d*)|(\d*\.\d{2})|(\d*)|(\d*\.\d{1}))$/;	
			blnFlag = regEx.test(ctl.value);
			if(from==0 && to==0)break;
			if(blnFlag)
			{
				val = parseFloat(ctl.value);
				if(val >= from && val <= to)
					blnFlag=true;
				else
					blnFlag=false; 
			}	
		break;
		case "INTEGER":
			regEx = /^(\d*)$/;	
			blnFlag = regEx.test(ctl.value);
			if(from==0 && to==0)break;
			if(blnFlag)
			{
				val = parseInt(ctl.value);
				if(val >= from && val <= to)
					blnFlag=true;
				else
					blnFlag=false; 
			}	
		break;
		case "DATE":
			tempMsg=this.ParseDate(ctl.value);
			
			if(tempMsg=="") //check the range(date is valid)
			{
				if(from==0 && to==0)
				{
					blnFlag=true;
					break;
				}
				fromMilli = Date.parse(from)/60/60/60/24;
				toMilli = Date.parse(to)/60/60/60/24;
				ctlMilli = Date.parse(ctl.value)/60/60/60/24;
							
				if(ctlMilli >=fromMilli && ctlMilli <=toMilli)
				{
					blnFlag=true;
				}
				else
					blnFlag=false;
				
			}
			else
			{
				Msg += "(" + tempMsg + ")";
				blnFlag=false;
			}
			
		break;
		case "MAXLENGTH":
			if(ctl.value.length > to)
				blnFlag=false;
			else
				blnFlag=true;
		break;
	}
	
	if(!blnFlag)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;	
	}
	else
		return true;
}

function SV_Validate(strType,ctrlId,Msg,blnRequired,regMsg)
{
	
	ctl = document.getElementById(ctrlId);
	
	//Check if the control is required.
	if(blnRequired)
	{
		if(!this.ValidateRequired(ctrlId,regMsg))
			return false;
	}
	else //if not required some value should be there.
	{
		if(this.Trim(ctl.value)=="")
			return true;
	}
		
	
	var blnFlag=false;
	
	var regEx;
	switch(strType)
	{
		case "EMAIL":
			regEx = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;;		
			blnFlag=regEx.test(ctl.value);
			break;
		case "URL":
			regEx = /^(file|http|https):\/\/\S+$/;
			//regEx = /^(file|http|https):\/\/\S+\.(com|net|org|info|biz|ws|us|tv|cc)$/;
			blnFlag=regEx.test(ctl.value);
			break;
		case "ZIP":
			regEx = /^[ 0-9a-zA-Z]+$/; //allowed
			blnFlag=regEx.test(ctl.value);
			if(blnFlag)
			{
				regEx = /([0-9(\b)].*){1}/; //Atleast one number
				blnFlag=regEx.test(ctl.value);
			}
			break;
		case "PHONE":
		case "FAX":	
			//regEx = /^[\-\s\(\)0-9]+$/; //allowed
			
			//regEx =/^((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}/;
			
			///regEx =/^[0-9]{3}([\-][0-9]{4})?/;
			regEx =/^[0-9]{3}([\-][0-9]{4})?/;

			
			blnFlag=regEx.test(ctl.value);
			if(blnFlag)
			{
				regEx = /[0-9]{1}/; //Atleast one number
				blnFlag=regEx.test(ctl.value);
			}
			break;
		case "PASSWORD":
			regEx = /^[^\s]+$/;	
			blnFlag=regEx.test(ctl.value);
			break;
		case "USERNAME":
			regEx = /^[^\s]+$/; //spaces not allowed
			blnFlag=regEx.test(ctl.value);
			if(blnFlag)
			{
				regEx = /[a-zA-Z]{1}/; //Atleast one char
				blnFlag=regEx.test(ctl.value);
			}
			break;
		case "NAMES":
			//regEx = /^[a-zA-Z .'0-9]+$/; 
			regEx = /^[a-zA-Z .']+$/; 
			blnFlag=regEx.test(ctl.value);
			if(blnFlag)
			{
				regEx = /[a-zA-Z]{1}/; //atleast one char
				blnFlag=regEx.test(ctl.value);
			}
			break;
		case "EXTENSION":
			regEx = new RegExp("^(.*)(\\." + this.Extra + ")$");
			strTemp=ctl.value.toLowerCase();
			match = strTemp.match(regEx);
			if (match != null)
				blnFlag=true;
			break;
		//Added by Apurva Kaushal
		case "ALPHANUMERIC":
			regEx = /^[ 0-9a-zA-Z]+$/; //allowed
			blnFlag=regEx.test(ctl.value);
			break;
		case "NUMERIC":
			regEx = /^[ 0-9]+$/; //allowed
			blnFlag=regEx.test(ctl.value);
			break;
			
	}
	
	if(!blnFlag)
	{
		if(this.IsInvalid(ctrlId))
		{
			this.arrMsg[this.counter]= Msg;
			this.arrCtl[this.counter]=ctrlId;
			this.counter++;
		}
		return false;	
	}
	else
		return true;
}


//=======================================================
//Validations controls ends here...
//=======================================================

//Check if the control is already invalid.
function SV_IsInvalid(currentCtlId)
{
	var blnFlag=true;
	for(i=0;i<this.arrCtl.length;i++)
	{
		if(this.arrCtl[i]==currentCtlId)
			blnFlag=false;
		else
			blnFlag=true;	
	}
	return blnFlag;
}

//Parse Date
function SV_ParseDate(str_date) {

	var arr_date = str_date.split('/');
	var RE_NUM = /^\-?\d+$/;
		
	if (arr_date.length != 3) return ("Invalid date format: '" + str_date + "'.\nFormat accepted is mm/dd/yyyy.");
	if (!arr_date[1]) return ("Invalid date format: '" + str_date + "'.\nNo day of month value can be found.");
	if (!RE_NUM.exec(arr_date[1])) return  ("Invalid day of month value: '" + arr_date[1] + "'.\nAllowed values are unsigned integers.");
	if (!arr_date[0]) return  ("Invalid date format: '" + str_date + "'.\nNo month value can be found.");
	if (!RE_NUM.exec(arr_date[0])) return  ("Invalid month value: '" + arr_date[0] + "'.\nAllowed values are unsigned integers.");
	if (!arr_date[2]) return  ("Invalid date format: '" + str_date + "'.\nNo year value can be found.");
	if (!RE_NUM.exec(arr_date[2])) return  ("Invalid year value: '" + arr_date[2] + "'.\nAllowed values are unsigned integers.");

	var dt_date = new Date();
	dt_date.setDate(1);

	if (arr_date[0] < 1 || arr_date[0] > 12) return  ("Invalid month value: '" + arr_date[0] + "'.\nAllowed range is 01-12.");
	dt_date.setMonth(arr_date[0]-1);
	 
	if (arr_date[2] < 100) arr_date[2] = Number(arr_date[2]) + (arr_date[2] < NUM_CENTYEAR ? 2000 : 1900);
	dt_date.setFullYear(arr_date[2]);

	var dt_numdays = new Date(arr_date[2], arr_date[0], 0);
	dt_date.setDate(arr_date[1]);
	if (dt_date.getMonth() != (arr_date[0]-1)) return  ("Invalid day of month value: '" + arr_date[1] + "'.\nAllowed range is 01-"+dt_numdays.getDate()+".");

	return ("")
}

//Trim
function SV_Trim(s) {
	var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
	return (m == null) ? "" : m[1];
}

//Display Message
function SV_DisplayMessage()
{
	//No Errors please return.
	if(this.arrMsg.length==0)
		return true;
	if(!this.ShowAlert)
	{
		first = "<ul>";
		pre = "<li>";
		post = "</li>";
		last = "</ul>";
	}
	else
	{
		first = "\n";
		pre = ">> ";
		post = "\n";
		last = "\n";
	}		
	strMsg = "";
	
	//Clear the old message
	this.target.innerHTML="";
	
	//Create message for span
	for(i=0;i<this.arrMsg.length;i++)
	{
		strMsg += pre + this.arrMsg[i] + post;		
	}
	
	if(this.heading != "")
		strMsg = this.heading + first + strMsg + last;
		
	//Show the message
	if(this.ShowAlert)
		alert(strMsg);
	else
	{
		this.target.innerHTML = strMsg;
		//Go to top of the page.	
		if(this.Scroll)
			window.scrollTo(0,0);
	}
	
	//Clear objects
	this.arrMsg=[];
	this.arrCtl=[];
	this.counter=0;
	this.ShowAlert=true;
	this.Scroll=true;

	return false;
}
				
//Display Error
function SV_error (str_message) {
	alert (str_message);
	return null;
}


