/**
 * @author Walter Wimberly
 * @version .9.1
 * @fileoverview
 * <p>Each of the test methods returns Boolean true if the test passes and the
 * error message if it fails. </p>
 * <p>Updated some minor bugs, which was causing minval to not work.</p>
 */
var sLanguage = 'en';
var submitElem = null;  //assigned during initialization
var submitDefaultValue = '';  //assigned during initialization
var messageFormat = 'inline';  //acceptable options are 'popup', 'inline', 'alert'


/**.
 * @type JSON
 * @private
 *
 * Hint and error messages. English only! These messages are used inside updateMessageBox()
 * They are display in the hints divs.
 */
var jsonMessages = 
{
        'loginHint': {
                'regex': 'Must be 5 to 16 alphanumeric characters.',
                'checklogin': 'This user name already exists. Contact the support if you own an account of the same name in one of our partner casinos.'
        },
        'password1Hint': {
                'pwstrength': 'Please choose strong password.'
        },
        'password2Hint': {
                'required': 'This field is required.',
                'matches': 'Passwords must match.'
        },
        'emailHint': {
                'email': 'Please enter valid email address.',
                'checkemail': 'This email is used by another user already. Contact the support if the email belongs to you.'
        },
        'addressStreetHint': {
                'required': 'May be up to 90 characters.'
        },
        'addressCityHint': {
                'required': 'May be up to 20 characters.'
        },
        'addressZipHint': {
                'zipcode': 'Please enter your ZIP code.'
        },
        'addressStateHint': {},
        'addressCountryHint': {},
        'firstNameHint': {
                'required': 'May be up to 20 characters.'
        },
        'lastNameHint': {
                'required': 'May be up to 20 characters.'
        },
        'birthdateHint': {
                'iseighteen': 'You must be at least 18 years old.',
                'regex': 'Please enter valid year.'
        },

        'phoneHint': {
                'regex': 'Must begin with + followed by your country\'s dialing code. Please use numbers only. Example: +421911703780'
        },
        'websiteHint': {
                'regex': 'Please enter valid URL address of your website.'
        },
        'userAgreementHint': {
                'requiredcheck': 'You must check this box to continue.'
        },
        'subjectHint': {
                'required': 'Please fill out the subject.'
        },
        'messageToSupportHint': {
                'required': 'Your message must not be empty.'
        },
        'captchaCodeHint': {
                'required': 'Enter the security code from the picture.'
        },
        'dateHint': {
                'regex': 'Enter date as YYYY/mm/dd'
        },
        'payeeNameHint': {
                'required': 'Please fill out the account holder\'s name.'
        },
        'bankNameHint': {
                'required': 'Please fill out the bank name.'
        },
        'bankSwiftCodeHint': {
                'required': 'Please fill out bank\'s SWIFT code.'
        },
        'accountIbanCodeHint': {
                'required': 'Please fill out your IBAN number.'
        },
        'moneybookersEmailHint': {
                'email': 'Please enter valid email address.'
        }
};
 
 /**
  * @type Array
  * @private
  * Language strings
  */
var aLangStringsMaster = ['This field is required.', 'Please enter a valid email address.', 'Please enter a valid zip code.', 'Please enter a valid value.', 'The field is too long. It can only be up to ', ' characters long. You currently have ', ' characters.', 'The field must match ', 'Please check the form for errors', 'This user name already exists. Contact the support if you own an account of the same name in one of our partner casinos.', 'This email is used by another user already. Contact the support if the email belongs to you.', 'Please wait...'];
var aLangStrings = new Array();
switch(sLanguage) {
    case 'sk':
        aLangStrings = ['Tento údaj je povinný.', 'Zadajte prosím platnú emailovú adresu.', 'Zadajte prosím platné PSČ.', 'Zadajte prosím platnú hodnotu.', 'Príliš dlhá hodnota. Sem môžete zadať najviac ', ' znakov. Momentálne je zadaných ', ' znakov.', 'Musí sa zhodovať s ', 'Skontrolujte prosím zadané údaje', 'Užívateľ s týmto menom už existuje. Ak vlastníte účet s týmto menom v niektorom z našich partnerských kasín, kontaktujte zákaznícku podporu.', 'Túto emailovú adresu už používa iný užívateľ. Ak email patrí vám, kontaktujte zákaznícku podporu.', 'Prosím čakajte...'];
        break;
    case 'en':
    default:
        aLangStrings = [];
}

function text(str) {
    var index = aLangStringsMaster.indexOf(str);
    var sTranslatedStr =  aLangStrings[index];
    if(sTranslatedStr) {
        return sTranslatedStr;
	} else {
		return str;
	}
}

/**
 * @type Array
 * @private
 * <p>A String array of the methods which can be checked against.</p>
 */
var validatorAttributes = ["autotrim", "required", "email", "maxlen", "maxval",
		"minlen", "minval", "notfirst", "maxwords", "usphone", "zipcode",
		"uscurrency", "ssn", "time", "usdate", "internationaldate",
		"alphanumeric", "numeric", "alpha", "regex", "matches",
		"numgt", "numgte", "iseighteen", "allowstatus", "checklogin", "checkemail", 
                "pwstrength", "requiredcheck"];
/**
 * @type Array
 * @private
 * <p>An array of functions which can be checked against.</p>
 */
var validatorFunctions = [autotrim, required, email, maxlen, maxval,
		minlen, minval, notfirst, maxwords, usphone, zipcode,
		uscurrency, ssn, time, usdate, internationaldate,
		alphanumeric, numeric, alpha, regex, matches,
		numgt, numgte, iseighteen, allowstatus, checklogin, checkemail, 
                pwstrength, requiredcheck];

/**
 * @type	Boolean
 * <p>Used to determine if we are currently checking the form to submit,
 * or not.</p>
 */
var formCheck = false;


