

if (!Tool.Form) {
	throw new Error('Missing Tool.form.js');
}

Tool.reg = new Tool.Form();

Tool.reg.STATUS = {
	OK: 200,
	INVALID: 400,
	INTERNAL_FAILURE: 500
};

Tool.reg.messages = {
	'failed': 'We are experiencing technical difficulties.\nYour registration cannot be completed at this time.\nPlease try back in a few minutes.',
	'invalid': 'Please correct the errors indicated in red and try again.'
};

Tool.reg.errorAlert = function(txt) {
	txt = txt || Tool.reg.messages.invalid;
	alert(txt);
	return false;
};

Tool.reg.Field = function(input, remote, tip) {
	this.remote = remote ? true : false;
	this.remoteValid = true;
	this.cold = true;
	this.input = input;
	this.tip = tip instanceof Tool.Form.Tip ? tip : false;
	this.compound = input.isCompound();
	var dis = this;
	var timeout;
	var timeout2;
	var lastvalue = this.input.getValue();

	if (input.isText()) {
		input.addEvent('keyup', function(evt) {
			if (!dis.cold) {
				if (dis.input.getValue() !== lastvalue) {
					lastvalue = dis.input.getValue();
					if (timeout) {
						clearTimeout(timeout);
					}
					if (timeout2)
					{
						clearTimeout(timeout2);
					}
					timeout = setTimeout(function() {
						dis.input.forceValid = false;
						dis.remoteValid = true;
						dis.isValid();
					}, 50);
				}
			}
		});
		input.addEvent('change', function(evt) {
			lastvalue = dis.input.getValue();
		});
	}

	var setCaretPosition = function(id, pos) {
		var range, el = $get(id);
		if (el) {
			if (el.createTextRange) {
				range = el.createTextRange();
				range.move('character', pos);
				range.select();
			}
			else {
				if (el.selectionStart) {
					el.setSelectionRange(pos, pos);
				}
				el.focus();
			}
		}
		return false;
	};

	if (!input.isCompound()) {
		input.addEvent('change', function(evt) {
			dis.input.forceValid = false;
			dis.thaw().isValid();
		});
		input.addEvent('focus', function(evt) {
			v = dis.input.getValue();
			if (v) {
				dis.thaw();
				if (dis.input.isText()) {
					setCaretPosition(dis.input.id, v.length);
				}
			}
			if (dis.tip) {
				dis.tip.enable().show();
			}
		});
		input.addEvent('blur', function(evt) {
			if (!dis.remote) {
				if (!dis.cold) {
					dis.isValid();
				}
			}
			if (dis.tip) {
				dis.tip.hide().disable();
			}
		});
	}

	// Disable CR on Safari
	if (/safari/i.test(navigator.userAgent)) {
		YAHOO.util.Event.addListener(input.id, 'keypress', function(evt) {
			if (evt.which && evt.which === 13) {
				evt.preventDefault();
			}
		});
	}

	return this;
};

Tool.reg.initSelectBoxes = function() {
	var createOption = function(text, value) {
		var opt = document.createElement('option');
		opt.text = text;
		if (value) {
			opt.value = value;
		}
		return opt;
	};
	var setYears = function(el) {
		var i, j = 1, opt, now = Tool.reg.now;
		var max = now.getFullYear() - 8;
		var min = max - 80;
//		el.options.length = 0;
		for (i = max; i >= min; i--, j++) {
			opt = createOption(i, i);
			el.options[j] = opt;
		}
		return;
	};
	var setMonths = function(el) {
		var i = 1;
//		el.options.length = 0;
		Tool.date.months.short.each(function(month) {
			el.options[i] = createOption(month, (i< 10 ? '0'+i : i));
			i++;
		});
		return;
	};
	var setDays = function(el) {
		var i, opt, days = 31;
//		el.options.length = 0;
		for (i = 1; i <= days; i++) {
			opt = createOption(i, (i< 10 ? '0'+i : i));
			el.options[i] = opt;
		}
		return;
	};

	setMonths($get('birthdate_month'));
	setYears($get('birthdate_year'));
	setDays($get('birthdate_day'));
	return this;
};

