
if (typeof(cfw) != 'function') {
	var cfw = function() {}
}

cfw.validator = function() {}

cfw.validator.findVarMessageZone = function(form_name, var_name) {
	var key = 'err_' + form_name + '_' + var_name;
	return dojo.byId(key);
}

cfw.validator.findMessageZone = function() {
	var key = 'cfwform_errormessage';
	return dojo.byId(key);
}

cfw.validator.formatMessage = function(message) {
	var node = document.createTextNode(message);
	return node;
}

cfw.validator.formatMessages = function(messages) {
	var div = document.createElement('div');
	for ( var i = 0; i < messages.length ; i++ ) {
		div.appendChild(cfw.validator.formatMessage(messages[i]));
		var sp = document.createElement('br');
		div.appendChild(sp);
	}
	return div;
}

cfw.validator.setVarError = function(form_name, var_name, messages) {

	div = cfw.validator.findVarMessageZone(form_name, var_name);
	if (!div) return;

	div.innerHTML = '';
	div.appendChild(cfw.validator.formatMessages(messages));

	div.style.display = 'block';
}

cfw.validator.clearVarError = function(form_name, var_name) {

	div = cfw.validator.findVarMessageZone(form_name, var_name);
	if (!div) return;

	div.style.display = 'none';
	div.innerHTML = '';
}

cfw.validator.setError = function(messages) {
	div = cfw.validator.findMessageZone();
	if (!div) return;

	div.innerHTML = '';
	div.appendChild(cfw.validator.formatMessages(messages));

	div.style.display = 'block';
}

cfw.validator.clearError = function() {
	div = cfw.validator.findMessageZone();
	if (!div) return;

	div.style.display = 'none';
	div.innerHTML = '';
}

cfw.validator.displayValidationResult = function(form, result) {

	var form_id = form.getAttribute('id');

	if (!result.status.valid && result.status.messages.length > 0) {
		cfw.validator.setError(result.status.messages);
	} else {
		cfw.validator.clearError();
	}

	for ( var key in result.entries ) {
		var matches = key.match(/(.*)#(.*)/);
		var form_name = matches[1];
		var var_name = matches[2];

		var status = result.entries[key];
		if (status.valid) {
			cfw.validator.clearVarError(form_name, var_name);
		} else {
			cfw.validator.setVarError(form_name, var_name, status.messages);
		}
	}

}

cfw.validator.formFilter = function(node) {
	if (!dojo.io.formFilter(node)) return false;
	if (node.getAttribute("name") == 'page') return false;
	return true;
}

cfw.validator.setup = function(kwArgs) {

	var form = dojo.byId(kwArgs['formNode']);
	if (!form || !form.tagName || form.tagName.toLowerCase() != "form") return;

	var ctx = new cfw.validator.Context();
	ctx.form = form;

	ctx.url = kwArgs['url'];
	ctx.action = kwArgs['action'];

	if (typeof kwArgs['autosubmit'] != 'undefined') ctx.autosubmit = kwArgs['autosubmit'];

	dojo.event.connect(form, 'onsubmit', ctx, 'submit');

	for(var i = 0; i < form.elements.length; i++) {
		var node = form.elements[i];
		if(node && node.type && dojo.lang.inArray(node.type.toLowerCase(), ["submit", "button"])) {
			dojo.event.connect(node, "onclick", ctx, 'click');
		}
	}

	var inputs = form.getElementsByTagName("input");
	for(var i = 0; i < inputs.length; i++) {
		var input = inputs[i];
		if(input.type.toLowerCase() == "image" && input.form == form) {
			dojo.event.connect(input, "onclick", ctx, 'click');
		}
	}

	return ctx;

}

cfw.validator.Context = function() {
	this.clickedButton = null;
	this.form = null;
	this.url = null;
	this.action = null;
	this.running = false;
	this.finished = false;
	this.valid = false;
	this.result = null;
	this.autosubmit = true;
}

cfw.validator.Context.prototype.formFilter = function (node) {
	var type = (node.type||"").toLowerCase();
	var accept = cfw.validator.formFilter(node);
	if (dojo.lang.inArray(type, ["submit", "button", "image"])) {
		if(!this.clickedButton) { this.clickedButton = node; }
	}
	return accept;
}

cfw.validator.Context.prototype.click = function (e) {
	var node = e.currentTarget;
	if (node.disabled) return;
	this.clickedButton = node;

	this.submit(e);
}

cfw.validator.Context.prototype.submit = function (e) {
	if (this.finished && this.valid) {
		// allow submission
		return;
	} else {
		// cancel submission, start validation
		e.stopPropagation();
		e.preventDefault();
		this.startValidation();
	}
}

cfw.validator.Context.prototype.startValidation = function() {

	if (this.running) return;

	this.running = true;
	this.finished = false;
	this.valid = false;

	var obj = this;

	dojo.io.bind({
		transport: 'XMLHTTPTransport',
		url: this.url,
		mimetype: 'text/json',
		preventCache: true,
		formNode: this.form,
		formFilter: dojo.lang.hitch(this, "formFilter"),
		encoding: 'utf-8',
		content: { page: this.action },
		load: function(type, evaledObj) { obj.handleValidationResult(evaledObj); }
		// load: function(type, evaledObj) { alert(evaledObj); }
	});

}

cfw.validator.Context.prototype.handleValidationResult = function(result) {
	this.running = false;
	this.finished = true;

	if (result.status.valid && this.autosubmit) {
		this.valid = true;
		if (this.clickedButton) this.clickedButton.click();
		else this.form.submit();
	}

	cfw.validator.displayValidationResult(this.form, result);
}