/**
 * <p>Call this function after a the form(s) have been loaded and the
 * appropriate tests will be attached to the onblur method of the form
 * element.</p>
 * @method
 */
function initializeValidator() {
	var lstForm = document.getElementsByTagName('form');
	var msg;

	for(i = 0; i < lstForm.length; i++) {
		cn = lstForm[i].elements;	// get all of the elements in the form
		for(j=0; j < cn.length; j++) {
			for(k=0; k < validatorAttributes.length; k++) {
				if(cn[j].getAttribute(validatorAttributes[k])) {
					if (validatorAttributes[k] == 'required') {
						defineRequired(cn[j].getAttribute('id'));
					}
					/*if(validatorAttributes[k] == 'allowstatus') {
                        submitElem = cn[j];
                        submitDefaultValue = submitElem.value;
                        //disable the submit button
                        //submitElem.disabled = true;  //doesn't work in FF 3.0!
                        submitElem.attr('disabled', true);
                    }*/
					myAttachEvent(cn[j], 'blur', validatorFunctions[k]);
				}
			}
		}
		if(submitDefaultValue == '') {
            var thisSubmitElem = $('[allowstatus]', lstForm[i]);
            thisSubmitElem.attr('defaultText', thisSubmitElem.text());
            //submitElem.attr('disabled', true);
            switchSubmit(thisSubmitElem, 0);
        }
        
        //bind custom submit function
        $('#' + lstForm[i].id).submit(function() {
            //todo: check all fields
            if(!validatorCheckForm(this)) {
                switchSubmit($('[allowstatus]', this), 0);
                return false;
            }
            button = $('button[type="submit"]', this);
            button.attr('disabled', true);
            var overlayContent = '<div>' + text('Please wait...') + '</div>';
            //$().show();  //display message
            //$('body').wrap('<div/>').parent().css('opacity',0.5);
            // clear out plugin default styling 
            $.blockUI.defaults.css = {};
            $.blockUI({
                message: overlayContent,
                /*css: {
                    border: 'none',
                    padding: '15px',
                    backgroundColor: '#000',
                    '-webkit-border-radius': '10px',
                    '-moz-border-radius': '10px',
                    opacity: '.5',
                    color: '#FFF'
                }*/
                css: {}
            });
            
            return true;
        }); //*/
        
	}
	//switchSubmit();
}

/**
 * <p>If the input is required, then apply the CSS style of the same
 * 	name to the associated label tag.  Additionally, a star (*) will
 * 	be inserted before the text of the label to visually identify
 * 	that the tag will be required.</p>
 * <p>This function is called during the initialization function
 * 	call, if that method is called.  If the checked element is not
 * 	implicitly stated as required, this function will not be
 * 	called. So tags that use attributes like minlen, and minwords
 * 	would need to have required added as well as an attribute to
 * 	take advantage of this feature.</p>
 * @see #initializeValidation
 * @param {String} id	The id of the DOM Object which needs to
 * 				checked to see if a label applies, in which to make
 * 				it required.
 *
 */
function defineRequired(id) {
	var lstLabels = document.getElementsByTagName('label');
	for(n=0; n < lstLabels.length; n++) {
		if(lstLabels[n].htmlFor == id) {
			// add a CSS class to the label
			addClassToElement(lstLabels[n], 'required');
			// add a star to the front of the label text
			//lstLabels[n].innerHTML = "<span class=\"requiredText\">* required</span> " + lstLabels[n].innerHTML;
			break;
		}
	}
}

/**
 * <p>This function adds a CSS class to a given DOM object. By
 * 	generating this method, a more centralized way of managing this
 * 	process can occur.</p>
 * <p>If a given element already has a CSS style attached to it,
 * 	this function will ensure that the original style is kept,
 * 	and the new style is appended.  If the element already has
 * 	the same style attached, nothing will happen. If no class has
 * 	been assigned to this element, then the class name applied will
 * 	be the only class assigned to the tag.</p>
 * @param {DOMObject} element	DOM Object that is supposed to
 * 		have a CSS element attached to it.
 * @param {String} classname	String representing the name of
 * 		the CSS class to be applied to the element
 */
function addClassToElement(element, classname) {
	if(!element) {
		return;
	}
	if( element.className === '' || element.className === null) {
		element.className = classname;
	} else if (element.className.indexOf(classname) == -1 ) {
		element.className += ' ' + classname;
	}
}

/**
 * @method
 * @param {Object} frm	The form to be called.
 * <p>This method will validate the form when it is submitted, if it is
 * manually placed in the onsubmit method.</p>
 * <p><strong>Example:</strong> <br />
 * <form .... onsubmit="return checkForm(this);"></p>
 * <p>This will check the form before it is submitted.  Because <em>return</em>
 * is used, if checkForm returns false, then it will not submit the form
 * requiring the user to fix the errors before proceding.</p>
 * <p>This can also be attached to an onclick method of a button with
 * some minor code tweaks to allow the user to confirm the correct data/
 * type of data had been entered.  Should be unnecessary since the form
 * is giving instaneous feedback as the form is being filled out.</p>
 * @type	Boolean
 * @throws  NullPointerException
 * @return	Returns true if the form passed all of the error checks, false
 * 		if it failed any of the checks.
 */
function validatorCheckForm(frm) {
	if (frm === null ) {
		throw("NullPointerException: A valid form must be passed to " +
			"the Check Form function.");
	}
	formCheck = true;	// set the formCheck value to true so error checking
						// knows how to handle the pop-up display information
	var cn = frm.elements;	// get all of the elements in the form
	// Used to keep a running tally of the error message which form checking.
	var alertMsg = '';

	for(j=0; j < cn.length; j++) {
		for(k=0; k < validatorAttributes.length; k++) {
			if(cn[j].getAttribute(validatorAttributes[k])) {

				// check the form element
//				if(cn[j].getAttribute('required') !== null ) {
					// build the alert message.
					temp = validatorFunctions[k](cn[j]);

					if(temp !== '') {
						alertMsg += temp + "\n";
					}
//				}

			}
		}
	}

	formCheck = false;	// release the form checking flag
	if(alertMsg !== '') {
		// if there was a message - an error occured, and it will be
		// displayed
		//alertMsg = 'There were errors processing the form:\n\n' + alertMsg;
		//alert(alertMsg);
		//alertMsg = '';
		// don't let the person progress past this point because of the error
		return false;
	} else {
		// no errors, so return true and let the person submit the form.
		return true;
	}
}

