/**
 * @version	$Id: easydns.form2.js 1316 2008-10-21 14:34:12Z awyld $
 * @author Andrew Wyld <awyld@easydns.com>
 * @category javascript
 * @copyright Copyright (c) 2007, EasyDNS Technologies Inc.
 */
 
 var RULE_ALPHA = /[a-z]/i;
 var RULE_NUM = /[1-9]/;
 var RULE_ANUM = /[a-z0-9]/i;
 var RULE_PHONE = /^[\d\-\(\)\.\+\#\*\ ]{4,}((x|ex|ext|xt)\.?\d+)?(TDD)?$/i;
 var RULE_EMAIL = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
 var RULE_CTRY = /[a-z]{2,2}/;
 var RULE_IP = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/;
 var RULE_PASS = /^[\w!@#$%^&\*-]+$/;


/**
 * These regular expressions are used to validate form fields based
 * on their ID attribute. Keep this in mind when naming your form fields.
 */
jQuery.FORM_RULES = {
	unknown: RULE_ALPHA,
	
	user: /^[a-z0-9_-]+$/i,
	pass: RULE_PASS,
	confirm_pass: RULE_PASS,
	
	domain: /^[a-z\.\-0-9]+$/i,
	tld: /^\.[a-z]/,
	ip: RULE_IP,
	
	first_name: RULE_ALPHA,
	owner_first_name: RULE_ALPHA,
	admin_first_name: RULE_ALPHA,
	tech_first_name: RULE_ALPHA,
	billing_first_name: RULE_ALPHA,

	last_name: RULE_ALPHA,
	owner_last_name: RULE_ALPHA,
	admin_last_name: RULE_ALPHA,
	tech_last_name: RULE_ALPHA,
	billing_last_name: RULE_ALPHA,

	org_name: RULE_ANUM,
	owner_org_name: RULE_ANUM,
	admin_org_name: RULE_ANUM,
	tech_org_name: RULE_ANUM,
	billing_org_name: RULE_ANUM,

	phone: RULE_PHONE,
	owner_phone: RULE_PHONE,
	admin_phone: RULE_PHONE,
	tech_phone: RULE_PHONE,
	billing_phone: RULE_PHONE,
	
	fax: RULE_PHONE,
	owner_fax: RULE_PHONE,
	admin_fax: RULE_PHONE,
	tech_fax: RULE_PHONE,
	billing_fax: RULE_PHONE,
	
	email: RULE_EMAIL,
	owner_email: RULE_EMAIL,
	admin_email: RULE_EMAIL,
	tech_email: RULE_EMAIL,
	billing_email: RULE_EMAIL,

	city: RULE_ALPHA,
	owner_city: RULE_ALPHA,
	admin_city: RULE_ALPHA,
	tech_city: RULE_ALPHA,
	billing_city: RULE_ALPHA,

	state: RULE_ALPHA,
	owner_state: RULE_ALPHA,
	admin_state: RULE_ALPHA,
	tech_state: RULE_ALPHA,
	billing_state: RULE_ALPHA,
	
	country: /[a-z]/,
	owner_country: RULE_CTRY,
	admin_country: RULE_CTRY,
	tech_country: RULE_CTRY,
	billing_country: RULE_CTRY,
	
	login_user: RULE_ANUM,
	login_pass: RULE_ANUM,
	password: RULE_ANUM,
	
	address1: RULE_ANUM,
	owner_address1: RULE_ANUM,
	admin_address1: RULE_ANUM,
	tech_address1: RULE_ANUM,
	billing_address1: RULE_ANUM,
	
	address2: RULE_ANUM,
	owner_address2: RULE_ANUM,
	admin_address2: RULE_ANUM,
	tech_address2: RULE_ANUM,
	billing_address2: RULE_ANUM,
	
	address3: RULE_ANUM,
	owner_address3: RULE_ANUM,
	admin_address3: RULE_ANUM,
	tech_address3: RULE_ANUM,
	billing_address3: RULE_ANUM,
	
	postal: RULE_ANUM,
	postal_code: RULE_ANUM,
	owner_postal_code: RULE_ANUM,
	admin_postal_code: RULE_ANUM,
	tech_postal_code: RULE_ANUM,
	billing_postal_code: RULE_ANUM,

	url: /^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}([\w]+)(.[\w]+){1,2}$/,
	opt_out: /[YN]/,
	security_secret_question_1: RULE_NUM,
	security_secret_question_2: RULE_NUM,
	security_secret_question_3: RULE_NUM,
	security_secret_answer_1: /.+/,
	security_secret_answer_2: /.+/,
	security_secret_answer_3: /.+/
};

jQuery.REMOTE_RULES = {
};

var MSG_FNAME = 'first name';
var MSG_LNAME = 'last name';
var MSG_PASS = 'password';
var MSG_ADDR = 'street address';


/**
 * These values are used in the user visible error messages object
 * but because they are form field specific I have put them here.
 * 
 * NOTE:
 * Do not mess with these unless you know what you are doing.
 */
jQuery.FIELD_NAMES = {
	domain: 'domain',
	transfer_domain: 'domain',
	bulktransfer_domain: 'list of domains',
	bulkbox: 'list of domains',
	login_user: 'username',
	user: 'username',
	login_pass: MSG_PASS,
	password: MSG_PASS,
	pass: MSG_PASS,
	confirm_pass: 'Please enter your password a second time to confirm the correct spelling.',
	first_name: MSG_FNAME,
	last_name: MSG_LNAME,
	org_name: 'organization name',
	address: MSG_ADDR,
	address1: MSG_ADDR,
	address2: 'second street address',
	address3: 'third street address',
	city: 'city',
	state: 'state',
	postal_code: 'postal code',
	phone: 'E.164 phone number',
	email: 'email address',
	email2: 'This is an additional email address we can use to contact the account holder in the case of account lockouts (due to a defunct email addresses), password resets, zombie attacks, etc.',
	public_email: 'This is the email address you would like displayed in your domain\'s WhoIs Records (you can use a free  myprivacy.ca address if privacy is a concern)',
	language: 'language',
	
	owner_first_name: MSG_FNAME,
	owner_last_name: MSG_LNAME,
	owner_org_name: 'organization name',
	owner_address: MSG_ADDR,
	owner_address1: MSG_ADDR,
	owner_address2: 'second street address',
	owner_address3: 'third street address',
	owner_postal_code: 'postal code',
	owner_phone: 'phone number',
	owner_email: 'email address',
	owner_email2: 'secondary email address',
	owner_public_email: 'public email address',
	owner_city: 'city',
	owner_state: 'state',
	owner_country: 'country',
	owner_language: 'language',
	
	admin_first_name: MSG_FNAME,
	admin_last_name: MSG_LNAME,
	admin_org_name: 'organization name',
	admin_address: MSG_ADDR,
	admin_address1: MSG_ADDR,
	admin_address2: 'second street address',
	admin_address3: 'third street address',
	admin_postal_code: 'postal code',
	admin_phone: 'phone number',
	admin_email: 'email address',
	admin_email2: 'secondary email address',
	admin_public_email: 'public email address',
	admin_city: 'city',
	admin_state: 'state',
	admin_country: 'country',
	admin_language: 'language',
	
	tech_first_name: MSG_FNAME,
	tech_last_name: MSG_LNAME,
	tech_org_name: 'organization name',
	tech_address: MSG_ADDR,
	tech_address1: MSG_ADDR,
	tech_address2: 'second street address',
	tech_address3: 'third street address',
	tech_postal_code: 'postal code',
	tech_phone: 'phone number',
	tech_email: 'email address',
	tech_email2: 'secondary email address',
	tech_public_email: 'public email address',
	tech_city: 'city',
	tech_state: 'state',
	tech_country: 'country',
	tech_language: 'language',
	
	billing_first_name: MSG_FNAME,
	billing_last_name: MSG_LNAME,
	billing_org_name: 'organization name',
	billing_address: MSG_ADDR,
	billing_address1: MSG_ADDR,
	billing_address2: 'second street address',
	billing_address3: 'third street address',
	billing_postal_code: 'postal code',
	billing_phone: 'phone number',
	billing_email: 'email address',
	billing_email2: 'secondary email address',
	billing_public_email: 'public email address',
	billing_city: 'city',
	billing_state: 'state',
	billing_country: 'country',
	billing_language: 'language',
	
	rgpc_name: 'domain owner name',
	rgpc_legal_type: 'legal type',
	rgpc_description: 'domain description',
	rgpc_trade_mark_registered: 'domain trademark',
	rgpc_member: 'CIRA member',
	rgpc_country: 'country',
	
	extra_rgpc_name: 'domain owner name',
	extra_rgpc_legal_type: 'legal type',
	extra_rgpc_description: 'domain description',
	extra_rgpc_trade_mark_registered: 'domain trademark',
	extra_rgpc_member: 'CIRA member',
	extra_rgpc_country: 'country',
	
	opt_out: 'non-critical email choice',
	
	security_secret_question_1: 'secret question #1',
	security_secret_question_2: 'secret question #2',
	security_secret_question_3: 'secret question #3',
	security_secret_answer_1: 'secret answer #1',
	security_secret_answer_2: 'secret answer #2',
	security_secret_answer_3: 'secret answer #3',
	
	arpa: 'reverse address',
	cidr: 'CIDR net block'
};

/**
 * FORM PROPERTIES
 */
jQuery.validated = true;
jQuery.formid = null;



/**
 * FORM METHODS
 */

// {{{ addHidden()

/**
 * addHidden
 * 
 * @return bool Success
 */
jQuery.fn.addHidden = function addHidden(name, value, id, classes) {
	/* if($('#' + id).length > 0) */
	jQuery(this).append('<input type="hidden" name="'+name+'" id="'+id+'" class="'+classes+'" value="'+value+'" />');
	return true;
};




// {{{ indicateValidity()

/**
 * indicateValidity
 * 
 * @return bool Success
 */
jQuery.fn.indicateValidity = function indicateValidity() {
	this.addHidden('jscheck', 0, 'jscheck');
};




// {{{ setFormValid()

/**
 * setFormValid
 * 
 * @return bool Success
 */
jQuery.fn.setFormValid = function setFormValid() {
	try {
		var frmid = jQuery(this).attr('id');
		var v = jQuery('#'+frmid+'/input[@name=jscheck]').val('1');
	} catch(e) {
		return fail(e);
	}
};
// }}}



// {{{ setFormInvalid()

/**
 * setFormInvalid
 * 
 * @return bool Success
 */
jQuery.fn.setFormInvalid = function setFormInvalid() {
	try {
		var frmid = jQuery(this).attr('id');
		var v = jQuery('#'+frmid+'/input[@name=jscheck]').val(0);
	} catch(e) {
		return fail(e);
	}
};

// }}}


/**
 * disable
 */
jQuery.fn.disable = function disable() {
	return this.each( function () {
			jQuery(this).attr('disabled', true);
	}); 
};




// {{{ enable()

/**
 * enable
 * 
 * @return bool Success
 */
jQuery.fn.enable = function () {
	return this.each( function () {
			jQuery(this).attr('disabled', false);
	}); 
};
// }}}

function fn_keypress(e) {
	var ev = (window.event) ? event : e;
	var key = (window.event) ? event.keyCode : e.keyCode;
	
	// window.event.cancelBubble = true;
	
	// ENTER
	if(key == 13) {
		if(ev.cancelable) {
			ev.stopPropagation();
		}
		if(window.event) {
			window.event.cancelBubble = true;
			ev.keyCode = 0;
			ev.returnValue = false;
		}
	}
};

function fn_click(e) {
	var ev = event || window.event;
};


// {{{ submitOff()

/**
 * submitOff
 * 
 * @return bool Success
 */
jQuery.fn.submitOff = function () {
	return this.each( function () {
			jQuery(this).attr('onsubmit', 'return false;');
			jQuery(this).keypress(fn_keypress);
			jQuery(this).indicateValidity();
	});
};
// }}}


// {{{ submitOn()

/**
 * submitOn
 * 
 * @return bool Success
 */
jQuery.fn.submitOn = function submitOn() {
	return this.each( function () {
				jQuery(this).unbind('submit');
				jQuery(this).attr('onsubmit', '');
				jQuery(this).unbind('keypress');
			
				jQuery(this).setFormValid();
	});
	
	return true;
};
// }}}


// {{{ nextPage()

/**
 * nextPage
 * 
 * @return bool Always true
 */
jQuery.fn.nextPage = function nextPage() {
	var frm = null;
	
	try {
		frm = jQuery.formid;
		if(frm == null || !isEl(frm)) {
			return false;
		}

		if(jQuery.validated) {
			jQuery(frm).submitOn();
			jQuery(frm)[0].submit();
			return true;
		} else {
			jQuery.uerror.show();
			jQuery.unblockUI();
			return false;
		}
	} catch(e) {
		fail(e);
		return false;
	}
	return false;

};
// }}}

/**
 * setFormValidity
 * 
 * @return bool Success
 */
jQuery.fn.setFormValidity = function setFormValidity() {
	try {
		jQuery('<input type="hidden" id="jscheck" name="jscheck" value="0"').appendTo(this);
	} catch(e) {
		return fail(e);
	}
	return true;
};

/**
 * setInvalid
 */
jQuery.fn.setInvalid = function setInvalid() {
	return this.each( function () {
			jQuery(this).removeClass('valid');
			jQuery(this).addClass('invalid');
			jQuery(this).change(function () {
				jQuery(this).removeClass('invalid');
			});
	});
};

/**
 * setValid
 */
jQuery.fn.setValid = function setValid() {
	return this.each( function () {
			jQuery(this).removeClass('invalid');
			jQuery(this).addClass('valid');
	});
};

/**
 * validate
 */
jQuery.fn.validate = function validate() {
	jQuery.validated = true;
	return this.each( function () {
		var fid = jQuery(this).attr('id');
		var fval = jQuery(this).val();
		var rule = false;

		if(fid == null || fid.length <= 0) {
			fid = jQuery(this).attr('name');
		}
		
		rule = jQuery.FORM_RULES[fid];
		if(rule == null) {
			rule = jQuery.REMOTE_RULES[fid];
		}
		if(rule == null) {
			rule = getClassRule(this);
		}
		if(rule == null || !rule) {
			rule = jQuery.FORM_RULES['unknown'];
		}
		if(rule.test(fval)) {
			jQuery(this).setValid();
			return null;
		} else {
			jQuery.validated = false;
			jQuery(this).setInvalid();
			missingReqField(fid);
			// jQuery.uerror.missingRequired(this);
			return jQuery(this);
		}
		return jQuery(this);
	});
};

/**
 * requireFields
 *
 * @param selector field_list The fields to require in order for the field to submit.
 */
jQuery.requireFields = function(field_list) {
	jQuery.PAGE.set('req_fields', field_list);
	return true;
};

// {{{ formClick()

/**
 * formClick
 * 
 * @return bool Success
 */
jQuery.fn.formClick = function formClick() {
	try {
		jQuery.blockUI();
		// window.setTimeout(5000, jQuery.unblockUI);
	} catch(e) {
		return true;
	}

	return true;
};

// }}}

// {{{ getClassRule()

/**
 * getClassRule
 * 
 * @return bool Success
 */
function getClassRule(el) {
	var cstr, classes;
	try {
		var hasclass = jQuery(el).filter('input[@class*=verify]');
		if(hasclass == null || !hasclass) {
			return null;
		}
		classes = getClassArray(el);
	} catch(e) {
		fail(e);
		return null;
	}

	return null;
};

// }}}

// {{{ findFormFields()

/**
 * findFormFields
 * 
 * @return array Matching elements or false on failure.
 */
function findFormFields(form_id, criteria) {
	var result = false;
	
	if(criteria == null) {
		criteria = ' :input';
	}

	try {
		if(!isEl(form_id)) {
			return false;
		}
		result = jQuery(form_id).find(criteria);
		if(result == null || result.length <= 0) {
			return false;
		}
		return result;
	} catch(e) {}
	
	return false;
};

// }}}
