//<SCRIPT LANGUAGE=javascript>

// set to true to bypass the validator
// do this on a cancel button
var ByPassValidation = false;

var bool_show_error_image = false;
var bool_set_error_in_title = true;

function ValidatorItem(parent, name, title, type, IsReq)
{
	this.Name = name;
	this.Title = title;
	this.Parent = parent;
	this.Type = type;
	this.IsRequired = IsReq;

	this.ErrorImage = document.getElementById(this.Name + '_ErrImage');
	this.TitleBlock = document.getElementById(this.Name + '_Title');

	this.FieldObjectByType = function()
	{
		switch(this.Type)
		{
			case 'mpan':
				return document.forms[this.Parent.FormName][this.Name + '_one'];
				break;
			default:
				return document.forms[this.Parent.FormName][this.Name]
				break;
		}
		return null;
	}

	this.Target = this.FieldObjectByType();

	if(String(this.Target) == 'undefined')
		this.Target == null;

	this.Error = function()
	{
		if(this.Parent.ShowErrorImages && this.ErrorImage != null)
			this.ErrorImage.src = this.Parent.ImageRoot + this.Parent.ErrorImageName;

		if(this.Parent.SetTitleErrorState && this.TitleBlock != null)
			this.TitleBlock.className = this.Parent.ErrorInTitleClass;

		this.Focus();
	}

	this.Reset = function()
	{
		if(this.Parent.ShowErrorImages && this.ErrorImage != null)
			this.ErrorImage.src = this.Parent.ImageRoot + this.Parent.ClearImageName;

		if(this.Parent.SetTitleErrorState && this.TitleBlock != null)
			this.TitleBlock.className = this.Parent.ClearTitleClass;

	}

	this.ValueMissing = function()
	{
		if(this.Target == null) return true;
		return (this.Target.value == '');
	}

	// Return values for 'Validate':
	// 0 - Success
	// 1 - Field not present
	// 2 - Required value missing
	// 3 - Type specific validation failed
	this.Validate = function()
	{
		if(ByPassValidation) return true;

		// check for the field existing
		if(this.Target == null) return 1;

		// check for a required value not be present
		if(this.IsRequired && this.ValueMissing()) return 2;

		// a non required field can be empty
		if(!this.IsRequired && this.ValueMissing()) return 0;

		switch(this.Type)
		{
			case 'any':
				// by this point all fields that can contain any value will have be validated, so always return true [0]
				return 0;
				break;
			case 'mpan':
				var value = '';
				value += document.forms[this.Parent.FormName][this.Name + '_one'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_two'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_three'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_four'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_five'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_six'].value;
				value += document.forms[this.Parent.FormName][this.Name + '_seven'].value;
				if(!value.IsMpan()) return 3;
				return 0;
				break;
			case 'mpr':
				if(!this.Target.value.IsMpr()) return 3;
				return 0;
				break;
			case 'email':
				if(!this.Target.value.IsEmail()) return 3;
				return 0;
				break;
			case 'number':
				if(!this.Target.value.IsNumber()) return 3;
				return 0;
				break;
			case 'telephone':
				if(!this.Target.value.IsPhoneNumber()) return 3;
				return 0;
				break;
			case 'postcode':
				if(!this.Target.value.IsPostcode()) return 3;
				return 0;
				break;
			case 'currency':
				if(!this.Target.value.IsCurrency()) return 3;
				return 0;
				break;
		}
	}

	// return a type specific error message for this field item [i.e. Invalid email address]
	this.ErrorMessage = function()
	{
		switch(this.Type)
		{
			case 'mpan':
				return 'The value for \'' + this.Title + '\' is not a valid Meter Point Administration Number.';
				break;
			case 'mpr':
				return 'The value for \'' + this.Title + '\' is not a valid Meter Point Reference number.';
				break;
			case 'email':
				return 'The value for \'' + this.Title + '\' is not a valid email address.';
				break;
			case 'number':
				return 'The value for \'' + this.Title + '\' is not a number.';
				break;
			case 'telephone':
				return 'The value for \'' + this.Title + '\' is not a telephone/fax number.';
				break;
			case 'postcode':
				return 'The value for \'' + this.Title + '\' is not a postcode.';
				break;
			case 'currency':
				return 'The value for \'' + this.Title + '\' is not a monetary figure.\n\nMust be of the format 12,345 or 12345, without a currency symbol.';
				break;
		}
	}

	this.Focus = function()
	{
		if(this.Target != null)
		{
			// HACK:
			// if the control is hidden or inactive, the focus raises an error
			// however, to check the item is visible+active, the script would bloat. this is quicker
			try
			{
				this.Target.focus();
			}
			catch(e) { }
		}
	}
}

function Validator(name, form)
{
	this.Name = name;
	this.FormName = form;

	this.SubmitID = 'sSubmit';
	this.SubmitSrc = '../images/button-submit-off.gif';
	this.SubmitOffSrc = '../images/button-submit-locked.gif';

	this.ShowErrorImages = bool_show_error_image;
	this.ImageRoot = 'images/';
	this.ErrorImageName = 'reddot.gif';
	this.ClearImageName = 'spacer.gif';

	this.SetTitleErrorState = bool_set_error_in_title;
	this.ErrorInTitleClass = 'error';
	this.ClearTitleClass = '';

	this.Items = new Array();

	this.AddValidationItem = function(name, title, type, IsReq)
	{
		this.Items[this.Items.length] = new ValidatorItem(this, name, title, type, IsReq)
	}

	this.DisableSubmit = function()
	{
		var o_submit = document.getElementById(this.SubmitID);
		if(o_submit != null)
		{
			if(o_submit.getAttribute('type') == 'image')
				o_submit.src = this.SubmitOffSrc;
			o_submit.disabled = true;
		}
	}

	this.EnableSubmit = function()
	{
		var o_submit = document.getElementById(this.SubmitID);
		if(o_submit != null)
		{
			if(o_submit.getAttribute('type') == 'image')
				o_submit.src = this.SubmitSrc;
			o_submit.disabled = false;
		}
	}

	this.Validate = function()
	{
	
		this.DisableSubmit();

		// reset any error messages/images in the form
		for(var i = 0; i < this.Items.length; i ++)
			this.Items[i].Reset();

		for(var i = 0; i < this.Items.length; i ++)
		{
			switch(this.Items[i].Validate())
			{
				case 0: // no error
					// do nothing, so the following fields are checked
					break;
				case 1: // field missing
					alert('The field item for \'' + this.Items[i].Title + '\' is missing!');
					this.EnableSubmit();
					return false;
					break;
				case 2: // value missing
					alert('Please provide a value for \'' + this.Items[i].Title + '\'');
					this.Items[i].Error();
					this.EnableSubmit();
					return false;
					break;
				case 3: // type specific error
					alert(this.Items[i].ErrorMessage());
					this.Items[i].Error();
					this.EnableSubmit();
					return false;
					break;
			}
		}
		return true;
	}
}

function hookSubmitEvents(uid, prefix, b_type)
{
	var o = document.getElementById(uid);
	
	if(o != null)
	{
		o.onmouseover = function()
		{
			if(!this.disabled)
				this.src = prefix + 'images/button-' + b_type + '-over.png';
		}
		o.onmouseout = function()
		{
			if(!this.disabled)
				this.src = prefix + 'images/button-' + b_type + '.png';
		}
	}
}

String.prototype.IsCurrency = IsValidCurrency;
String.prototype.IsEmail = IsValidEmail;
String.prototype.IsPhoneNumber = IsValidPhone;
String.prototype.IsNumber = IsValidNumber;
String.prototype.IsPostcode = IsValidPostcode;
String.prototype.IsMpan = IsValidMpan;
String.prototype.IsMpr = IsValidMpr;

function IsValidCurrency()
{
	if(this.indexOf(',') != -1)
	{
		return /^\-?(\d{1,3}\,)*(\d{3}\,)*(\d{3})(\.\d+)?$/.test(this);
	}
	else
	{
		return /^\-?\d+(\.\d+)?$/.test(this);
	}
}

function IsValidNumber()
{
	return /^\-?\d+(\.{1}\d+)?$/.test(this);
}

function IsValidEmail()
{
	return /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(this);
}

function IsValidPhone()
{
	// remove spaces
	var p = this.replace(/[ ]+/ig, '');
	// test: can have a plus at start.
	// all other characters numeric - (0) allowed for int numbers
	return /^\+?\d+(\(?0?\))?\d{5,}$/.test(p);
}

function IsValidPostcode()
{
	return /^[a-z]{1,2}(\d{1,2}|\d{1}[a-z]{1}) ?\d{1}[a-z]{2}$/i.test(this);
}

function IsValidMpan()
{
	return /^\d{21}$/.test(this);
}

function IsValidMpr()
{
	return /^\d{1,10}$/.test(this);
}