/**
 * <p><strong>Error Information</strong><br />
 * This method only needs to be called from the other included
 * functions, however it is important enough to note here as it yeilds
 * information on how the error messages and classes are handled.</p>
 * <p>Displays the error based upon the status of the error checking.
 * If frmCheck is set to true, no pop-ups are displayed.</p>
 * <p>Error messages can come from several sources:</p>
 * <ul>
 * 	<li><strong>Error Specific Message:</strong> If you want define an
 * 		error message for a given element, and you want it to be for a
 * 		spefic type of error create an attribute on the element to be
 * 		used such as <em>requirederrmsg</em>. This can be broken down to
 * 		"required error message".  If the required attribute is present
 * 		and requirederrmsg is also present, then the contents of the
 * 		requirederrmsg attribute will be displayed for this	error
 * 		message, but only for that error.  So if additional errors are
 * 		present on the form element, then they can get different error
 * 		messages.</li>
 * 	<li><strong>Tag Specific Message:</strong> The same error message
 * 		can be used regardless of the error generating it.  This message
 * 		can be displayed using the <em>errmsg</em> attribute.  What ever
 * 		the value within the errmsg attribute, will be displayed for that
 * 		form element, if there are any errors.  If their are multiple
 * 		errors the error message will be displayed multiple times, unless
 * 		an Error Specific Message attribute was used for the other
 * 		potential errors.</li>
 * 	<li><strong>Generic Error Message:</strong> When no Error Specific
 * 		Tag Message, or Tag Specific Error Message can be determined, a
 * 		generic error message can be used to generate an error.</li>
 * </ul>
 * <p><strong>Pop-Up Information</strong><br />
 * 	Additionally, you can set the <strong>popup</strong> attribute
 * 	(ex.: popop="only").  By doing so, when an error on that form field
 * 	occurs, it will cause the error message to display in a pop-up window.
 * 	<br />Legal values for the popup attribute are: only and both.  If
 * 	<em>both</em> is set, the error message will be displayed in both
 * 	the pop-up window, and an error box below the form element.  If
 * 	the value <em>only</em> is set, only the pop-up window gets the error
 * 	message.  This is a <em>per field</em> attribute setting.</p>
 * <p><strong>CSS Style Information</strong><br />
 * 	Two CSS classes are used for defining error messages.  You can
 * 	include	the external CSS file provided, make changes, etc. The
 * 	classes are <strong>.errMsg</strong> and .<strong>errElem</strong>.
 * 	errMsg is used to display the error message box.  errElem is for the
 * 	form element with the error.  If these are not available, or made to
 * 	be blank, then the element recieving these classes will have no
 *  additional style attached.  The errElem is smartly applied and
 *  removed so it will not effect any additional styles that have been
 *  applied, unless it directly effects an associated attribute.</p>
 * @private
 * @method
 * @param {Event} elem - which element is getting the error message
 * @param {String} errType - what type of error - important for
 * 		generating unique sections to hold the ID
 * @param {String} msg - the default error message.
 * @type	String
 * @return	Returns the error message os it can be captured by the
 * calling method.
 */
function displayError(elem, errType, msg) {
    if(errType == 'iseighteen') {
            elem = document.getElementById('birthYear');
            //console.log(elem.attr('id'));
    }
    var id = elem.getAttribute('id');
	var idErrName = id + "_" + errType + "_err";
	var container = null;
	var errorBtn = null;
	var txt = '';

	if(elem.getAttribute(errType + 'errmsg') !== null ) {
		msg = elem.getAttribute(errType + 'errmsg');
	} else if(elem.getAttribute('errmsg') !== null ) {
		msg = elem.getAttribute('errmsg');
	}
	
	if(messageFormat == 'popup') {
		if(document.getElementById(idErrName) && elem.getAttribute('popup') != 'only') {
			container = document.getElementById(idErrName);
			if(msg != container.firstChild.innerText) {
				container.innerHTML = msg;
			}
		} else if(elem.getAttribute('popup') != 'only') {
			//create an error button (i)
			$(elem).after('<div id="' + idErrName + '_btn" class="errorButton"><div></div></div>');
			$('#' + idErrName + '_btn').click(function() {
		    		$('#' + idErrName).show('slow');
			});
		
			//remove ok button
			$('#' + id + '_ok_btn').remove();
		
			//create the message box
			container = document.createElement('div');
			txt = document.createTextNode(msg);
			container.appendChild(txt);
			container.setAttribute('id', idErrName);
			$(container).hide();
			if(!document.getElementById(idErrName)) {
				//elem.parentNode.insertBefore(container,elem.nextSibling);
				     $('#' + idErrName + '_btn').after(container);
			}
			document.getElementById(idErrName).className = 'errMsg';
		}
	} else if(messageFormat == 'inline') {
		// remove the ok icon
		$('#' + id + '_ok_btn').remove();
		//create the error icon
                //do not attach the icon if this is checkbox
                if(errType != 'requiredcheck') {
        		$(elem).after('<div id="' + idErrName + '_btn" class="errorIcon"><div></div></div>');
                }
		// update the message box
		var msgBoxId = id + 'Hint';
		var msgClass = 'errHint';
		updateMessageBox(msgBoxId, msg, msgClass, errType);
	}
	
	//disable the submit button
	var form = $(elem).parents('form').get(0);
	var submitBtn = $('[allowstatus]', form);
    	switchSubmit(submitBtn, 0);

	if((elem.getAttribute('popup') == 'only' || elem.getAttribute('popup') == 'both') && !formCheck) {
		alert(msg);
	}

	//remove ok class from the element
	$(elem).removeClass('okElem');
	//add error class to the element
	//addClassToElement(elem, 'errElem');
	$(elem).addClass('errElem');
	$('#' + idErrName).click(function() {
            $(this).hide("slow");
    });

	return msg;
}

