/**
 * Alliance Software Content Management System
 *
 * @copyright Copyright &copy; 2004, Alliance Software
 * No unauthorised use without the express written permission
 * of Alliance Software
 *
 * @package core
 *
 */

//////////////////////////////////////////////////////////////////////////////

var debug = true;
var disableValidation = false;

function isEmpty(x)
{
	return (x === false) ||
			(x === undefined) ||
			(x === null) ||
			(x === '');
}

function isValid(x)
{
	return (x !== null) && (x !== undefined);
}

// Trim leading/trailing spaces from string
String.prototype.trim = function()
{
	return isEmpty(this)
			? ''
			: this.replace(/^\s+|\s+$/g, '');
}

//////////////////////////////////////////////////////////////////////////////
// Validate and do nothing
function nullValidate(field, fieldTitle, params)
{
	return null;
}

//////////////////////////////////////////////////////////////////////////////
// Validate and do nothing
function incompleteValidate(field, fieldTitle, params)
{
	if (debug) alert(fieldTitle + ' has no javascript validation');
	return null;
}

//////////////////////////////////////////////////////////////////////////////
// Validate a floating point number
function floatValidate(field, fieldTitle, params)
{
	var min = params.min;
	var max = params.max;

	// check for a number
	if (!field.value.match(/^-?[0-9]*\.?[0-9]*$/g)) {
		return fieldTitle + ' must be a number';
	}

	// check >= min
	if (isValid(min) && field.value < min) return fieldTitle + ' is too small';

	// check <= max
	if (isValid(max) && field.value > max) return fieldTitle + ' is too large';

	return null;
}

//////////////////////////////////////////////////////////////////////////////
// Valiate an integer
function intValidate(field, fieldTitle, params)
{
	var r = floatValidate(field, fieldTitle, params);
	if (!isEmpty(r)) return r;

	// check for an integer
	if (!field.value.match(/^-?[0-9]+(\.0*)?$/g)) {
		return fieldTitle + ' must be a whole number';
	}

	return null;
}

//////////////////////////////////////////////////////////////////////////////
// Valiate a string
function stringValidate(field, fieldTitle, params)
{
	var size = params.size;
	var regex = params.regex;
	var regexError = (params.regexError) ? String(params.regexError) : '';
	var minSize = params.minSize;

	// min & max size
	if (isValid(minSize) && field.value.length < minSize) {
		return fieldTitle + ' is not long enough';
	}

	if (isValid(size) && field.value.length > size) {
		return fieldTitle + ' is too long';
	}

	// regex
	if (isValid(regex) && !field.value.match(regex)) {
		return fieldTitle + " is not in the correct format\n"
			+ regexError;
	}

	return null;
}

function passwordValidate(field, fieldTitle, params)
{
	return stringValidate(field, fieldTitle, params);
}

//////////////////////////////////////////////////////////////////////////////
function selectValidateSelectAll(field, fieldTitle, params)
{
	for (var i = 0; i < field.options.length; i++) {
		field.options[i].selected = true;
	}
	return null;
}

//////////////////////////////////////////////////////////////////////////////
function checkboxValidateAtLeastOne(field, fieldTitle, params)
{
	var checked = false;
	for (var i = 0; i < field.length; i++) {
		if (field[i].checked) checked = true;
	}
	if (!checked) {
		return fieldTitle + ' must have at least one selected item';
	}	
	return null;
}

//////////////////////////////////////////////////////////////////////////////
// Credit card expiry date validation
function cardExpiryValidate( field, fieldTitle, params) 
{
	// TODO
	return null;	
}

//////////////////////////////////////////////////////////////////////////////
// Form validation object
function FormValidator() {
	this.entries = Array();
		/* The entries array should eventially end up something like this:
		  [
			{	field : document.pageedit.page_name,
				fieldTitle : 'Page name',
				required : false
			},
			{	field : document.pageedit.page_number,
				fieldTitle : 'Page Number',
				validateFunction : intValidate,
				min : 6,
				max : 7,
				required : true
			}

		  ]
		*/
}