Tool.reg.Field.prototype = {
	blockRemote: function() {
		this.remoteBlocked = true;
		return this;
	},
	unblockRemote: function() {
		this.remoteBlocked = false;
		return this;
	},
	doRpc: function() {
		var dis = this;
		if (this.busy || this.remoteBlocked) {
			return this;
		}
		this.busy = true;

		var data = 'key=' + this.input.id + "&value="+encodeURIComponent(this.input.getValue());
		
		YAHOO.util.Connect.asyncRequest('POST', 'validate.asp', {
			success: function(o) {
				var response = YAHOO.lang.JSON.parse(o.responseText);

				if (response.status && response.status !== Tool.reg.STATUS.INTERNAL_FAIlURE) {

					// Field did not pass validation
					if (response.status === Tool.reg.STATUS.INVALID) {
						if (response.error) {
							if (dis.tip) {
								dis.tip.setErrors([response.error]);
								dis.tip.show();
							}
							dis.input.paintError().forceValid = false;
							dis.remoteValid = false;
						}
					}
					// Field passed validation
					else if (response.status === Tool.reg.STATUS.OK) {
						if (dis.tip) {
							dis.tip.revert().hide();
						}
						dis.input.unpaintError();
						dis.input.forceValid = true;
						dis.remoteValid = true;
					}
					dis.busy = false;
				} else {
					dis.doErrorAlert(Tool.reg.messages.failed);
				}
			},
			failure: function(o) {
				dis.doErrorAlert(Tool.reg.messages.failed);
			}
		}, data);
		return this;
	},
	thaw: function() {
		if (!this.input.isText()) {
			return this;
		}
		var yue = YAHOO.util.Event, el = this.input.getElement();
		this.cold = false;
		if (el) {
			yue.removeListener(el, 'change');
		}
		return this;
	},
	isValid: function(evt) {
		var valid = this.input.isValid();
		if(!this.remoteValid) return false;

		if(this.timeout2) clearTimeout(this.timeout2);
		if (this.tip) {
			if (valid) {
				this.tip.hide().revert();
			} else {
				this.tip.setErrors(this.input.getErrorMessages()).show();
			}
		}
		if (valid && this.remote) {
			var dis = this;
			this.timeout2 = setTimeout(function() {
				dis.doRpc();
			}, 500);
//			this.doRpc();
		}
		return valid;
	}
};


Tool.reg.initDob = function() {
	var yu = YAHOO.util;
	var dob = new Tool.reg.Field(new Tool.CompoundSelectBox([
		new Tool.SelectBox('birthdate_month'),
		new Tool.SelectBox('birthdate_day'),
		new Tool.SelectBox('birthdate_year')
	], 'Date of birth').setId('birthdate').setEvaluator(function(selects) {
		var m = selects[0].getValue();
		var d = selects[1].getValue();
		var y = selects[2].getValue();
		if (m === '' || m < 0 || !d || !y) {
			return false;
		}
		return new Date(y, --m, d);

	}).addSpec(Tool.valueSpecs.notBlank).addSpec(new Tool.ValueSpec('Sorry, you are not eligible to register.', function(birthdate) {
		var now = new Date();
		var _13yearsAgo = new Date(now.getFullYear() - 13, now.getMonth(), now.getDate());
		if (birthdate && birthdate.constructor === Date) {
			return birthdate.toUnixTimestamp() <= _13yearsAgo.toUnixTimestamp();
		}
		return true;

	})), false);

	dob.tip = new Tool.Form.Tip('birthdate_tip');

	var dobCold = {
		birthdate_month: true,
		birthdate_day: true,
		birthdate_year: true
	};
	dob.input.paintError = function() {
		yu.Dom.addClass('birthdate_wrap', 'error');
		return this;
	};
	dob.input.unpaintError = function() {
		yu.Dom.removeClass('birthdate_wrap', 'error');
		return this;
	};
	dob.input.selects.each(function(selekt) {
		yu.Event.addListener(selekt.id, 'change', function() {
			var p;
			dob.cold = false;
			dobCold[selekt.id] = false;
			for (p in dobCold) {
				if (dobCold[p]) {
					dob.cold = true;
				}
			}
			if (!dob.cold) {
				dob.tip.enable();
				if (dob.isValid()) {
					dob.tip.hide().revert();
				}
				else {
					dob.tip.show();
					setTimeout(function() {
						yu.Event.addListener(selekt.id, 'blur', function(evt) {
							dob.tip.hide();
						});
						yu.Event.addListener(selekt.id, 'focus', function(evt) {
							if (!dob.isValid()) {
								dob.tip.show();
							}
						});
					}, 0);
				}
			}
		});
	});

	this.fields.birthdate = dob;
	return this;
};

Tool.reg.isBusy = function() {
	var p;
	for (p in this.fields) {
		if (this.fields[p].remote) {
			if (this.fields[p].busy) {
				return true;
			}
		}
	}
	return false;
};

Tool.reg.handleTermsOfServiceError = function() {
	$get('tos_error').style.display = 'block';
	return this;
};