/**
 * Update (removed: contents of the) message box and its class.
 * Messages are pulled from the jsonMessages object.
 *
 * @param string msgBoxId DOM id
 * @param string msg Contents of the message
 * @param string className Either 'errHint' or 'okHint' or 'neutralHint'
 * @param string errType
 */
function updateMessageBox(msgBoxId, msg, className, errType) {
        // birthDay, birthMonth and birthYear all use the same message box
        if(msgBoxId == 'birthDayHint' ||
           msgBoxId == 'birthMonthHint' ||
           msgBoxId == 'birthYearHint'
          ) {
                msgBoxId = 'birthdateHint';
        }
	$('#' + msgBoxId).removeClass();
	$('#' + msgBoxId).addClass(className);

        if(msg == '') {
                $('#' + msgBoxId).text('');
                $('#' + msgBoxId).css('visibility', 'hidden');
        } else {
                //var objId = $('#' + msgBoxId);
                msg = jsonMessages[msgBoxId][errType];
                $('#' + msgBoxId).text(msg);
                $('#' + msgBoxId).css('visibility', 'visible');
        }

        //$('#' + msgBoxId).text(msg);
        /*if(msg == '') {
                //hide message, dont delete it
                $('#' + msgBoxId).css('visibility', 'hidden');
        } else {
                $('#' + msgBoxId).css('visibility', 'visible');
        }*/

	return;
}

/**
 * <p>If the error has been resolved, it will remove the error node and
 * reset any styles.</p>
 * @private
 * @param {DOMObject} elem
 * @param {String} errType
 */
function removeErrorNode(elem, errType) {
        
    if(errType == 'iseighteen') {
            elem = document.getElementById('birthYear');
            //console.log(elem.attr('id'));
    }
	id = elem.getAttribute('id');
	idErrName = id + "_" + errType + "_err";
	var parent = null;

	// remove the error message node
	if(document.getElementById(idErrName)) {
		parent = document.getElementById(idErrName).parentNode;
		parent.removeChild(document.getElementById(idErrName));
	}

	//remove the error button
	//var errorBtn = $('#'+idErrName+'_btn').remove();
        var errorBtn = $('div.errorIcon[id^="' + idErrName +  '_btn"]').remove();

	
	if($('#' + id + ' ~ div.errorButton').length == 0 &&
		//$('#' + id + ' ~ div.errorIcon').length == 0 ) {
		$('div.errorIcon[id^="' + id +  '"]').length == 0 ) {
		//update the message box if applicable
		if(messageFormat == 'inline') {
			var msgBoxId = id + 'Hint';
			var msg = '';  //todo: read ok message from the elements attribute
                        var msgClass = 'okHint';
			updateMessageBox(msgBoxId, msg, msgClass);
		}

		// remove the error class from the element
		// dont do this if there is still some errorButton left for this element
		$(elem).removeClass('errElem');
		
		// add ok button. Remove any ok button assigned to this field previously.
		// only if there are no other error buttons for this element
                // dont mess with buttons if this is checkbox
                if(errType != 'requiredcheck') {
                        $('#' + id + '_ok_btn').remove();
                        if(messageFormat == 'popup') {
				$(elem).after('<div id="' + id + '_ok_btn" class="okButton"><div></div></div>');
                        } else if(messageFormat == 'inline') {
                                $(elem).after('<div id="' + id + '_ok_btn" class="okIcon"><div></div></div>');
                        }
                        $(elem).addClass('okElem');
                }
	}

	//enable the submit button
	//console.log('remove '+errType);
	var form = $(elem).parents('form').get(0);
	var submitBtn = $('[allowstatus]', form);
    switchSubmit(submitBtn);
}


/**
 * <p>Attached a function to an event for a given object.  Checks to make
 * sure it can be done for different browsers.</p>
 * <p>This presents a unified method of adding the function as the event
 * handler, and abstracts this level so the same code is not repeated over and over.</p>
 * @private
 * @param {DOMObject} obj
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @param {Function} func
 * @type Boolean
 * @return returns if the event was successfully added to the handler
 * or not
 */
function myAttachEvent(obj,evt,func){
	var ret = false;
	if (obj.addEventListener){
		obj.addEventListener(evt,func,false);
		ret = true;
	} else if (obj.attachEvent) {
		ret = obj.attachEvent("on"+evt,func);
	}
	return ret;
}

/**
 * <p>Trims unnecessary white space around the text within the element.
 * This is a private method that should not be needed except by other
 * functions within this library.</p>
 * @param {String} inString
 * @type	String
 * @return	Returns a trimed version of the string (without whitespace to as a
 * prefix or suffix to the string contents).
 */
function trim(inString) {
	if(inString !== '' && inString.replace) {
		// check to make sure there is a string, and that the string object
		// has the replace command.
		inString = inString.replace( /^\s+/g, "" );// strip leading white space
		inString = inString.replace( /\s+$/g, "" );// strip trailing white space
	}
	return inString;
}


/**
 * <p>Convert the humpBack notation into English readable for determining
 * form element names.</p>
 * @private
 * @param {String} inString	The string which should be "fixed" to convert from hump
 * 		notation, or under_scored notation, into regular words for displaying error messages.
 * @type String
 * @return	Readable format of the string that was passed to the method
 */