function FormValidator_addEntry(newEntry) {
	var id = newEntry['field'].id;
	if (id == undefined) {
		id = this.entries.length;
	}
	this.entries[id] = newEntry;
}

function FormValidator_validate() {
	if (disableValidation) return true;
	for (var index in this.entries) {
		// get entry and some properties
		var entry = this.entries[index];
		if (typeof entry == "function") continue;
		var field = entry.field;

		// ---- dont validate display:none fields ----
		// Only occurrs if jquery present
		if (typeof(jQuery) !== 'undefined') {
			// TODO: a non-jquery version of this
			var visible = true;
			$(field).parents().each(function() {
				if ('none' == $(this).css('display')) {
					visible = false;
				}
			});
			if (!visible) continue;
		}
		// -------------------------------------------

		var fieldTitle = entry.fieldTitle;
		var validateFunction = entry.validateFunction;
		
		// remove spaces
		if (typeof field == "object") {
			field.value = field.value.trim();
			
			var err = '';
			// precheck for empty fields (makes validation easier)
			if (isEmpty(field.value) && entry.required !== null) {
				if (entry.required) {
					err = (fieldTitle + ' must contain a value');
				}
			
			// validate the field
			} else {
				if (!isEmpty(validateFunction)) {
					err = validateFunction(field, fieldTitle, entry);
				}
			}

			// if we got an error, display it
			if (!isEmpty(err)) {
				alert('Error: ' + err);
				// set focus to the error field
				field.focus();
				return false;
			}
			
		} else if (typeof field == "function") {
			
			var err = '';
			
			// multiple checkboxes that go into an array fall here
			if (!isEmpty(validateFunction)) {
				err = validateFunction(field, fieldTitle, entry);
			}
			
			// if we got an error, display it
			if (!isEmpty(err)) {
				alert('Error: ' + err);
				// set focus to the error field
				field[0].focus();
				return false;
			}
		} else {
			if (debug) alert('Field ' + fieldTitle + ' not found');
		}
	}
	return true;
}


new FormValidator();
FormValidator.prototype.validate = FormValidator_validate;
FormValidator.prototype.addEntry = FormValidator_addEntry;

//////////////////////////////////////////////////////////////////////////////

function checkForm(formname)
{
	return eval('document.forms.' + formname + '.validator.validate()');
}

//////////////////////////////////////////////////////////////////////////////
// Move selected element value from <select> to text box
function moveSelectValue(form, selectFrom, textTo)
{
	from = form.elements[selectFrom];	
	if (from.options.length > 0 && from.selectedIndex >= 0) {
		form.elements[textTo].value = from.options[from.selectedIndex].value;
	}
}

//////////////////////////////////////////////////////////////////////////////
// Move highlighted elements in a <select> to another <select>
function moveSelectElements(form, selectFrom, selectTo)
{
	from = form.elements[selectFrom];
	to = form.elements[selectTo];

	while (from.selectedIndex >= 0) {
		if (from.options.length > 0) {
			for (var i = 0; i < from.options.length; i++) {
				while (i < from.options.length && from.options[i].selected == true) {
					var o = new Option(from.options[i].text, from.options[i].value, false, false);
					to.options[to.options.length] = o;
					from.options[i] = null;
				}
			}
		}
	}

	sortOptions(to);
}

// Sort the options in a select
function sortOptions(select)
{
	// copy out the options
	var options = new Array();
	for (var i = 0; i < select.options.length; i++) {
        options[i] = {
			'text' : select[i].text,
			'value' : select[i].value
			};
	}

	// sort
	options.sort(function(a,b) {
			if (a.text < b.text) return -1;
			if (a.text > b.text) return +1;
			return 0;
		});

	// remove old options
	while (select.options.length) select.options[0] = null;

	// insert new options back in
	for (var i = 0; i < options.length; i++) {
		var o = new Option(
					options[i].text,
					options[i].value,
					false,
					false);
		select.options[select.options.length] = o;
	}
}

//////////////////////////////////////////////////////////////////////////////

