/*
 *	DwaknCMS: PHP/MySQL Content managment system.
 *	http://www.dwakn.com/
 *
 *	Copyright 2004 Dwakn Consulting.
 *
 *	This code cannot be redistributed without permission
 *	from Dwakn Consulting.
 *
 *	$Id$
*/

/* --------------------- Validator --------------------- */

function Validator(formName, errorPreMessage, errorType, outputElement)
{
	var formObject = $(formName);
	if (!formObject) { return; }

	if (formObject.onsubmit)
	{
		this.oldOnSubmit = formObject.onsubmit;
	}
	else
	{
		this.oldOnSubmit = null;
	}

	formObject.onsubmit = SubmitHandler;

	this.AddValidation = AddValidation;
	this.Validators = new Array();
	this.errorPreMessage = errorPreMessage;
	this.outputElement = outputElement;
	this.errorType = errorType;

	formObject.validator = this;
}

function SubmitHandler()
{
	var validator = this.validator;
	if (!validator) { return true; }

	var validators = validator.Validators;

	var error = new Array();
	var erroredElements = new Array();

	for (x = 0; x < validators.length; x++)
	{
		var validatorItem = validators[x];

		if (validatorItem.validate && validatorItem.element && !erroredElements[validatorItem.element.id] && Element.visible(validatorItem.element))
		{
			if (!validatorItem.validate(validatorItem.element, validatorItem.args))
			{
				erroredElements[validatorItem.element.id] = 1;
				error[error.length] = validatorItem.errorMessage;
				Element.addClassName(validatorItem.element, 'errored');

				if (validator.errorType == 'box-below' || validator.errorType == 'below')
				{
					if ($(validatorItem.element.id + '-error'))
					{
						Element.remove(validatorItem.element.id + '-error');
					}

					var element = validatorItem.element;

					for (var e = element.nextSibling; e != null; e = e.nextSibling)
					{
						if (e.nodeType == 3)
							continue;

						if (e.nodeType == 1 && Element.hasClassName(e, 'required'))
						{
							element = e;
						}

						break;
					}

					new Insertion.After(element, '<div id="' + validatorItem.element.id + '-error" class="alert">' + validatorItem.errorMessage + '</div>')
				}

				if (error.length == 1)
				{
					validatorItem.element.focus();
				}
			}
			else
			{
				if ($(validatorItem.element.id + '-error'))
				{
					Element.remove(validatorItem.element.id + '-error');
				}

				Element.removeClassName(validatorItem.element, 'errored');
			}
		}
	}

	if (error.length > 0)
	{
		switch (validator.errorType)
		{
			case 'box':
			case 'box-below':
				if (validator.outputElement)
				{
					var element = $(validator.outputElement);

					if (element)
					{
						var innerHTML = '<div class="messagebad">'

						if (validator.errorPreMessage)
						{
							innerHTML += '<p>' + validator.errorPreMessage + '</p>';
						}

						innerHTML += '<ul>';

						for (x = 0; x < error.length; x++)
						{
							innerHTML += '<li>' + error[x] + '</li>';
						}

						innerHTML += '</ul></div>';

						element.innerHTML = innerHTML;

						break;
					}
				}

			case 'below':
				break;

			case 'alert':
			default:

				var output = validator.errorPreMessage + '\n';

				for (x = 0; x < error.length; x++)
				{
					output += ' - ' + error[x] + '\n';
				}

				alert(output);
				break;
		}

		return false;
	}

	if (validator.oldOnSubmit)
	{
		return validator.oldOnSubmit;
	}
	else
	{
		return true;
	}
}

function AddValidation(elementId, type, args, errorMessage)
{
	this.Validators[this.Validators.length] = new ValidatorItem(elementId, type, args, errorMessage);
}

/* --------------------- ValidatorItem --------------------- */

