/*
 *  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.
 */
/**
 * Custom layout.
 */
Ext.define('Ametys.plugins.forms.content.layout.Custom', {
	
	singleton: true,
	
	/**
	 * Unlock the custom layout
 	 * @param {Ametys.ribbon.element.ui.ButtonController} controller the controller calling this function
	 */
	act: function(controller)
	{
		if (!Ametys.plugins.forms.content.Layout._setLayoutOnNode(controller.getInitialConfig('value'), controller.getInitialConfig('css-class')))
		{
			return;
		}
		
		var tables = Ext.get(Ametys.plugins.forms.content.Forms._currentNode).select("table");
		for (var i = 0; i < tables.getCount(); i++)
		{
			tables.item(i).dom.removeAttribute("marker");
		}

		// nothing more to do
		if (Ametys.plugins.forms.content.Forms._currentNode.childNodes.length == 0)
		{
			this.create();
		}

		// FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
		tinyMCE.activeEditor.execCommand('mceSelectNode', false, Ametys.plugins.forms.content.Forms._currentNode.childNodes[0]);

		tinyMCE.activeEditor.focus();
	},
	
	/**
	 * Create the custom layout
	 */
	create: function()
	{
		var newP = tinyMCE.activeEditor.dom.doc.createElement("p");
		Ametys.plugins.forms.content.Forms._currentNode.appendChild(newP);
		var br = tinyMCE.activeEditor.dom.doc.createElement("br");
		br.setAttribute("_moz_dirty", "");
		newP.appendChild(br);
	},
	
	
	/**
	 * Insert an input text in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputText: function(name, id, inputHTML, labelHTML)
	{
	    // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
		tinyMCE.activeEditor.execCommand('mceBeginUndoLevel');
		if (labelHTML != null && labelHTML != "")
		{
			tinyMCE.activeEditor.execCommand('mceInsertContent', false, labelHTML);
		}
		tinyMCE.activeEditor.execCommand('mceInsertContent', false, inputHTML);
		tinyMCE.activeEditor.execCommand('mceEndUndoLevel');
		tinyMCE.activeEditor.execCommand('mceSelectNode', false, tinyMCE.activeEditor.dom.doc.getElementById(id));
	},
	
	/**
	 * Insert a text area in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertTextarea: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a select input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertSelect: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a captcha in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertCaptcha: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a checkbox in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputCheckbox: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a radio in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputRadio: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a password input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputPassword: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
    /**
     * Insert a cost field in the layout
     * @param {String} name the name of the input
     * @param {String} id the id of the input
     * @param {String} inputHTML the html for the input
     * @param {String} labelHTML the html for the label
     */
    insertInputCost: function(name, id, inputHTML, labelHTML) 
    {
        this.insertInputText(name, id, inputHTML, labelHTML);
    },
    
	/**
	 * Insert a file input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputFile: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert an hidden input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputHidden: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a submit input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputSubmit: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a reset input input in the layout
	 * @param {String} name the name of the input
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 * @param {String} labelHTML the html for the label
	 */
	insertInputReset: function(name, id, inputHTML, labelHTML) 
	{
		this.insertInputText(name, id, inputHTML, labelHTML);
	},
	
	/**
	 * Insert a fieldset in the layout
	 * @param {String} id the id of the input
	 * @param {String} inputHTML the html for the input
	 */
	insertFieldset: function(id, inputHTML)
	{
	    // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
		tinyMCE.activeEditor.execCommand('mceBeginUndoLevel');
		tinyMCE.insertHTMLAtRoot(inputHTML);
		tinyMCE.activeEditor.execCommand('mceEndUndoLevel');
		var fieldset = tinyMCE.activeEditor.dom.doc.getElementById(id);
		tinyMCE.activeEditor.execCommand('mceSelectNode', false, fieldset.childNodes[fieldset.childNodes.length - 1]);
	},
	
	/**
	 * Move the selected input up
	 * @param {HTMLElement} input the input to move
	 * @param {String} label the label
	 */
	moveUp: function(input, label)
	{
		var preceding = Ametys.plugins.forms.content.Layout._findPrevious(input);
		if (preceding != null)
		{
			if (preceding.previousSibling != null && preceding.previousSibling == Ametys.plugins.forms.content.Components._getLabel(preceding))
			{
				preceding = preceding.previousSibling;
			}
			
			preceding.parentNode.insertBefore(input, preceding);
			if (label != null)
			{
				preceding.parentNode.insertBefore(label, input);
			}
		}
	},
	
	/**
	 * Move the selected input down
	 * @param {HTMLElement} input the input to move
	 * @param {String} label the label
	 */
	moveDown: function(input, label)
	{
		var next = Ametys.plugins.forms.content.Layout._findNext(input);
		
		if (next != null)
		{
			if (next.nextSibling != null && next.nextSibling == Ametys.plugins.forms.content.Components._getLabel(next))
			{
				next = next.nextSibling;
			}
			
			next.parentNode.insertBefore(input, next.nextSibling);
			if (label != null)
			{
				next.parentNode.insertBefore(label, input);
			}
		}
	},
	
	/**
	 * Remove the selected input 
	 * @param {HTMLElement} input the input to remove
	 * @param {String} label the label
	 */
	remove: function(input, label)
	{
		if (Ametys.plugins.forms.content.Components._currentMovableNode != null)
		{
		    // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
			tinyMCE.activeEditor.execCommand('mceBeginUndoLevel');
			var label = Ametys.plugins.forms.content.Components._getLabel(Ametys.plugins.forms.content.Components._currentMovableNode);
			if (label != null)
			{
				label.parentNode.removeChild(label);
			}
			Ametys.plugins.forms.content.Components._currentMovableNode.parentNode.removeChild(Ametys.plugins.forms.content.Components._currentMovableNode);
			Ametys.plugins.forms.content.Components._currentMovableNode = null;
			tinyMCE.activeEditor.execCommand('mceEndUndoLevel');
		}
	}
});