/* Copyright (c) 2006 N2N Consulting Pte Ltd. All rights reserved. */

/**
 * @author Antonius Ng
 * 
 * $Id: AJAXForm.js,v 1.2 2007/06/16 09:57:21 tracy Exp $
 */

dojo.provide("n2n.AJAXForm");
dojo.require("dojo.lang.*");
dojo.require("dojo.validate");

/**
 * @class An AJAXFormField object.
 */
n2n.AJAXFormField = Class.create();
n2n.AJAXFormField.prototype = {

	initialize : function(type, id, name, label, size, form, validateFunction,
			rule, container) {
		this.type = type;
		this.id = id;
		this.label = label;
		this.name = name;
		this.form = form;
		this.value;
		this.size = size;
		this.validateFunction = validateFunction;
		this.rules = null;
		this.rules = new dojo.collections.SortedList();
		if (rule) {
			var ruleArray = rule.split(',');

			var len = ruleArray.length;
			for ( var i = 0; i < len; i++) {
				this.rules.add(ruleArray[i], true);
			}
		}
		if (!container) {
			container = document;
		}
		this.container = container;

		if (type == "select") {
			this.options = new dojo.collections.ArrayList();

			this.addOption = function(name, value, selected) {
				var opt = {};
				opt.name = name;
				opt.value = value;
				opt.selected = selected;
				this.options.add(opt);
			}
		}
	},

	paint : function() {
		var s = this.toHTML();

		this.container.write(s);
		this.register();
		if (this.toHTML2()) {
			this.paint2 = function() {
				var s = this.toHTML2();
				this.container.write(s);
			}
		}
	},

	register : function() {

		this.HTMLObject = document.getElementById(this.id);

		if (!this.HTMLObject) {
			return;
		}

		if (this.focus) {
			this.HTMLObject.focus();
		}
		this.HTMLObject.field = this;

		if (this.type == "password") {
			this.HTMLObject2 = document.getElementById(this.id + "2");
			this.HTMLObject2.field = this;
			this.getValue2 = function() {
				return document.getElementById(this.id + "2").value;
			}
		}

	},

	toHTML : function() {
		var s = "";

		if (this.type == "text") {
			s = s + "<input type=\"text\" id=\"" + this.id + "\" name=\""
					+ this.name + "\"";
			if (this.value) {
				s = s + " value=\"" + this.value + "\"";
			}
			if (this.size) {
				s = s + " style=\"width: " + this.size + "px;\"";
			}
			s = s
					+ " onClick=\"this.focus()\" onblur=\"this.field.validate()\"/>";
			s = s + "<span id=\"" + this.id
					+ "Progress\" style=\"display:none;\"><img src=\""
					+ this.form.progressImage + "\" height=\"15\"/></span>";
			s = s
					+ "<span style=\"border-bottom: solid 1px red; color: red;\" id=\""
					+ this.id + "Error\"></span>";
		} else if (this.type == "password") {
			s = s + "<input type=\"password\" id=\"" + this.id + "\" name=\""
					+ this.name + "\"";

			if (this.size) {
				s = s + " style=\"width: " + this.size + "px;\"";
			}
			s = s + " onClick=\"this.focus()\"/>";
			this.toHTML2 = function() {
				var s2 = "";
				s2 = s2 + "<input type=\"password\" id=\"" + this.id
						+ "2\" name=\"" + this.name + "2\"";

				if (this.size) {
					s2 = s2 + " style=\"width: " + this.size + "px;\"";
				}
				s2 = s2
						+ " onClick=\"this.focus()\" onblur=\"this.field.validate()\"/>";
				s2 = s2
						+ "<span style=\"border-bottom: solid 1px red; color: red;\" id=\""
						+ this.id + "Error\"></span>";
				return s2;
			}
		} else if (this.type == "hidden") {
		} else if (this.type == "select") {
			s = s + "<select id=\"" + this.id + "\">";
			var i;
			var n = this.options.size();
			for (i = 0; i < n; i++) {
				var opt = this.options.item(i);
				s = s + "<option value=\"" + opt.value + "\"";
				if (opt.selected) {
					s = s + " selected";
				}
				s = s + ">" + opt.name;
			}
			s = s + "</select>";
		} else if (this.type == "textarea") {
			s = s + "<textarea id=\"" + this.id + "\" name=\"" + this.name
					+ "\"";

			if (this.size) {
				s = s + " cols=\"50\" rows=\"" + this.size + "\"";
			}
			s = s
					+ " onClick=\"this.focus()\" onblur=\"this.field.validate()\">";

			if (this.value) {
				s = s + this.value;
			}
			s = s + "</textarea>";
			s = s + "<span id=\"" + this.id
					+ "Progress\" style=\"display:none;\"><img src=\""
					+ this.form.progressImage + "\" height=\"15\"/></span>";
			s = s
					+ "<span style=\"border-bottom: solid 1px red; color: red;\" id=\""
					+ this.id + "Error\"></span>";
		}
		return s;
	},
	setValue : function(value) {
		this.value = value;
	},

	getValue : function() {
		if (this.type == "hidden") {
			return this.value;
		} else {
			return document.getElementById(this.id).value;
		}
	},

	showError : function() {
		var keyList = this.rules.getKeyList();
		var key = "";
		var errorMsg = "Unknown Error";
		var len = keyList.length;
		for ( var i = 0; i < len; i++) {

			var bool = this.rules.item(keyList[i]);

			if (!bool) {
				key = keyList[i];
			}
		}

		if (key == "required") {
			errorMsg = "Field Required";
		} else if (key == "duplicate") {
			errorMsg = this.label + " Exists";
		} else if (key == "unmatch") {
			errorMsg = "Passwords Unmatch";
		}

		if (key != "") {
			var errBox = document.getElementById(this.id + "Error");
			errBox.innerHTML = errorMsg;
		}
	},

	validate : function() {
		if (!this.validateFunction) {
			return;
		}
		var errBox = document.getElementById(this.id + "Error");
		errBox.innerHTML = "";

		if (this.rules.contains("required")) {
			if (!this.validateRequired()) {
				this.rules.replace("required", false);
				return this.showError();
			} else {
				this.rules.replace("required", true);
			}
		}

		if (this.rules.contains("duplicate")) {
			if (!this.validateDuplicate()) {
				this.rules.replace("duplicate", false);
				return this.showError();
			} else {
				this.rules.replace("duplicate", true);
			}
		}

		if (this.type == "password") {
			if (!dojo.lang.isUndefined(this.getValue())
					&& !dojo.lang.isUndefined(this.getValue2())) {
				this.rules.replace("required", true);
				if (this.getValue() != this.getValue2()) {
					this.rules.replace("unmatch", false);
					return this.showError();
				} else {
					this.rules.replace("unmatch", true);
				}
			} else {
				this.rules.replace("required", false);
				return this.showError();
			}
		}
	},

	validateRequired : function() {
		// alert(this.id);
	return !dojo.lang.isUndefined(this.getValue())
},

validateDuplicate : function() {
	// To be overridden
	return true;
}

}