Tool.reg.init = function() {

	this.initSelectBoxes();
	var dis = this;
	var p, i, n, el, tip;
	var is = Tool.valueSpecs, has = is, spec = Tool.ValueSpec;
	var map = {
		'userid': {
			'name': 'User ID',
			'remote': true,
			'tip': true,
			'specs': [
				new spec('%s must be at least 5 characters long', function(value) {
					return value.trim().length >= 5;
				}),
				has.letterFirst,
				has.noSpace,
				new spec('Symbols other than a dash, underscore or period are not allowed', function(value) {
					return /[^a-z0-9\-\_\.]/i.test(value) === false;
				}),
				new spec('Only 1 dash, underscore or period is allowed', function(value) {
					var count = 0;
					['-', '_', '.'].each(function(symbol) {
						var chars = value.split('');
						while (chars.length) {
							if (chars.shift() === symbol) {
								if (count++ > 1) {
									return;
								}
							}
						}
					});
					return count < 2;
				}),
				new spec('UserID cannot contain &quot;ndoors&quot;', function(value) {
					return /ndoors/i.test(value) === false;
				})
			]
		},
		'passwd': {
			'name': 'Password',
			'remote': false,
			'tip': true,
			'specs': [
				is.notBlank,
				new spec('%s must be at least 6 characters in length', function(value) {
					return value.trim().length >= 6;
				}),
				has.noSpace,
				has.oneDigit
			]
		},
		'passwd_confirm': {
			'name': 'This',
			'remote': false,
			'tip': true,
			'specs': [
				is.notBlank,
				new spec('%s should match your password', function(value) {
					return dis.fields.passwd.input.getValue() === value;
				})
			]
		},
		'f_name': {
			'name': 'First name',
			'remote': false,
			'tip': true,
			'specs': [
				is.notBlank,
				has.letterFirst,
				new spec('%s can only contain the characters A-Z', function(value) {
					return /[^a-z\s]/i.test(value) === false;
				})
			]
		},
		'l_name': {
			'name': 'Last name',
			'remote': false,
			'tip': true,
			'specs': [
				is.notBlank,
				has.letterFirst,
				new spec('%s can only contain the characters A-Z', function(value) {
					return /[^a-z\s]/i.test(value) === false;
				})
			]
		},
		'email': {
			'name': 'Email address',
			'remote': true,
			'tip': true,
			'specs': [
				is.notBlank,
				is.email
			]
		},
		'agreement': {
			'name': 'Terms of Service',
			'remote': false,
			'tip': false,
			'specs': [] 
		},
		'event_key': {
			'name': 'MMOPRG Event key',
			'remote': false,
			'tip': true,
			'specs': [
				has.noSpace,
				new spec('%s can only contain the characters A-F or numbers 0-9', function(value) {
					return /[^a-f0-9]/i.test(value) === false;
				})
			]
		}
	};

	for (p in map) {
		n = map[p].name;
		el = $get(p);
		if(!el) continue;
		tip = map[p].tip ? new Tool.Form.Tip(p + '_tip') : false;
		if (el.type === 'select-one') {
			i = new Tool.SelectBox(p, n);
		} else {
			i = new Tool.FormInput(p, n);
//			i.getElement().value = '';
		}
		this.addField(new Tool.reg.Field(i, map[p].remote, tip));
		map[p].specs.each(function(spec) {
			i.addSpec(spec);
		});
	}

	this.fields.passwd.input.addEvent('keyup', function(evt) {
		var f = dis.fields.passwd_confirm;
		if (!f.cold) {
			f.tip.disable();
			setTimeout(function() {
				f.isValid();
			}, 250);
		}
	});

	this.setSubmitButton('regButton');
	this.initDob();
	this.initTermsOfService();

	return this;
};

Tool.reg.initTermsOfService = function() {
	var dis = this, tos = this.fields.agreement.input, tos_error = $get('tos_error');	
	YAHOO.util.Event.addListener(tos.getElement(), 'click', function(evt) {
		if (tos.getValue()) {
			tos_error.style.display = 'none';
		}
		else {
			tos_error.style.display = 'block';
		}
	});
	return this;
};

Tool.reg.setHandler(function() {

    // Note: this = Tool.reg
    var dis = this;

    // If RPC is in progress, exit and resubmit the form later
    if (this.isBusy()) {
        document.body.style.cursor = 'default';
        setTimeout(arguments.callee.bind(this), 500);
        return;
    }

    if ('submitTimeout' in this) {
        this.submitBtn.style.cursor = 'not-allowed';
        return false;
    }
    this.submitTimeout = setTimeout(function() {
        dis.submitBtn.style.cursor = 'pointer';
        delete dis.submitTimeout;
    }, 3000);

    if (!this.isValid()) {
        //		this.errorAlert();
        return false;
    }
    else {
        ValidationExceptCaptcha = true;
    }

    if (!LBD_ValidationResult) {
        return false;
    }


    this.submitBtn.style.cursor = 'wait';
    document.body.style.cursor = 'wait';

    document.frmRegist.action = "https://sign.ndoorsgames.com/atlantica/register_proc_new_capcha.asp";
    document.frmRegist.submit();

    return false;
});

Tool.reg.setValidator(function() {
	var p, f, valid = true;
	for (p in this.fields) {
		f = this.fields[p];
		if (f.input.id == "agreement")
		{
			if(!f.input.getValue()) {
				valid = false;
				this.handleTermsOfServiceError();
			}
			continue;
		}
		if(!f.remoteValid || !f.isValid() ) {
			if(valid == true) { $get(f.input.id).focus(); }
			valid = false;
		}
	}
	
	return valid;
});

YAHOO.util.Event.onDOMReady(function() {

	YAHOO.util.Event.addListener(document.body, 'unload', function(evt) {
		$purge(document.body);
	});

	Tool.reg.init();
	setTimeout(function() {
//		$get('userid').focus();
		window.scrollTo(0, 0);
		}, 100);
});

// set reCAPTCHA skin
var RecaptchaOptions = {
	theme : 'blackglass',
	lang : 'en'
};
