
/*
 * WebCT95
 *
 * Copyright (C) 2003 Conseil Général du Val d'Oise. All Rights
 * Reserved.
 *
 * Developed by IDEALX S.A.S. and Business Decision
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
/*
 * Object for Form Dynamic
 * @param label the name of variable
 * @param nameForm the name of form
 * @param obj the div element in which print the output
 * @param parent the object parent of the form (like a request object)
 */
function Forms(label, nameForm, obj, parent) {
	this.obj = obj;
	this.label = label;
	this.data = null;
	this.nameForm = nameForm;
	this.info = null;
	this.infos = null;
	this.edited = false;
	this.parent = parent;
	this.isInBO = true;
	this.COLSPAN = 4;
	this.line = 1;
	this.classTable = "tabcontenu";
	this.classHead = "casecontenuentete";
	this.classCell = "casecontenu";
	this.classLink = "lientabcontenuon2";
	this.classInput = "saisie2";
	this.classRadio = "radio";
	this.types = {text:"Texte", textarea:"Zone de texte", mail:"Email", select:"Liste", radio:"Puce", checkbox:"Case \xe0 cocher", upload:"Upload", info:"Commentaire", separator:"S\xe9parateur"};
	/*
	* initialize the object with a separator and mail elements
	*/
	this.init = function () {
		this.data.elements = [{type:"separator", label:""}, new ElementText().create("mail")];
	};
	/*
	* print the object in the div
	*/
	this.printTab = function () {
		this.printInfo();
		this.setDuration();
		this.setConfirmation();
		var content = "<table class=\"" + this.classTable + "\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">" + this.printHeader();
		if (this.data.elements.length == 0) {
			this.init();
		}
		this.line = 1;
		for (var i in this.data.elements) {
			this.data.elements[i].pos = i;
			content += this.printLine(this.data.elements[i]);
		}
		content += this.printNewLine() + "</table>";
		this.obj.innerHTML = content;
	};
	/*
	* print the header of table
	*/
	this.printHeader = function () {
		var content = "<tr>";
		var tab = ["Nom du champ", "type", "position", "Action"];
		for (var i in tab) {
			content += "<td class=\"" + this.classHead + "\">" + tab[i] + "</td>";
		}
		content += "</tr>";
		return content;
	};
	/*
	* print one line of table
	* @param line the line to print
	*/
	this.printLine = function (line) {
		var color = (line.type == "separator") ? "style=\"background-color: #efe8ef\"" : "";
		var content = "<tr onmouseover=\"" + this.label + ".printInfo(" + this.label + ".getDescription(" + line.pos + "))\" onmouseout=\"" + this.label + ".printInfo();\">" + "<td class=\"" + this.classCell + this.line + "\" " + color + ">";
		if (line.edit) {
			content += "<input type=\"text\" name=\"label\" value=\"" + line.label + "\" class=\"" + this.classInput + "\" maxlength=\"100\"/>";
		} else {
			content += ((line.label != "") ? line.label : "<br/>");
		}
		content += "</td>" + "<td class=\"" + this.classCell + this.line + "\" " + color + ">";
		if (line.pos != 0 && line.edit) {
			content += this.printType(line);
		} else {
			content += this.types[line.type];
		}
		if (line.pos == 0 && line.edit) {
			content += "<input type=\"hidden\" name=\"type\" value=\"" + line.type + "\"/>";
		}
		content += "</td>" + "<td class=\"" + this.classCell + this.line + "\" " + color + ">";
		if (line.pos != 0 && line.pos < this.data.elements.length - 1) {
			content += "<a href=\"#\" onclick=\"" + this.label + ".move(" + line.pos + ",1);return false;\">" + "<img src=\"/assets/common/img/tridown.gif\" border=\"0\"/></a> ";
		}
		if (line.pos > 1) {
			content += "<a href=\"#\" onclick=\"" + this.label + ".move(" + line.pos + ",-1);return false;\">" + "<img src=\"/assets/common/img/triup.gif\" border=\"0\"/></a>";
		}
		content += "<br/></td>" + "<td class=\"" + this.classCell + this.line + "\" " + color + ">";
		if (!line.edit) {
			content += "<a href=\"#\" class=\"" + this.classLink + "\" onclick=\"" + this.label + ".edit(" + line.pos + ");return false;\">" + "Modifier</a> ";
		}
		if (line.pos > 1) {
			content += "<a href=\"#\" class=\"" + this.classLink + "\" onclick=\"" + this.label + ".suppress(" + line.pos + ");return false;\">" + "Supprimer</a> ";
		}
		content += "<br/></td>" + "</tr>";
		if (line.edit) {
			this.createControl(line);
			if (line.control) {
				content += line.control.printEdit() + this.printLinkValidate(line, color);
			}
		}
		this.line = this.line % 2 + 1;
		return content;
	};
	/*
	* print link to control the line
	* @param data
	* @param color of line
	*/
	this.printLinkValidate = function (data, color) {

		var content = "<tr><td class=\"" + this.classCell + this.line + "\" colspan=\"3\" " + color + "><br/></td>" + "<td class=\"" + this.classCell + this.line + "\" " + color + ">" + "<a href=\"\" onclick=\"" + this.label + ".save(" + data.pos + ");return false;\" class=\"" + this.classLink + "\">" + "Valider</a> " + "<a href=\"\" onclick=\"" + this.label + ".cancel(" + data.pos + ");return false;\" class=\"" + this.classLink + "\">Annuler</a></td></tr>";
		return content;
	};
	/*
	* print a new line
	*/
	this.printNewLine = function () {
		var content = "<tr>" + "<td class=\"" + this.classCell + this.line + "\">" + "<input type=\"text\" name=\"newLabel\" class=\"" + this.classInput + "\"  maxlength=\"100\"/>" + "</td>" + "<td class=\"" + this.classCell + this.line + "\">" + this.printType() + "</td>" + "<td class=\"" + this.classCell + this.line + "\"><br/></td>" + "<td class=\"" + this.classCell + this.line + "\">" + "<a href=\"#\" onclick=\"" + this.label + ".add();return false;\" class=\"" + this.classLink + "\">" + "Ajouter</a>" + "</td>" + "</tr>";
		return content;
	};
	/*
	* print the type of data
	* @param data
	*/
	this.printType = function (data) {
		var name = "type";
		if (!data) {
			data = {pos:-1, type:"text"};
			name = "newType";
		}
		var content = "<select name=\"" + name + "\" class=\"" + this.classInput + "\" onchange=\"" + this.label + ".changeType(" + data.pos + ",this);\">";
		for (var i in this.types) {
			var selected = (data.type == i) ? "selected" : "";
			content += "<option value=\"" + i + "\" " + selected + ">" + this.types[i] + "</option>";
		}
		content += "</select>";
		return content;
	};
	/*
	* create the control for the data
	* @param line
	*/
	this.createControl = function (line) {
		line.control = null;
		if (line.type == "separator") {
			line.control = new ElementSeparator(line, this);
		}
		if (line.type == "text") {
			line.control = new ElementText(line, this);
		}
		if (line.type == "mail") {
			line.control = new ElementText(line, this, "mail");
		}
		if (line.type == "textarea") {
			line.control = new ElementTextarea(line, this);
		}
		if (line.type == "upload") {
			line.control = new ElementUpload(line, this);
		}
		if (line.type == "radio") {
			line.control = new ElementItems(line, this);
		}
		if (line.type == "select") {
			line.control = new ElementItems(line, this);
		}
		if (line.type == "checkbox") {
			line.control = new ElementItems(line, this);
		}
		if (line.type == "info") {
			line.control = new ElementInfo(line, this);
		}
	};
	/*
	* move a line from pos. the sens is indicated by the sens
	* @param pos of line
	* @param sens (1 or -1)
	*/
	this.move = function (pos, sens) {
		setDocumentHasChanged(this.nameForm, "true");
		var tmp = this.data.elements[pos];
		this.data.elements[pos] = this.data.elements[pos + sens];
		this.data.elements[pos + sens] = tmp;
		this.printTab();
	};
	/*
	* print this line in mode edit
	* @param pos of line
	*/
	this.edit = function (pos) {
		for (var i in this.data.elements) {
			var edit = (pos == i) ? true : false;
			this.data.elements[i].edit = edit;
		}
		this.printTab();
	};
	/*
	* suppress a line from table
	* @param pos of line
	*/
	this.suppress = function (pos) {
		if (confirm("Voulez-vous supprimer cet \xe9l\xe9ment ?")) {
			setDocumentHasChanged(this.nameForm, "true");
			for (var i = pos; i < this.data.elements.length - 1; i++) {
				this.data.elements[i] = this.data.elements[i + 1];
			}
			this.data.elements.length--;
			this.printTab();
		}
	};
	/*
	* cancel the mode edit of a line
	* @param pos of line
	*/
	this.cancel = function (pos) {
		this.data.elements[pos].edit = false;
		this.printTab();
	};
	/*
	* save the modification for the line
	* @param pos of line
	* @param notPrint inidicate if must print the tab
	* @param edit indicate the flag edit
	*/
	this.save = function (pos, notPrint, edit) {

		setDocumentHasChanged(this.nameForm, "true");
		var form = this.getForm();
		var data = this.data.elements[pos];
		if (!edit) {
			edit = false;
		}
		data.edit = edit;
		data.label = form.label.value;

		if (form.type) {
			data.type = form.type.value;
		}
		if (data.control) {
			data.control.save(form);
		}
		if (!notPrint) {
			this.printTab();
		}
	};
	/*
	* save all field (before add a new field)
	*/
	this.saveAll = function () {
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			if (data.edit) {
				this.save(data.pos, true);
			}
		}
	};
	/*
	* add a new line
	*/
	this.add = function () {
		var form = this.getForm();
		var type = form.newType.value;
		if (type == "mail" && this.hasElementMail()) {
			showMessage("Il existe d\xe9j\xe0 un \xe9l\xe9ment de type 'Email', vous ne pouvez en ajouter un second.");
			return;
		}
		setDocumentHasChanged(this.nameForm, "true");
		this.saveAll();
		var data = new Object();
		switch (type) {
		  case "text":
		  case "mail":
			data = new ElementText().create(type);
			break;
		  case "textarea":
			data = new ElementTextarea().create();
			break;
		}
		data.label = form.newLabel.value;
		data.type = type;
		var pos = this.data.elements.length;
		this.data.elements[pos] = data;
		this.edit(pos);
	};
	/*
	* indicate if there is already a mail element
	*/
	this.hasElementMail = function () {
		for (var i in this.data.elements) {
			if (this.data.elements[i].type == "mail") {
				return true;
			}
		}
		return false;
	};
	/*
	* return the form
	*/
	this.getForm = function () {
		return eval("document.forms['" + this.nameForm + "']");
	};
	/*
	* change the type of a line
	* @param pos of line
	* @param obj the select object
	*/
	this.changeType = function (pos, obj) {
		if (this.data.elements[pos]) {
			var data = this.data.elements[pos];
			data.type = obj.options[obj.selectedIndex].value;
			this.save(pos, true, true);
			this.printTab();
		}
	};
	/*
	* print form to indicate required value
	* @param data
	*/
	this.printRequired = function (data) {
		var required = ["", "checked"];
		if (data.required) {
			required = ["checked", ""];
		}
		var content = "<tr><td class=\"" + this.classInput + "\">champ obligatoire : </td>" + "<td class=\"" + this.classInput + "\">" + "<input type=\"radio\" class=\"" + this.classRadio + "\" name=\"required\" value=\"true\" " + required[0] + "/>oui " + "<input type=\"radio\" class=\"" + this.classRadio + "\" name=\"required\" value=\"false\" " + required[1] + "/>non " + "</td>" + "</tr>";
		if(data.type == 'radio')
		{
			var alignment = ["", "checked"];
			if(data.alignment == 'h')
			{
				alignment = ["checked", ""];
			}
			return content + "<tr><td class=\"" + this.classInput + "\">Alignement : </td>" + "<td class=\"" + this.classInput + "\">" + "<input type=\"radio\" class=\"" + this.classRadio + "\" name=\"alignment\" value=\"v\" " + alignment[1] + "/>Vertical " + "<input type=\"radio\" class=\"" + this.classRadio + "\" name=\"alignment\" value=\"h\" " + alignment[0] + "/>Horizontal " + "</td>" + "</tr>";
		}
		else
			return content;
	};
	/*
	* print Information in fieldset helper
	* @param label the label of text to print
	*/
	this.printInfo = function (label) {
		if (!label) {
			label = "root";
		}
		var content = this.infos[label];
		if (!content) {
			content = label;
		}
		this.info.innerHTML = content;
	};
	/*
	* get the description of a line
	* @param pos of line
	*/
	this.getDescription = function (pos) {
		return "element #" + pos;
	};
	/*
	* set the duration for the form
	*/
	this.setDuration = function () {
		var form = this.getForm();
		for (var i = 0; i < form.duration.options.length; i++) {
			var option = form.duration.options[i];
			var selected = (this.data.duration == option.value) ? true : false;
			option.selected = selected;
		}
	};

	/*
	* read or get the duration
	*/
	this.getDuration = function () {
		var form = this.getForm();
		if (!form.duration) {
			alert("duration not found");
			return "";
		}
		if (form.duration.value) {
			return form.duration.value;
		} else {
			if (form.duration.length) {
				return form.duration[form.duration.selectedIndex].value;
			} else {
				0;
			}
		}
	};

	/*
	* read or get the duration
	*/
	this.getDurationType = function () {
		var form = this.getForm();
		if (!form.durationType) {
			//alert("durationType not found");
			return "";
		}
		if (form.durationType.value) {
			return form.durationType.value;
		}
	};

	/*
	* submit the form
	* @param form
	*/
	this.mySubmit = function (form) {
		form.body.value = this.createXml();
		//alert(form.body.value);
		return validateFormsManagementForm(form);
	};
	/*
	* create the xml for the form
	* @param att attributes to add for form tag
	*/
	this.createXml = function (att) {
		this.initData();
		var xml = "<form ";
		if (att) {
			for (var i in att) {
				xml += i + "=\"" + att[i] + "\" ";
			}
		}
		var confirm = this.getConfirmation();
		xml += ">" + this.getXmlTitle() + this.getXmlProperty("duration", this.getDuration()) + this.getXmlProperty("durationType", this.getDurationType()) + this.getXmlProperty("confirmName", confirm.name) + this.getXmlProperty("confirmMail", confirm.mail);
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			xml += data.control.getXml();
		}
		xml += "</separator></form>";
		return xml;
	};
	/*
	* decore xml element with the others attributes
	* @param xml
	* @param el data
	*/
	this.getXmlElement = function (xml, el) {
		return "<element><label>" + this.printCDATA(el.label) + "</label>" + xml + this.getXmlRequired(el) + this.getXmlAlignment(el) +"</element>";
	};
	/*
	* add required tag in the xml
	* @param el data
	*/
	this.getXmlRequired = function (el) {
		var xml = "";
		if (el.required) {
			xml = this.getXmlProperty("required", "true");
		}
		return xml;
	};

	this.getXmlAlignment = function (el) {
		var xml = "";
		xml = this.getXmlProperty("alignment", el.alignment);
		return xml;
	};
	/*
	* get the property tag
	* @param name of property
	* @param value of property
	*/
	this.getXmlProperty = function (name, value) {
		if (!value) {
			return "";
		}
		return "<property name=\"" + name + "\" value=\"" + value + "\"/>";
	};
	/*
	* get the value tag
	* @param el data
	*/
	this.getXmlValue = function (el) {
		var out = new Object();
		var last = "";
		for (var i in el.values) {
			var value = el.values[i];
			out[value.id] = this.printValue(value.value, value);
			last = value.value;
		}
		var value = this.getValue(el);
		if (!value || last == value) {
			return this.printAllValues(out);
		}
		this.edited = true;
		out[this.parent.getVersionId()] = this.printValue(value);
		return this.printAllValues(out);
	};
	/*
	* get the title tag
	*/
	this.getXmlTitle = function () {
		var form = this.getForm();
		var title = (form.title) ? form.title.value : this.data.title;
		return "<title>" + this.printCDATA(title) + "</title>";
	};
	/*
	* get the value from el
	* @param el data
	*/
	this.getValue = function (el) {
		var form = this.getForm();
		var value = form[el.name];
		if (!value || !value.value) {
			return null;
		} else {
			return value.value;
		}
	};
	/*
	* print the value for xml
	* @param value
	* @param obj
	*/
	this.printValue = function (value, obj) {
		var id = (obj && obj.id) ? obj.id : this.parent.getVersionId();
		var content = "<value id=\"" + id + "\" ";
		if (obj && obj.logo) {
			content += "logo=\"" + obj.logo + "\" ";
		}
		content += ">" + this.printCDATA(value) + "</value>";
		return content;
	};
	/*
	* print data for xml
	* @param value
	*/
	this.printCDATA = function (value) {
		return "<![CDATA[" + value + "]]>";
	};
	/*
	* print all values from tab
	* @param tab
	*/
	this.printAllValues = function (tab) {
		var out = "";
		for (var i in tab) {
			out += tab[i];
		}
		return out;
	};
	/*
	* set the name for element
	* @param el
	*/
	this.setName = function (el) {
		el.name = "field" + el.pos;
	};
	/*
	* valide the form
	*/
	this.validate = function () {
		this.initData();
		var valid = true;
		var error = "";
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			var separator = this.getSeparator(data);
			if (separator.rendered || this.isInBO) {
				data.control.validate();
				if (!data.validate) {
					valid = false;
					error += data.error;
				}
			}
		}
		if (!valid) {
			showMessage(error);
		}
		return valid;
	};
	
	this.validateBO = function () {
		this.initData();
		var valid = true;
		var error = "";
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			var separator = this.getSeparator(data);
			if (separator.rendered || this.isInBO) {
				data.control.validate();
				if (!data.validate) {
					valid = false;
					error += data.error;
				}
			}
		}
		
		return true;
	};
	/*this.isInBO=function(){
		for(var i in this.data.elements){
			var data=this.data.elements[i];
			if(data.type=='separator' && data.rendered){
				return false;
			}
		}
		return true;
	};*/
	/*
	* indicate if required
	* @param el
	* @parma value
	*/
	this.required = function (el, value) {
		if (!value && value != "") {
			value = this.getValue(el);
		}
		if (el.required && (!value || value == "")) {
			el.error += "Le champ \"" + el.label + "\" est obligatoire.\n";
		}
	};
	/*
	* get parent separator element for el
	* @param el
	*/
	this.getSeparator = function (el) {
		var pos = el.pos;
		while (this.data.elements[pos].type != "separator") {
			pos--;
		}
		return this.data.elements[pos];
	};
	/*
	* initialize the data with pos and control
	*/
	this.initData = function () {
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			data.pos = i;
			this.createControl(data);
		}
	};
	/*
	* render the next separator
	*/
	this.setRenderNextSeparator = function () {
		var rendered = false;
		for (var i in this.data.elements) {
			var data = this.data.elements[i];
			if (data.type == "separator") {
				var tmp = data.rendered;
				data.rendered = rendered;
				rendered = tmp;
			}
		}
		this.isInBO = false;
	};
	/*
	* render the previous separator
	*/
	this.setRenderPreviousSeparator = function () {
		var rendered = false;
		for (var i = this.data.elements.length - 1; i >= 0; i--) {
			var data = this.data.elements[i];
			if (data.type == "separator") {
				var tmp = data.rendered;
				data.rendered = rendered;
				rendered = tmp;
			}
		}
		this.isInBO = false;
	};
	/*
	* set values for input confirmation (name and mail)
	*/
	this.setConfirmation = function () {
		var form = this.getForm();
		//form.confirmName.value = this.data.confirmName;
		//form.confirmMail.value = this.data.confirmMail;
	};
	/*
	* read or get the confirmation
	*/
	this.getConfirmation = function () {
		var form = this.getForm();
		if (!form.confirmName) {
			alert("confirmName not found");
			return "";
		}
		if (!form.confirmMail) {
			alert("confirmMail not found");
			return "";
		}
		return {name:form.confirmName.value, mail:form.confirmMail.value};
	};
}

