/*
 *  Copyright 2015 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Initialize forms to register forms tags to the inline editor
 */
Ext.define('Ametys.plugins.forms.content.Conversions', {
    statics: {
        /**
         * @private
         * @property {Boolean} _initialized Has the richtextconfiguration been initialized
         */
        _initialized: false,
        
        /**
         * Create the html for an input 
         * @param {String} name the name of the input
         * @param {String} id the id of the input
         * @param {String} attributes additional attributes
         * @return the html of the input 
         */
        createHTML: function(name, id, attributes)
        {
            return '<img ' + (name != null ? ('name="' + name + '" ') : '') 
                              + (id != null ? ('id="' + id + '" ') : '') 
                              + attributes + ' src="' + Ametys.getPluginResourcesPrefix('forms') + '/img/edition/trans.gif" form="form" marker="marker"/>';
        },
        
        /**
         * Encode the attributes of the given input string
         * @param {String} str the input string
         * @return the encoded string
         */
        encodeAttributes: function(str)
        {
            if (str == null)
            {
                return null;
            }
            return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "&#13;");
        },
        
        /**
         * Decode the attributes of the given input string
         * @param {String} str the input string
         * @return the decoded string
         */
        decodeAttributes: function(str)
        {
            if (str == null)
            {
                return null;
            }
            return str.replace(/&#13;/g, "\n").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
        }        
    },
    
    constructor: function(config)
    {
        config = config || {}
        config.layoutclasses = config.layoutclasses || {};
        
        var values = Ext.Array.from(config.layoutclasses.value);
        Ext.Array.forEach(values, function(value) {
            Ametys.plugins.forms.content.Layout.registerLayoutCSS(value);
        });        
    
        if (!Ametys.plugins.forms.content.Conversions._initialized)
        {
    		Ametys.form.widget.RichText.RichTextConfiguration.on('keypress', Ext.bind(this._onKeyPressUpdateCaret, this));
            
            if (tinymce.isGecko || tinymce.isWebKit) 
            {
    			Ametys.form.widget.RichText.RichTextConfiguration.on('setcontent', Ext.bind(this._fixTableCaretPos, this));
    			Ametys.form.widget.RichText.RichTextConfiguration.on('keyup', Ext.bind(this._fixTableCaretPos, this));
        		Ametys.form.widget.RichText.RichTextConfiguration.on('visualaid', Ext.bind(this._fixTableCaretPos, this));
            }
            
    		if (tinymce.isGecko) 
    		{
    			Ametys.form.widget.RichText.RichTextConfiguration.on('keydown', Ext.bind(this._onKeyDownUpdateCaret, this));
    			Ametys.form.widget.RichText.RichTextConfiguration.on('preprocess', Ext.bind(this._onPreProcessUpdateCarret, this));
    		}
            
            Ametys.plugins.forms.content.Conversions._initialized = true;
        }
    },
    
	/**
	 * @private
	 * Is the given element a start ?
	 * @param {Object} rng the browser's internal range object.
	 * @param {HTMLElement} el the element to start from
	 * @return true if the given element matches a start, false otherwise
	 */
	_isAtStart: function(rng, el) 
	{
		var doc = el.ownerDocument, rng2 = doc.createRange(), elm;
	
		rng2.setStartBefore(el);
		rng2.setEnd(rng.endContainer, rng.endOffset);
	
		elm = doc.createElement('body');
		elm.appendChild(rng2.cloneContents());
	
		// Check for text characters of other elements that should be treated as content
		return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length == 0;
	},

	/**
	 * @private
	 * Fix the position of the table carret
	 * @param {Ext.form.Field} field the editor field
	 * @param {tinymce.Editor} editor The tinymce editor 
	 */
	_fixTableCaretPos: function(field, editor) 
	{
		var last;
		
		// Skip empty text nodes from the end
		for (last = editor.getBody().lastChild; last && last.nodeType == 3 && !last.nodeValue.length; last = last.previousSibling) ;
		
		if (last && last.nodeName == 'DIV' && last.getAttribute("form") == "form")
		{
			editor.dom.add(editor.getBody(), 'p', null, '<br mce_bogus="1" />');
		}
	},
	
	/**
	 * @private
	 * Update the carret on key up event
	 * @param {Ext.form.Field} field the editor field
	 * @param {tinymce.Editor} editor the tinymce editor
	 * @param {Ext.event.Event} event the keypress event
	 */
	_onKeyPressUpdateCaret: function(field, editor, event)
	{
		if (event.keyCode == 13 || event.charCode == 13) 
		{
			if (tinymce.isGecko) 
			{
				var rng = editor.selection.getRng();

				if (rng.startContainer && ed.getBody() == rng.startContainer && /^div$/i.test(editor.selection.getStart().nodeName) && editor.selection.getStart().getAttribute("form") == "form") 
				{
					ed.execCommand('mceInsertContent', false, '<p><br mce_bogus="1"/></p>');

					return tinymce.dom.Event.cancel(event);
				}
			}
			else if (tinymce.isIE)
			{
				var sel = editor.selection;
				if (/^div$/i.test(sel.getStart().nodeName) && sel.getStart().getAttribute("form") == "form")
				{
					tinyMCE.insertHTMLAtRoot('<p><br mce_bogus="1"/></p>', 'before');
					
					return tinymce.dom.Event.cancel(event);
				}
			}
		}
	},
	
	/**
	 * @private
	 * Update the carret in key down event
	 * @param {Ext.form.Field} field the editor field
	 * @param {tinymce.Editor} editor the tinymce editor
	 * @param {Ext.event.Event} event the keypress event
	 */
	_onKeyDownUpdateCaret: function(field, editor, event)
	{
		var rng, table, dom = editor.dom;

		// On gecko it's not possible to place the caret before a table
		if (event.keyCode == 37 || event.keyCode == 38) 
		{
			rng = editor.selection.getRng();
			table = dom.getParent(rng.startContainer, 'div');

			if (table) 
			{
				if (this._isAtStart(rng, table)) 
				{
					rng = dom.createRng();

					rng.setStartBefore(table);
					rng.setEndBefore(table);

					editor.selection.setRng(rng);
					
					event.preventDefault();
				}
			}
		}
	},
	
	/**
	 * @private
	 * Handler invoked when the editor pre processes the serialization
	 * @param {Ext.form.Field} field the editor field
	 * @param {tinymce.Editor} editor the tinymce editor
	 * @param {Object} object the object
	 */
	_onPreProcessUpdateCarret: function(field, editor, object) 
	{
		var last = object.node.lastChild;

		if (last && last.childNodes.length == 1 && last.firstChild.nodeName == 'BR')
		{
			editor.dom.remove(last);
		}
	},
	
    /**
     * Registered to intercept getContent on richtext
     * @param {Ametys.form.field.RichText} field The richtext to convert
     * @param {tinymce.Editor} editor The current richtext editor
     * @param {Object} object The object of value to be modified
     */
	onGetContent: function(field, editor, object)
	{
		if (object.from === 'char-counter') return;
		
		var regexpGetContentFormFull = new RegExp("<div[^>]* form=\"form\"[^>]*>"
											         + "("
														+ "((?!<div[^>]*>)(?!<\/div>)(.|\n))"
														+ "|" 
                                                        + "(<div[^>]*>"
															+ "((?!<\/div>)(.|\n))*"
														+ "<\/div>)"
													 + ")*"
												  + "<\/div>", "g");
		object.content = object.content.replace(
				regexpGetContentFormFull, 
				function (s) 
				{
					return s.substring(0, s.length - 6) + "</form>";
				}
		);
		
		var regexpGetContentForm = /<div[^>]* form="form"[^>]*>/g;
		object.content = object.content.replace(
				regexpGetContentForm, 
				function (s) 
				{
					var type = /type="cms"/.test(s) ? ' type="cms"' : '';
					var target = /target="_blank"/.test(s) ? ' target="_blank"' : '';
					
					var id = /id="([^"]*)"/.test(s) ? (' id="' + RegExp.$1 + '"') : '';
					var action = (type == '' && /form_action="([^"]*)"/.test(s)) ? (' action="' + RegExp.$1 + '"') : '';
					var label = (type != '' && /form_name="([^"]*)"/.test(s)) ? (' label="' + RegExp.$1 + '"') : '';
					var processingEmails = (type != '' && /form_processing_emails="([^"]*)"/.test(s)) ? (' processing_emails="' + RegExp.$1 + '"') : '';
					var receiptTo = (type != '' && /form_receipt_to="([^"]*)"/.test(s)) ? (' receipt_to="' + RegExp.$1 + '"') : '';
					var receiptFrom = (type != '' && /form_receipt_from="([^"]*)"/.test(s)) ? (' receipt_from="' + RegExp.$1 + '"') : '';
					var receiptSubject = (type != '' && /form_receipt_subject="([^"]*)"/.test(s)) ? (' receipt_subject="' + RegExp.$1 + '"') : '';
					var receiptBody = (type != '' && /form_receipt_body="([^"]*)"/.test(s)) ? (' receipt_body="' + RegExp.$1 + '"') : '';
					var redirect = (type != '' && /form_redirect="([^"]*)"/.test(s)) ? (' redirect="' + RegExp.$1 + '"') : '';
					var workflow = (type != '' && /form_workflow="([^"]*)"/.test(s)) ? (' workflow="' + RegExp.$1 + '"') : '';
                    var limit = (type != '' && /form_limit="([^"]*)"/.test(s)) ? (' limit="' + RegExp.$1 + '"') : '';
                    var places = (type != '' && /form_places="([^"]*)"/.test(s)) ? (' places="' + RegExp.$1 + '"') : '';
                    var noPlaces = (type != '' && /form_no_places="([^"]*)"/.test(s)) ? (' no_places="' + RegExp.$1 + '"') : '';
					
					var cssClass = '';
	                var handledCssClass = Ametys.plugins.forms.content.Layout.getHandledLayoutClass();
	                if (/class="([^"]*)"/.test(s))
	                {
	                    var filteredClass = [];
	                    var values = RegExp.$1.split(" ");
	                    for (var i=0; i < values.length; i++)
		                {
		                    if (handledCssClass.indexOf(values[i]) != -1)
		                    {
		                        filteredClass.push(values[i]);
		                    }
		                }
	                   
	                    cssClass = ' class="' + filteredClass.join(' ') + '"';
	                }
	                
					if (/layout="([^"]*)"/.test(s))
                    {
                        // empty
                    }
					var layout = RegExp.$1;

					return '<form' + type + target + label + action + id + redirect + receiptTo + receiptFrom + receiptSubject + receiptBody + limit + places + noPlaces + processingEmails + cssClass + workflow + ' layout="' + layout + '">';
				}
		);

		var regexpGetContentCmp = /<img[^>]* form="form"[^>]*>/g;
		object.content = object.content.replace(
				regexpGetContentCmp, 
				function (s) 
				{
					var id = / id="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var name = / name="([^"]*)"/.test(s) ? RegExp.$1 : "";

					var className = / class="([^"]*)"/.test(s) ? RegExp.$1 : "form_input_text";
					var maxsize = / form_maxfilesize="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var fileextension = / form_fileextension="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var minvalue = / form_minvalue="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var maxvalue = / form_maxvalue="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var regexptype = / form_regexptype="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var autofill = / form_autofill="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var regexp = / form_regexp="([^"]*)"/.test(s) ? RegExp.$1 : "";
					

					var style = / style="([^"]*)"/.test(s) ? RegExp.$1 : null;
					var width = /width: ?([0-9]*)px/.test(style) ? RegExp.$1 : (/ width="([^"]*)"/.test(s) ? RegExp.$1 : "100");
					var height = /height: ?([0-9]*)px/.test(style) ? RegExp.$1 : (/ height="([^"]*)"/.test(s) ? RegExp.$1 : "20");

					
					var value = / form_value="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var mandatory = / mandatory="mandatory"/.test(s) ? "true" : "false";
                    var partofcost = / partofcost="partofcost"/.test(s) ? "true" : "false";
                    var unitcost = / form_unitcost="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var checked = / checked="checked"/.test(s) ? "true" : "false";
					var confirmation = / confirmation="confirmation"/.test(s) ? "true" : "false";
					var multiple = / multiple="multiple"/.test(s) ? "true" : "false";
					
					var placeholder = / form_placeholder="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var description = / form_description="([^"]*)"/.test(s) ? RegExp.$1 : "";
					
					function generateOptions(value)
					{
						var s = "";
						
						if (value == "")
						{
							return s;
						}
						
						var values = value.split("\n");
						for (var i = 0; i < values.length; i++)
						{
                            var vs = values[i].split(";");
                            
							var l = vs[0];
							var v = vs.length > 1 ? vs[1] : null;
                            var c = vs.length > 2 ? vs[2] : 0;
							
							s += '<option' 
                                        + (v != null ? ' value="' + Ametys.plugins.forms.content.Conversions.encodeAttributes(v) + '"' : '') 
                                        + (partofcost ? ' cost="' + c + '"' : '') 
                                    + '>' 
                                    + Ametys.plugins.forms.content.Conversions.encodeAttributes(l) 
                                + '</option>';
						}
						
						return s;
					}

					switch (className)
					{
						case "form_input_text": 	return '<input type="text"' 		+ ' name="' + name + '" id="' + id + '" description="' + description + '" placeholder="' + placeholder + '" mandatory="' + mandatory + '" width="' + width + '" confirmation="' + confirmation + '" value="' + value + '" maxvalue="' + maxvalue + '" minvalue="' + minvalue + '" regexptype="' + regexptype + '" autofill="' + autofill + '" regexp="' + regexp + '"/>';
						case "form_input_submit": 	return '<input type="submit"' 		+ ' name="' + name + '" id="' + id + '" width="' + width + '" value="' + value + '"/>';
						case "form_input_reset": 	return '<input type="reset"' 		+ ' name="' + name + '" id="' + id + '" width="' + width + '" value="' + value + '"/>';
						
						case "form_input_password": return '<input type="password"' 	+ ' name="' + name + '" id="' + id + '" description="' + description + '" placeholder="' + placeholder + '" mandatory="' + mandatory + '" width="' + width + '" confirmation="' + confirmation + '" maxvalue="' + maxvalue + '" minvalue="' + minvalue + '" regexp="' + regexp + '"/>';
                        case "form_input_cost":     return '<input type="cost"'         + ' name="' + name + '" id="' + id + '" description="' + description + '" unitcost="' + unitcost +  '" width="' + width + '"/>';
						case "form_input_file": 	return '<input type="file"' 		+ ' name="' + name + '" id="' + id + '" description="' + description + '" mandatory="' + mandatory + '" width="' + width + '" maxsize="' + maxsize + '" fileextension="' + fileextension + '"/>';
						
						case "form_input_checkbox form_input_checkbox_checked":
						case "form_input_checkbox": return '<input type="checkbox"' 	+ ' name="' + name + '" id="' + id + '" description="' + description + '" mandatory="' + mandatory + '" value="' + value + '" checked="' + checked + '"/>';
						case "form_input_radio form_input_radio_checked":
						case "form_input_radio": 	return '<input type="radio"' 		+ ' name="' + name + '" id="' + id + '" mandatory="' + mandatory + '" value="' + value + '" checked="' + checked + '"/>';
						case "form_input_hidden": 	return '<input type="hidden"' 		+ ' name="' + name + '" id="' + id + '" value="' + value + '"/>';

						case "form_textarea": 		return '<textarea' 					+ ' name="' + name + '" id="' + id + '" description="' + description + '" placeholder="' + placeholder + '" mandatory="' + mandatory + '" width="' + width + '" height="' + height + '">' + value + '</textarea>';
						case "form_select_multiple":
						case "form_select": 		return '<select' 					+ ' name="' + name + '" id="' + id + '" description="' + description + '" placeholder="' + placeholder + '" mandatory="' + mandatory + '" partofcost="' + partofcost + '" width="' + width + '"' + (multiple == "true" ? ' height="' + height + '"' : '') + ' multiple="' + multiple + '">' 
															+ (value != null ? generateOptions(decodeURIComponent(value)) : '') 
															+ '</select>';

						case "form_captcha": 		return '<captcha' 				+ ' id="' + id + '" description="' + description + '" placeholder="' + placeholder + '" width="' + width + '" height="' + height + '" />';

						default: return "<!-- Unknown form element of classname " + className + "-->";
					}
				}
		);
	},

    /**
     * Registered to intercept setContent on richtext
     * @param {Ametys.form.field.RichText} field The richtext to convert
     * @param {tinymce.Editor} editor The current richtext editor
     * @param {Object} object The object of value to be modified
     */
	onSetContent: function (field, editor, object)
	{
		var me = this;
        
        if (!object.content)
        {
            return;
        }
		
		var regexpSetContentFormFull = /<\/form>/g;
		object.content = object.content.replace(
				regexpSetContentFormFull, 
				function(s) 
				{
					return "</div>";
				}
		);
		
		var regexpSetContentForm = /<form([^>]*)>/g;
		object.content = object.content.replace(
				regexpSetContentForm, 
				function(s) 
				{
					var type = (/type="cms"/.test(s)) ? ' type="cms"' : '';
					var target = (/target="_blank"/.test(s)) ? ' target="_blank"' : '';
					
					var action = (type == '' && (/action="([^"]*)"/.test(s))) ? (' form_action="' + RegExp.$1 + '"') : '';
					var label = (type != '' && (/label="([^"]*)"/.test(s))) ? (' form_name="' + RegExp.$1 + '"') : '';
					var id = /id="([^"]*)"/.test(s) ? (' id="' + RegExp.$1 + '"') : '';
					var processingEmails = (type != '' && (/processing_emails="([^"]*)"/.test(s))) ? (' form_processing_emails="' + RegExp.$1 + '"') : '';
					var receiptTo = (type != '' && (/receipt_to="([^"]*)"/.test(s))) ? (' form_receipt_to="' + RegExp.$1 + '"') : '';
					var receiptFrom = (type != '' && (/receipt_from="([^"]*)"/.test(s))) ? (' form_receipt_from="' + RegExp.$1 + '"') : '';
					var receiptSubject = (type != '' && (/receipt_subject="([^"]*)"/.test(s))) ? (' form_receipt_subject="' + RegExp.$1 + '"') : '';
					var receiptBody = (type != '' && (/receipt_body="([^"]*)"/.test(s))) ? (' form_receipt_body="' + RegExp.$1 + '"') : '';
					var redirect = (type != '' && (/redirect="([^"]*)"/.test(s))) ? (' form_redirect="' + RegExp.$1 + '"') : '';
					var formWorkflow = (type != '' && (/workflow="([^"]*)"/.test(s))) ? (' form_workflow="' + RegExp.$1 + '"') : '';
					var initialFormWorkflow = (type != '' && (/workflow="([^"]*)"/.test(s))) ? (' initial_form_workflow="' + RegExp.$1 + '"') : '';
					var limit = (type != '' && (/limit="([^"]*)"/.test(s))) ? (' form_limit="' + RegExp.$1 + '"') : '';
                    var places = (type != '' && (/places="([^"]*)"/.test(s))) ? (' form_places="' + RegExp.$1 + '"') : '';
                    var noPlaces = (type != '' && (/no_places="([^"]*)"/.test(s))) ? (' form_no_places="' + RegExp.$1 + '"') : '';
                     
					/layout="([^"]*)"/.test(s);
					var layout = RegExp.$1;

					/class="([^"]*)"/.test(s);
			        var cssClass = RegExp.$1;
        
					regexpSetContentForm.test(s);
					return '<div form="form" class="form' + (type != '' ? ' cmsForm' : '') + (cssClass != '' ? ' ' + cssClass : '') + '"' + type + id + target + processingEmails + redirect + receiptTo + receiptFrom + receiptSubject + receiptBody + limit + places + noPlaces + action + label + formWorkflow + initialFormWorkflow + ' layout="' + layout + '">';
				}
		);

		var regexpSetContentFormInput = /<input([^>]*)\/>/g;
		object.content = object.content.replace(
				regexpSetContentFormInput, 
				function(s) 
				{
					var id = / id="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var name = / name="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var maxsize = / maxsize="([^"]*)"/.test(s) ? ' form_maxfilesize="' + RegExp.$1 + '"' : "";
					var fileextension = / fileextension="([^"]*)"/.test(s) ? ' form_fileextension="' + RegExp.$1 + '"' : "";
					var width = / width="([^"]*)"/.test(s) ? ' width="' + RegExp.$1 + '"' : '';
					var value = / value="([^"]*)"/.test(s) ? ' form_value="' + RegExp.$1 + '"' : '';
					var placeholder = / placeholder="([^"]*)"/.test(s) ? ' form_placeholder="' + RegExp.$1 + '"' : '';
					var description = / description="([^"]*)"/.test(s) ? ' form_description="' + RegExp.$1 + '"' : '';
                    var unitcost = / unitcost="([^"]*)"/.test(s) ? ' form_unitcost="' + RegExp.$1 + '"' : '';
					var type = / type="([^"]*)"/.test(s) ? RegExp.$1 : "text";
					var mandatory = / mandatory="true"/.test(s) ? ' mandatory="mandatory"' : '';
					var checked = (type == "radio" || type == "checkbox") && / checked="true"/.test(s) ? ' checked="checked"' : '';
					var confirmation = (type == "text" || type == "password") && / confirmation="true"/.test(s) ? ' confirmation="confirmation"' : '';
					var minvalue = (type == "text" || type == "password") && / minvalue="([^"]*)"/.test(s) ? ' form_minvalue="' + RegExp.$1 + '"' : '';
					var maxvalue = (type == "text" || type == "password") && / maxvalue="([^"]*)"/.test(s) ? ' form_maxvalue="' + RegExp.$1 + '"' : '';
					var regexp = (type == "text" || type == "password") && / regexp="([^"]*)"/.test(s) ? ' form_regexp="' + RegExp.$1 + '"' : '';
					var regexptype = type == "text" && / regexptype="([^"]*)"/.test(s) ? ' form_regexptype="' + RegExp.$1 + '"' : '';
					var autofill = type == "text" && / autofill="([^"]*)"/.test(s) ? ' form_autofill="' + RegExp.$1 + '"' : '';

					var additionnalCSS = "";
					if (checked != "" && type == "radio") 
					{
						additionnalCSS += " form_input_radio_checked";
					}
					else if (checked != "" && type == "checkbox") 
					{
						additionnalCSS += " form_input_checkbox_checked";
					}
					
					return Ametys.plugins.forms.content.Conversions.createHTML(name, id, 'class="form_input_' + type + additionnalCSS + '" input_' + type + '="input_' + type + '"' + width + value + placeholder + unitcost + description + maxsize + mandatory + confirmation + fileextension + minvalue + maxvalue + regexp + regexptype + autofill + checked);
				}
		);
		
		var regexpSetContentFormSelect = /<select([^>]*)((\/>)|(>(<option[^>]*>[^<]*<\/option>)*<\/select>))/g;
		object.content = object.content.replace(
				regexpSetContentFormSelect, 
				function(s) 
				{
					var id = / id="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var name = / name="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var multiple = / multiple="true"/.test(s) ? ' multiple="multiple"' : '';
					var mandatory = / mandatory="true"/.test(s) ? ' mandatory="mandatory"' : '';
                    var partofcost = / partofcost="true"/.test(s) ? ' partofcost="partofcost"' : '';
					var placeholder = / placeholder="([^"]*)"/.test(s) ? ' form_placeholder="' + RegExp.$1 + '"' : '';
					var description = / description="([^"]*)"/.test(s) ? ' form_description="' + RegExp.$1 + '"' : '';
					
					var width = / width="([^"]*)"/.test(s) ? ' width="' + RegExp.$1 + '"' : '';
					var height = / height="([^"]*)"/.test(s) ? ' height="' + RegExp.$1 + '"' : '';
					
					var value = "";
					s.replace(/<option( value="([^"]*)")?( cost="([^"]*)")? ?>([^<]*)<\/option>/g,
							function(s)
							{
								/<option( value="([^"]*)")?( cost="([^"]*)")? ?>([^<]*)<\/option>/g.test(s);
								if (value != "")
								{
									value += "\n";
								}
								var v_expr = RegExp.$1;
								var v = RegExp.$2;
                                var c_expr = RegExp.$3;
                                var c = RegExp.$4;
								var l = RegExp.$5;
								
								value += Ametys.plugins.forms.content.Conversions.decodeAttributes(l) 
                                    + (v_expr != '' ? ("; " + Ametys.plugins.forms.content.Conversions.decodeAttributes(v)) : ';')
                                    + (c_expr != '' ? ("; " + c) : ';0');
							}
					);
					var formvalue = value != '' ? ' form_value="' + encodeURIComponent(value) + '"' : '';

					return Ametys.plugins.forms.content.Conversions.createHTML(name, id, 'class="form_select' + (multiple != '' ? '_multiple' : '') + '" select="select"' + width + height + multiple + mandatory + partofcost + placeholder + description + formvalue);
				}
		);

		
		var regexpSetContentFormCaptcha = /<captcha[^>]*\/>/g;
		object.content = object.content.replace(
				regexpSetContentFormCaptcha, 
				function(s) 
				{
					var id = / id="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var width = / width="([^"]*)"/.test(s) ? ' width="' + RegExp.$1 + '"' : '';
					var height = / height="([^"]*)"/.test(s) ? ' height="' + RegExp.$1 + '"' : '';
					var placeholder = / placeholder="([^"]*)"/.test(s) ? ' form_placeholder="' + RegExp.$1 + '"' : '';
					var description = / description="([^"]*)"/.test(s) ? ' form_description="' + RegExp.$1 + '"' : '';
					
					return Ametys.plugins.forms.content.Conversions.createHTML(name, id, 'class="form_captcha" captcha="captcha"' + width + height + placeholder + description);
				}
		);
		
		var regexpSetContentFormTextarea = /<textarea[^>]*((\/>)|(>[^<]*<\/textarea>))/g;
		object.content = object.content.replace(
				regexpSetContentFormTextarea, 
				function(s) 
				{
					var id = / id="([^"]*)"/.test(s) ? RegExp.$1 : "";
					var name = / name="([^"]*)"/.test(s) ? RegExp.$1 : "";
					
					var style = "";
					var width = / width="([^"]*)"/.test(s) ? ' width="' + RegExp.$1 + '"' : '';
					var height = / height="([^"]*)"/.test(s) ? ' height="' + RegExp.$1 + '"' : '';
					
					var placeholder = / placeholder="([^"]*)"/.test(s) ? ' form_placeholder="' + RegExp.$1 + '"' : '';
					var description = / description="([^"]*)"/.test(s) ? ' form_description="' + RegExp.$1 + '"' : '';
					
					var value = />([^<]*)</.test(s) ? RegExp.$1 : '';
					var mandatory = / mandatory="true"/.test(s) ? ' mandatory="mandatory"' : '';
					
					return Ametys.plugins.forms.content.Conversions.createHTML(name, id, 'class="form_textarea" textarea="textarea"' + width + height + mandatory + placeholder + description + ' form_value="' + value + '"');
				}
		);
	}
});