function ValidatorItem(elementId, type, args, errorMessage)
{
	this.element = $(elementId);
	if (!this.element) { return; }

	switch (type)
	{
		case 'required':
		case 'required-file':
			this.validate = ValidateRequiredField;
			break;
		case 'maxlength':
			this.validate = ValidateMaxLength;
			break;
		case 'minlength':
			this.validate = ValidateMinLength;
			break;
		case 'minlengthoptional':
			this.validate = ValidateMinLengthOptional;
			break;
		case 'minmaxlength':
			this.validate = ValidateMinMaxLength;
			break;
		case 'numeric':
			this.validate = ValidateNumeric;
			break;
		case 'float':
			this.validate = ValidateFloat;
			break;
		case 'email':
			this.validate = ValidateEmail;
			break;
		case 'url':
			this.validate = ValidateUrl;
			break;
		case 'regexp':
			this.validate = ValidateRegexp;
			break;
		case '!regexp':
			this.validate = ValidateNotRegexp;
			break;
		case 'equal':
			this.validate = ValidateEqual;
			break;
		default:
			return;
	}

	this.args = args;
	this.errorMessage = errorMessage;
}


/* --------------------- Validators --------------------- */

function ValidateRequiredField(element, args)
{
	if (eval(element.value.length) == 0)
	{
		return false;
	}
	return true;
}

function ValidateMaxLength(element, args)
{
	if (eval(element.value.length) > eval(args))
	{
		return false;
	}
	return true;
}

function ValidateMinLength(element, args)
{
	if (eval(element.value.length) < eval(args))
	{
		return false;
	}
	return true;
}

function ValidateMinLengthOptional(element, args)
{
	var length = eval(element.value.length)

	if (length > 0 & length < eval(args))
	{
		return false;
	}
	return true;
}

function ValidateNumeric(element, args)
{
	var pos = element.value.search("[^0-9\-\+]");
	if(element.value.length > 0 && pos >= 0)
	{
		return false;
	}
	return true;
}

function ValidateFloat(element, args)
{
	var pos = element.value.search("[^0-9\-\+\.]");
	if(element.value.length > 0 && pos >= 0)
	{
		return false;
	}
	return true;
}

function ValidateRegexp(element, args)
{
    if(!element.value.match(args))
    {
    	return false;
    }
    return true;
}

function ValidateNotRegexp(element, args)
{
    if(element.value.match(args))
    {
    	return false;
    }
    return true;
}

function ValidateEmail(element, args)
{
	if (!element.value)
		return true;

	return ValidateRegexp(element, /^[\w\!\#\$\%\&\'\*\+\-\/\=\?\^_\`\{\|\}\~]+(?:\.[\w\!\#\$\%\&\'\*\+\-\/\=\?\^_\`\{\|\}\~]+)*@(?:[\w-]+\.)+[a-zA-Z]{2,7}$/i);
}

function ValidateUrl(element, args)
{
	if (!element.value)
		return true;

	return ValidateRegexp(element, /^((([hH][tT][tT][pP][sS]?|[fF][tT][pP])\:\/\/)?([\w\.\-]+(\:[\w\.\&%\$\-]+)*@)?((([^\s\(\)\<\>\\\"\.\[\]\,@;:]+)(\.[^\s\(\)\<\>\\\"\.\[\]\,@;:]+)*(\.[a-zA-Z]{2,4}))|((([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])))(\b\:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)\b)?((\/[^\/][\w\.\,\?\'\\\/\+&%\$#\=~_\-@]*)*[^\.\,\?\"\'\(\)\[\]!;<>{}\s\x7F-\xFF])?)$/i);
}

function ValidateEqual(element, args)
{
	var otherElement = $(args);

	if (otherElement)
	{
		var ret = (element.value == otherElement.value);

		if (!ret)
			Element.addClassName(otherElement, 'errored');
		else
			Element.removeClassName(otherElement, 'errored');

		return ret;
	}
	return true;
}