function fixNaming(inString) {
	if(inString !== '') {
		rExp = /[A-Z]/g;
		inString = inString.replace(rExp,  ' $&' );

		rExp = /[-_]/g;
		inString = inString.replace(rExp,  ' ' );
		inString = inString.substr(0,1).toUpperCase() + inString.substr(1, inString.length - 1);
	}
	return trim(inString);
}

/**
 * <p>Determine the target.  If a Form element is passed, it is returned, if an
 * Event is passed, the element that sent the event is returned, if nothing
 * is passed (IE) then we get the last event, and determine which element
 * generated that event.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * 		In some cases, this may also be the object itself.  The method will handle this
 * 		discrepancy.
 * @type	DOMObject
 * @return	The form element that is to be checked.
 */
function getTarget(evt) {
	var element;
	if(evt.getAttribute && document.getElementById(evt.getAttribute('id')) == evt) {
		element = evt;
	} else {
		if (!evt) {
			evt = window.event;
		}

		if (evt.target) {
			element = evt.target;
		} else if (evt.srcElement) {
			element = evt.srcElement;
		}

                if(element === undefined && evt) {
                        element = evt;
                }

		if (element.nodeType == 3) {
			// defeat Safari bug
			element = elem.parentNode;
		}
	}
	return element;
}

/**
 * <p>Determine if there was a match with the regular expression and the
 * string.</p>
 * @param {String} string	The value that is to be checked against a
 * regualr expression.
 * @param {String} regEx	The regular expression that we will used
 * @type	Boolean
 * @return	Returns true if there was a match with the regular
 * 		expression, false if there was no match.
 */
function meetsRegEx(string, regEx) {
       // console.log('string:'+string + '\nregex'+regEx);
	var re = new RegExp(regEx);
	var m = re.test(string);
    //console.log(m);
    return m;
	//return (m !== null);
}

/**
 * <p>If we want the form element to auto trim the white space, we can
 * set this attribute.  Does not generate any error message - so safe for
 * error checking if it is not a required field.
 * <em>ex.: autotrim="autotrim"</em></p>
 * <p>This method is good for eliminating unwanted spaced before usernames,
 * passwords, and other fields which could eventually cause a problem if
 * looking for a match.</p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * 		function to be called.
 */
function autotrim(evt) {
	var elem = getTarget(evt);
	elem.value = trim(elem.value);
}

/**
 * <p>This element cannot be left blank. <em>example: required="true"</em></p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * 		function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function required(evt) {
	var elem = getTarget(evt);

	if(trim(elem.value) === '') {
		return displayError(elem, 'required', text('This field is required.'));
	} else {
		removeErrorNode(elem, 'required');
		return '';
	}
}

/**
 * This checkbox element must be checked
 */
function requiredcheck(evt) {
        var elem = getTarget(evt);

        if(!elem.checked) {
		return displayError(elem, 'requiredcheck', text('You must check this box.'));
        } else {
		removeErrorNode(elem, 'requiredcheck');
                return '';
        }
}

/**
 * <p>This element must be a standard valid e-mail address.
 * <em>ex.: email="email"</em></p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function email(evt) {
	var elem = getTarget(evt);
	var reg = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'email', text('Please enter a valid email address.'));
	} else {
		removeErrorNode(elem, 'email');
		return '';
	}
}

/**
 * <p>This element cannot have more than the number of charcters that the
 * attribute value specifies. <em>ex.: maxlen="300"</em></p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function maxlen(evt) {
	var elem = getTarget(evt);

	if(elem.value.length > elem.getAttribute('maxlen')) {
		return displayError(elem, 'maxlen', text('The field is too long. It can only be up to ') +
			$(elem).attr('maxlen') + text(' characters long. You currently have ') +
			elem.value.length + text(' characters.'));
	} else {
		removeErrorNode(elem, 'maxlen');
		return '';
	}
}

/**
 * <p>Called if this form element cannot be above the value specified
 * within the value of the attribute. <em>ex.: maxval="300"</em> - then
 * the contents of the text box cannot have a numeric value of over
 * 300.</p>
 * <p>Additionally, the value in the textbox must consist of only
 * numbers. The numeric function is automatically called with this
 * function. This should make writting the attributes a little simpler.
 * However, a value does not have to entered.  So if the field is
 * manditory, then it should have an attribute of <em>required</em>
 * as well.</p>
 * @see #numeric
 * @see #required
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function maxval(evt) {
	// ensure that the form element is also numeric
	numeric(evt);
	var elem = getTarget(evt);

	if(parseFloat(elem.value) > parseFloat(elem.getAttribute('maxval'))) {
		return displayError(elem, 'maxval', 'The field ' + fixNaming(elem.name) + ' is too large a number. ' +
			'It can only have a maximum value of ' + elem.getAttribute('maxval') +
			'. It is currently ' + elem.value + '.');
	} else {
		removeErrorNode(elem, 'maxval');
		return '';
	}
}

/**
 * <p>This element must be at least n characters long as specified by the
 * attribute value.  <em>ex.: minlen="6"</em></p>
 * <p>This attribute is good to use when you want to ensure a certain
 * field, like a password is over a given length to make it more difficult
 * to guess.</p>
 * <p>This has a similar effect to required, with the added bonus of
 * ensuring that the field has a length over the specified number. If
 * you wanted to use it as/instead of the required attribute, you could
 * specify: <em>minlen="1"</em>.</p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * 		function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 * @see #required
 */
function minlen(e) {
	// call required as it is assumed at this point.
	var elem = getTarget(e);

	if(elem.value.length < elem.getAttribute('minlen')) {
		displayError(elem, 'minlen', 'The field ' + fixNaming(elem.name) + ' is not long enough. It must be at least ' +
			elem.getAttribute('minlen') + ' characters long. You currently have ' +
			elem.value.length + ' characters');
		return false;
	} else {
		removeErrorNode(elem, 'minlen');
		return '';
	}

}