/**
 * @class An AJAXForm object.
 * 
 * Usage: var box = new n2n.AJAXForm("form_id","/submit");
 *  // set the properties of the box
 * box.addField('text','username',20,true,'required,duplicate');
 * box.addField('password',''password',20,true,'required');
 *  // draw the box box.paint();
 */
n2n.AJAXForm = Class.create();

n2n.AJAXForm.prototype = {

	initialize : function(id, url, rpcMethod, container) {

		this.id = id;

		this.jsonrpcjava = new n2n.JsonRpcJava(url);

		this.rpcMethod = rpcMethod;
		if (!container) {
			container = document;
		}
		this.container = container;

		this.fields = new dojo.collections.ArrayList();
		this.submitLabel = "OK";
	},

	progressImage : "/podcast/images/progress.gif",

	successMethod : function(data) {

		// To be overridden
		alert("Success!!");
	},
	loadingMethod : function(data) {

		// To be overridden
	},

	errorMethod : function(error) {
		// To be overridden
		alert(toJSON(error));
	},

	backMethod : function() {
		// To be overridden
		alert("Back button pressed!!");
	},

	addField : function(type, name, label, size, validate, rule, focus) {

		var field = new n2n.AJAXFormField(type, this.id + "_" + name, name,
				label, size, this, validate, rule, this.container);
		if (focus) {
			field.focus = focus;
		}
		this.fields.add(field);
		return field;
	},

	submit : function(synchronous, enableHistory) {
		loadJSON();
		
		var jsonProcedure = new n2n.JsonProcedure(this.rpcMethod);
		var spaceChar = " ";
		var len = this.fields.size();
		for ( var i = 0; i < len; i++) {
			var field = this.fields.item(i);

			if (field.rules.contains("required")) {

				if (dojo.lang.isUndefined(field.getValue())) {
					alert("Invalid " + field.label);
					return false;
				}
			}
			
			if (field.name != "password" && field.name != "username" && field.name == "msisdn") {
				var fieldValue = field.getValue();
				if (fieldValue.length > 20) {
					alert(field.label + " can not be greater than 20 characters.");
					return false;
				}
			}
			
			if (field.type == "email") {
				if (!dojo.validate.isEmailAddress(field.getValue(), '')) {
					alert(field.label + " is invalid.");
					return false;
				}
			}			
			
			if (field.type == "msisdn") {
				if (!dojo.validate.isInteger(field.getValue(), '')) {
					alert(field.label + " is invalid.");
					return false;
				}
				
				if (field.getValue().length > 19) {
					alert(field.label + " can not be contain more than 19 digits.")
				}
			}
			
			if (field.type == "username") {
				var fieldValue = field.getValue();
				for (var j = 0; j < fieldValue.length; j++) {
					if (spaceChar == fieldValue.charAt(j)) {
						alert(field.label + " is invalid.");
						return false;
					}
				}
				
				if (fieldValue.length > 12) {
					alert(field.label + " can not be greater than 12 characters.");
					return false;
				}
				
				if (fieldValue.length < 3) {
					alert(field.label + " can not be less than 3 characters.");
					return false;
				}
			}
			if (field.type == "password") {

				if (dojo.lang.isUndefined(field.getValue())) {
					alert("Invalid " + field.label);
					return false;
				}
				if (field.getValue() != field.getValue2()) {
					alert("Passwords do not match");
					return false;
				}
				var fieldValue = field.getValue();
				
				if (fieldValue.length > 20) {
					alert(field.label + " can not be greater than 20 characters.");
					return false;
				}
				
				if (fieldValue.length < 6) {
					alert(field.label + " can not be less than 6 characters.");
					return false;
				}
				
				if (fieldValue.indexOf(spaceChar) > -1) {
					alert(field.label + " is invalid.");
					return false;
				}
				
			}

			jsonProcedure.addParam(field.getValue());
		}

		if (synchronous) {
			jsonProcedure.synchronous = true;
		}
		if (enableHistory) {
			jsonProcedure.enableHistory = true;
			jsonProcedure.backMethod = this.backMethod;
		}
		jsonProcedure.loadingMethod = this.loadingMethod;
		jsonProcedure.successMethod = this.successMethod;
		jsonProcedure.errorMethod = this.errorMethod;

		this.jsonrpcjava.run(jsonProcedure);

	},
	setValue : function(key, value) {
		var i;
		var n = this.fields.size();

		for (i = 0; i < n; i++) {
			var field = this.fields.item(i);

			if (field.id == this.id + "_" + key) {
				field.setValue(value);

				return

			}
		}
	},

	paint : function() {
		var s = "";

		s = s + "<table id=\"" + this.id + "_table\">";
		var len = this.fields.size();

		for ( var i = 0; i < len; i++) {
			var field = this.fields.item(i);
			if (field.type == "hidden") {
				continue;
			}
			s = s + "<tr>";

			if (field.type == "text") {
				s = s + "<td>";
				s = s + field.label;
				s = s + "</td><td>";
				s = s + field.toHTML();
				s = s + "</td>";
			} else if (field.type == "password") {
				s = s + "<td>";
				s = s + field.label;
				s = s + "</td><td>";
				s = s + field.toHTML();
				s = s + "</td>";
				s = s + "</tr><tr>";
				s = s + "<td>";
				if (field.label2) {
					s = s + field.label2;
				}
				s = s + "</td><td>";
				s = s + field.toHTML2();
				s = s + "</td>";
			} else if (field.type == "select") {
				s = s + "<td>";
				s = s + field.label;
				s = s + "</td><td>";
				s = s + field.toHTML();
				s = s + "</td>";
			} else if (field.type == "textarea") {
				s = s + "<td>";
				s = s + field.label;
				s = s + "</td><td>";
				s = s + field.toHTML();
				s = s + "</td>";
			}
			s = s + "</tr>";
		}

		s = s + "<tr>";
		s = s + "<td>";
		s = s + "</td>";
		s = s + "<td align=\"left\">";
		s = s + "<input type=\"button\" value=\"" + this.submitLabel
				+ "\" onClick=\"document.getElementById(\'" + this.id
				+ "\').form.submit()\"/>";
		if (this.cancelLabel) {

			s = s + "<input type=\"button\" value=\"" + this.cancelLabel
					+ "\" onClick=\"document.getElementById(\'" + this.id
					+ "\').hide()\"/>";
		}
		s = s + "</td>";
		s = s + "</tr>";
		s = s + "</table>";
		document.getElementById(this.id).form = this;
		this.container.write(s);

		for ( var i = 0; i < len; i++) {

			var field = this.fields.item(i);
			field.register();
		}
	}
}
