//////////////////////////////////
// Realtime form validation functions
// for create character / account form.
//
// Some of the form fields get AJAX
// validated.  These fields call validateField()
// on blur.
//
// validateField() does some local validation,
// then adds an AJAX validation request to
// queue.
//
// The queue is processed by tryAjaxCheck().
// It and its child functions (ajaxSuccess()
// and ajaxFail()) display user feedback in
// the *_result elements, and stores
// system status messages in the *_check
// elements.  Possible values of *_check
// are:
//	not_checked
//	ok => valid for form submission
//	checking => AJAX check in progress
//	net_fail => network problem prevented validation
//	val_fail => invalid value in field
// On network problem, tries again 10 times.
// If 10th try fails, gives up and displays
// failure message in *_result.

var ajaxQ = new Array(); // FIFO of ajax requests.
var ajax_checking = false;
var chars = new Object();
chars.uc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
chars.lc = 'abcdefghijklmnopqrstuvwxyz';
chars.num = '01234567890';

// There are a few input fields with similar
// validation rules.  This function handles:
//	email
//	login (user name)
//	name (character name)
function validateField(which)
{
	var val = $('input#'+which).val();
	var err = '';
	var legal_chars = ''; // may only have these characters
	var email = false; // must be email address
	var url = ''; // url of server-side validator
	var max_length = 0;
	var min_length = 0;
	var regex;
	switch (which)
	{
		case 'name': // characer name
			max_length = 16;
			min_length = 2;
			legal_chars = ' '+chars.uc+chars.lc;
			url = 'validate_char_name.php';
			break;
		case 'email':
			max_length = 256;
			min_length = 5;
			email = true;
			url = 'validate_email.php';
			break;
		case 'login': // user name
			max_length = 16;
			min_length = 4;
			legal_chars = ' '+chars.uc+chars.lc+chars.num;
			url = 'validate_login.php';
			break;
		default:
			alert('Touble validating data: do not know what to do with "'+which+'" field.');
	}

	// There are always rules about use of spaces.
	val = val.trim();
	while (val != val.replace('  ', ' '))
	{
		val = val.replace('  ', ' ');
	}

	// Limit to certain characters
	if (legal_chars.length > 0)
	{
		val = val.filter(legal_chars);
	}

	// Must be email address
	if (email)
	{
		regex = /^.+@.+\..+/;
		if (!regex.test(val))
		{
			err = "Please enter a valid email address.";
		}
	}

	// Check length
	if (val.length < 1)
	{
		err = "Please fill in this field.";
	} else if (val.length < min_length
		|| val.length > max_length)
	{
		err = "This must be between "+min_length+" and "+max_length+" characters long.";
	}

	if (err != '')
	{
		// Something's wrong with data.
		$('#'+which+'_result').html('<span class="error">'+err+'</span>');
		$('input#'+which+'_check').val('bad');
		return false;
	} else {
		// value may have been quietly modified.
		$('input#'+which).val(val);

		// Set to "checking" state
		$('#'+which+'_result').html('<span class="grey">Checking...</span>');
		$('input#'+which+'_check').val('checking');

		// queue an ajax check
		var check = {
			'url':url,
			'val':val,
			'which':which,
			'fails':0
			};
		ajaxQ.push(check);
		tryAjaxCheck();
	}
}

function tryAjaxCheck()
{
	if (ajax_checking)
	{
		// Don't want more than one
		// instance running at a time.
		return false;
	}
	if (ajaxQ.length < 1)
	{
		// Nothing to do.
		return false;
	}

	// Process first request in Q
	var current = ajaxQ[0];
	var param = {
		'data':{'val':current.val},
		'error':ajaxFail,
		'success':ajaxSuccess,
		'timeout':10000,
		'type':'POST',
		'url':current.url
		};
	$.ajax(param);
}

function ajaxSuccess(data)
{
	var good = ajaxQ.shift();
	var msg = '';
	var check_val = '';
	if (data == 'ok')
	{
		msg = '<span style="color:green;">Great!  No one is using this one yet.</span>';
		check_val = 'ok';
	} else {
		msg = '<span class="error">'+data+'</span>';
		check_val = 'val_fail';
	}
	$('#'+good.which+'_result').html(msg);
	$('input#'+good.which+'_check').val(check_val);
	ajaxQ.shift();
	tryAjaxCheck();
}

function ajaxFail(request, textStatus, errorThrown)
{
	// Increment error count and
	// add to back of queue.
	var bad = ajaxQ.shift();
	bad.fails++;
	if (bad.fails > 10)
	{
		$('#'+bad.which+'_result').html('<span class="error">Could not reach server to check this.  Are you still connected to the internet?  Please try again later.  Error message was: "'+textStatus+'"</span>');
		$('input#'+bad.which+'_check').val('net_fail');
	} else {
		$('#'+bad.which+'_result').html('<span class="grey">Having trouble talking to server.  Trying again. (Retry #'+bad.fails+')</span>');
		ajaxQ.push(bad);
		$('input#'+bad.which+'_check').val('val_fail');
	}
	tryAjaxCheck();
}