/**
 * <p>The value of this form element cannot be below the value specified
 * within the value of the attribute. <em>ex.: minval="300"</em> - then
 * the contents of the text box cannot have a numeric value less than
 * 300.</p>
 * <p>Additionally, the value in the textbox must consist of only
 * numbers. The numeric function is automatically called with this
 * function. This should make writting the attributes a little simpler.
 * However, a value does not have to entered.  So if the field is
 * manditory, then it should have an attribute of <em>required</em>
 * as well.</p>
 * @see #numeric
 * @see #required
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function minval(evt) {
	var elem = getTarget(evt);
	var str;

	if(isNaN(parseFloat(elem.value)) ) {
		str = 'The field ' + fixNaming(elem.name) + ' does not appear to even be a number!';
		return displayError(elem, 'minval', str);
	} else if( parseFloat(elem.value) < parseFloat(elem.getAttribute('minval'))) {
		str = 'The field ' + fixNaming(elem.name) + ' does not have a large enough value. ' +
			'It must have a minumum value of at least ' + elem.getAttribute('minval') +
			'. It is currently ' + elem.value + '.'

		return displayError(elem, 'minval', str);
	} else {
		removeErrorNode(elem, 'minval');
		return '';
	}
}

/**
 * <p>Called if this form element, a drop down element or a list box,
 * is not the first element as the selected element.
 * <em>ex.: notfirst="notfirst"</em></p>
 * <p>This attribute is only effective for llist boxes and drop-down
 * menus.  (i.e. the select tag)</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function notfirst(evt) {
	var elem = getTarget(evt);
	if (elem.selectedIndex === 0) {
		return displayError(elem, 'notfirst', 'Please pick something other than the first choice.');
	} else {
		removeErrorNode(elem, 'notfirst');
		return '';
	}
}

/**
 * <p>Called if this form element cannot have more than a certain number
 * of words.  Sites requiring short answers, interview questions, etc would
 * benifit from it availablity.  <em>ex.: maxwords="250"</em> would keep
 * any response more than 250 from progressing through.</p>
 * <p>Words are specified by being seperated with a space.  Words
 * seperated with new line characters, commas, and other values not
 * associated with a space, will not be counted with this version.
 * Future updates might allow for those functions to take place.</p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * 		function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function maxwords(evt) {
	var elem = getTarget(evt);

	var arr = elem.value.split(' ');
	var wordCnt = arr.length;
	if(wordCnt > elem.getAttribute('maxwords')) {
		return displayError(elem, 'maxwords', 'The field ' + fixNaming(elem.name) + ' has too many words. ' +
			'You shouldn\'t have more than ' + elem.getAttribute('maxwords') +
			' words. You have ' + wordCnt + ' words.');
	} else {
		removeErrorNode(elem, 'maxwords');
		return '';
	}
}

/**
 * <p>Called if this form element is supposed to be a standard 10 digit
 * US phone number (area code plus phone number).  It will accept numbers
 * and seperators only, so vanity phone numbers ex.: (800) my-teeth, will
 * not validate.
 * <em>ex.: usphone="usphone"</em>.</p>
 * <p>This attribute will allow standard phone numbers to be used such
 * as:<br />
 * 407-555-1234<br />
 * 407.555.1234<br />
 * 407 555 1234<br />
 * (407)555-1234<br />
 * (407) 555-1234
 * </p>
 * <p>Note: This attribute does not check to see if the phone number is a
 * legitimate value, only that it is a legitimate format. i.e. someone could
 * enter 407-555-1234, which is not legal, but in the correct format.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function usphone(evt) {
	var elem = getTarget(evt);
	var reg = /^[2-9][0-9]{2}([-. ])[2-9][0-9]{2}\1[0-9]{4}$/;
	var reg2 = /^\([2-9][0-9]{2}\)[ ]*[2-9][0-9]{2}[- \.][0-9]{4}$/;
	elem.value = trim(elem.value);

	var tested = meetsRegEx(elem.value, reg) || meetsRegEx(elem.value, reg2);
	if(!tested) {
		return displayError(elem, 'usphone', 'The field ' + fixNaming(elem.name) + ' is not a valid phone number.');
	} else {
		removeErrorNode(elem, 'usphone');
		return '';
	}
}

/**
 * <p>Called if this form element is supposed to be 5 digit or 9 digit
 * zip code.</p>
 * <p>This attribute will allow standard zip codes to be used such
 * as:<br />
 * 32712<br />
 * 32712-1234
 * </p>
 * <p>Note: This attribute does not check to see if the zip code is a
 * legitimate value, only that it is a legitimate format.</p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * 		function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function zipcode(evt) {
	var elem = getTarget(evt);
	var reg = /(^[0-9]{5}(-[0-9]{4})?$)|(^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA$)/i;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'zipcode', text('Please enter a valid zip code.'));
	} else {
		removeErrorNode(elem, 'zipcode');
		return '';
	}
}

/**
 * <p>Called if this form element is supposed to be in the form of US
 * currency (US dollars).  This does not allow for commas for thousand
 * places, but does require the decimal and two digits for the cents.
 * The dollar sign is also required for the start of the value.
 * <em>ex.: uscurrency="uscurrency"</em></p>
 * <p>This attribute will allows for:<br />
 * $123.45<br />
 * $0.99
 * </p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function uscurrency(evt) {
	var elem = getTarget(evt);
	var reg = /^\$\d+(\.\d\d){0,1}$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'uscurrency', 'The field ' + fixNaming(elem.name) + ' is not a valid US Currency.');
	} else {
		removeErrorNode(elem, 'uscurrency');
		return '';
	}
}

/**
 * <p>This attribute is used to check to see that the form element is using
 * a SSN format.  It will support dashes or spaces between the number
 * groupings, as well as leaving them out.  <em>ex.: ssn="ssn"</em></p>
 * <p>This attribute will allows for:<br />
 * 123-45-6789<br />
 * 123 45 6789<br />
 * 123456789
 * </p>
 * <p>Note: This attribute does not check to see if theSSN is valid for
 * a living individual, only that it is a legitimate format.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function ssn(evt) {
	var elem = getTarget(evt);
	var reg = /^\d{3}([- ])?\d{2}\1?\d{4}$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'ssn', 'The field ' + fixNaming(elem.name) + ' is not a valid US Social Security Number.');
	} else {
		removeErrorNode(elem, 'ssn');
		return '';
	}
}

/**
 * <p>Called if this form element is a time value of hours and minutes.</p>
 * <p>This attribute will allows for:<br />
 * 9:45<br />
 * 9:45 am<br />
 * 9:45 AM
 * </p>
 * <p>This formating does not allow for 24 hour time telling, sometimes
 * called "Military Format".  It also does not allow for time zones to be
 * included with the time.  Given the number of time zones (there are
 * more than 24 depending upon country location) it would be impractical
 * to include that information.  Likewise, most people do not know their
 * +/- GMT value, so it is not valid for this time pattern.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function time(evt) {
	var elem = getTarget(evt);
	var reg = /^([1-9]|1[0-2]):[0-5]\d( (am|pm|AM|PM))?$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'time', 'The field ' + fixNaming(elem.name) + ' is not a valid standard time.');
	} else {
		removeErrorNode(elem, 'time');
		return '';
	}
}

/**
 * <p>Called if this form element is a US formated date value
 * (month-day-year). Two seperators are supported including the slash and
 * the dash. Use of the seperators must be consistant.</p>
 * <p>This attribute will allows for:<br />
 * 6/7/2007<br />
 * 06/7/2007<br />
 * 6/07/2007<br />
 * 06/07/2007<br />
 * 6/7/07<br />
 * 06/07/07<br />
 * et cetra.  Dashes may also replace the slashes.
 * </p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function usdate(evt) {
	var elem = getTarget(evt);
	var reg =  /^(1[0-2]|0?[1-9])(\-|\/)([0-2]?0?[\d]|3[01])(\2)\d{2,4}$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'usdate', 'The field ' + fixNaming(elem.name) + ' is not a valid standard time.');
	} else {
		removeErrorNode(elem, 'usdate');
		return '';
	}
}

/**
 * <p>Called if this form element is an international formated date
 * value (year-month-day). Three seperators are supported including the
 * slash, the dash, and the period.  Use of the seperators must be
 * consistant.  The year may be in 2 digit or 4 digit format.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function internationaldate(evt) {
	var elem = getTarget(evt);
	var reg = /^\d{2,4}(\-|\/\.)(1[0-2]|[1-9])(\1)([0-2]?[\d]|3[01])$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'intdate', 'The field ' + fixNaming(elem.name) + ' is not a valid standard time.');
	} else {
		removeErrorNode(elem, 'intdate');
		return '';
	}
}

/**
 * <p>Called if this form element can contain only letters and numbers.
 * No special characters or formatters are allowed.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function alphanumeric(evt) {
	var elem = getTarget(evt);
	var reg = /^([a-zA-Z\d])*$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'alphanumeric', 'The field ' + fixNaming(elem.name) + ' must be only letters and/or numbers.');
	} else {
		removeErrorNode(elem, 'alphanumeric');
		return '';
	}
}

/**
 * <p>Called if this form element can contain only numbers. No letters,
 * or special symbols will be included.  A single decimal place is
 * allowed to seperate the space between the whole number and the decimal,
 * value, however, the comma, used to group numbers, is not allowed, nor
 * is the period allowed to group numbers.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function numeric(evt) {
	var elem = getTarget(evt);
	var reg = /^(\d*|\d*\.\d+)$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'numeric', 'The field ' + fixNaming(elem.name) + ' must be only numbers.');
	} else {
		removeErrorNode(elem, 'numeric');
		return '';
	}
}

/**
 * <p>Called if this form element can contain only letters. No numbers,
 * or special symbols will be included.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.</p>
 * @param	{Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 * @see #required
 */
function alpha(evt) {
	var elem = getTarget(evt);
	var reg = /^([a-zA-Z])*$/;

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'alpha', 'The field ' + fixNaming(elem.name) + ' must be only letters.');
	} else {
		removeErrorNode(elem, 'alpha');
		return '';
	}
}

/**
 * <p>Called if this form element must match a regular expression. The
 * regular expression to be matched is the value within the attribute
 * regex.</p>
 * <p>This feature was added incase any potential areas that were not
 * covered by the built in expresssions were needed.  With this attribute
 * those circumstances could be covered.  This might include things like
 * product serial numbers, library card values, et cetera.</p>
 * @param {Event} evt	The event (usually onblur) which caused this
 * function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function regex(evt) {
	var elem = getTarget(evt);
	var reg = elem.getAttribute('regex');

	if(!meetsRegEx(elem.value, reg)) {
		return displayError(elem, 'regex', text('Please enter a valid value.'));
	} else {
		removeErrorNode(elem, 'regex');
		return '';
	}
}

/**
 * <p>The value of this form element must match another form element's,
 * value. The form element to match against is the value of the matches
 * attribute. <em>ex.: matches="password"</em> could be used on a confirm
 * password field, that requires the passwords to match. The value in the
 * attribute should be the form elements id.  If the HTML document is well
 * formed, this will keep the elements from potentially having the same
 * name in two different forms.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.  However, if the form
 * element which this element is supposed to match, has the required
 * attribute, then essentially this form element also gets that benifit
 * because they two values must match.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function matches(evt) {
	var elem = getTarget(evt);
	var dup = document.getElementById(elem.getAttribute('matches'));

	if(elem.value != dup.value) {
		//return displayError(elem, 'matches', 'The field ' + fixNaming(elem.name) + ' does not match ' + fixNaming(elem.getAttribute('matches')) );
		return displayError(elem, 'matches', text('The field must match ') + fixNaming(elem.getAttribute('matches')) );
	} else {
		removeErrorNode(elem, 'matches');
		return '';
	}
}

/**
 * <p>The number in the given field must be larger than the field
 * associated as the value in the attribute numgt.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.  However, if the form
 * element which this element is supposed to match, has the required
 * attribute, then essentially this form element also gets that benifit
 * because they two values must match.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function numgt(evt) {
	var elem = getTarget(evt);
	var tgt = document.getElementById(elem.getAttribute('numgt'));

	if(elem.value <= document.getElementById(tgt).value ) {
		return displayError(elem, 'numgt', 'The field ' + fixNaming(elem.name) + ' is not greater than ' + fixNaming(elem.getAttribute('numgt')) );
	} else {
		removeErrorNode(elem, 'numgt');
		return '';
	}
}

/**
 * <p>The number in the given field must be larger than or equal to the
 * field associated as the value in the attribute numgt.</p>
 * <p><strong>Note:</strong> This will not make the entry {@link requried}.
 * You must add that attribute to the form element as well if you
 * require this form element to have a value.  However, if the form
 * element which this element is supposed to match, has the required
 * attribute, then essentially this form element also gets that benifit
 * because they two values must match.</p>
 * @param {Event} evt	The event (usually onblur) which caused this function to be called.
 * @type	String
 * @return	an error message is necessary, otherwise a null string
 */
function numgte(evt) {
	var elem = getTarget(evt);
	var tgt = document.getElementById(elem.getAttribute('numgt'));

	if(elem.value < document.getElementById(tgt).value ) {
		return displayError(elem, 'numgte', 'The field ' + fixNaming(elem.name) + ' is not greater than ' + fixNaming(elem.getAttribute('numgte')) );
	} else {
		removeErrorNode(elem, 'numgte');
		return '';
	}
}

function hidePopups(evt) {
    var elem = (evt.target) ? evt.target : evt.srcElement;
    while(elem != null) {
        if(elem.className == 'errMsg' ||
            elem.className == 'errorButton'
        ) {
            return false;
        }
        elem = elem.parentNode;
    }
    //clicked outside
    $('.errMsg').hide('slow');
}

function iseighteen(evt)
{
    var elem = getTarget(evt);
    var birthYear = $('#birthYear').val();
    if(!birthYear.match(/^((19)|(20))[0-9]{2}$/i)
    ) {
        //console.log('invalid year');
        return '';
    }
    //console.log('ok, year valid');
    var oDate = new Date();
    var timeNow = oDate.getTime();
    oDate.setDate($('#birthDay').val());
    oDate.setMonth($('#birthMonth').val() - 1);
    oDate.setFullYear($('#birthYear').val());
    var timeThen = oDate.getTime();
        //console.log('then:' + timeThen + ', now:' + timeNow);
    var years = timeNow - timeThen;
    years = Math.floor(years/(1000 * 60 * 60 * 24 * 365));
        //console.log('You are:' + years + ' years old');
    if(years < 18) {
            //console.log('poping up error');
        return displayError(elem, 'iseighteen', 'You must be at least 18 years old.' );
    } else {
            //console.log('removing error');
        removeErrorNode(elem, 'iseighteen');
    }
    return '';
}

/**
 * Dummy function for implementing Submit button disabled switching.
 *
 */
function allowstatus ()
{
    return '';
}

/**
 * Disable the submit button if at least one error message exists
 *
 * @param integer state 1 for ok, 0 for error
 * @param object btn jquery button object
 */
function switchSubmit(btn, state)
{
    //console.log('btn='+btn.attr('name'));
    //console.log('state='+state);
    //if state is defined (0 or 1), set explicitly to this state

    //console.log('checking for errors');
    if(state === 0 ||
        (typeof state == 'undefined' && (
            $('.errMsg').length ||
            ($('.okButton').length == 0 &&
	    	$('.okIcon').length == 0 )
            )
        )
    ) {
         //console.log('errors found');
        //submitElem.value = text('Please check the form for errors');
        btn.text(text('Please check the form for errors'));
        //submitElem.disabled = true;
        btn.attr('disabled', true);
        btn.addClass('disabledBtn');
    } else {
        //console.log('no errors');
        //submitElem.value = submitDefaultValue;
        btn.text(btn.attr('defaultText'));
        //submitElem.disabled = false;
        btn.attr('disabled', false);
        btn.removeClass('disabledBtn');
    }
}

/**
 * Check if login is available (i.e. not used by another user)
 */
function checklogin(evt)
{
    var elem = getTarget(evt); 
    var login = elem.value;
    $.getJSON(urlRoot + '/check-availability.php', {'login':login}, function(json) {
            if(json.login == 1) { //login exists
                return displayError(elem, 'checklogin', text('This user name already exists. Contact the support if you own an account of the same name in one of our partner casinos.') );
            } else {
                removeErrorNode(elem, 'checklogin');
		        return '';
            }
        }
    );
    return '';
}

/**
 * Check if email is available (i.e. not used by another user)
 */
function checkemail(evt)
{
    var elem = getTarget(evt);
    var email = elem.value;
    $.getJSON(urlRoot + '/check-availability.php', {'email':email}, function(json) {
            if(json.email == 1) { //email exists
                return displayError(elem, 'checkemail', text('This email is used by another user already. Contact the support if the email belongs to you.') );
            } else {
                removeErrorNode(elem, 'checkemail');
		        return '';
            }
        }
    );
    return '';
}

/**
 * Check if password is strong enough. This depends on the StrongPassword class!!
 */
function pwstrength(evt)
{
        var elem = getTarget(evt);
        if(sp) {
                 if(sp.strength < sp.minAllowScore) {
                         displayError(elem, 'pwstrength', sp.scoreTextNotAcceptable);
                 } else {
                         removeErrorNode(elem, 'pwstrength');
                 }
        }
        return '';
}



window.addEventListener('load', initializeValidator, false);
window.addEventListener('click', hidePopups, false);
