/**
 * EGroupware eTemplate2 - JS Box object
 *
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
 * @package etemplate
 * @subpackage api
 * @link https://www.egroupware.org
 * @author Andreas Stöckel
 * @copyright EGroupware GmbH 2011-2021
 */

/*egw:uses
	/vendor/bower-asset/jquery/dist/jquery.js;
	et2_core_baseWidget;
*/


import {et2_register_widget, WidgetConfig} from "./et2_core_widget";
import {et2_baseWidget} from "./et2_core_baseWidget";
import {et2_IDetachedDOM} from "./et2_core_interfaces";
import {et2_readAttrWithDefault} from "./et2_core_xml";

/**
 * Class which implements box and vbox tag
 *
 * Auto-repeat: In order to get box auto repeat to work we need to have another
 * box as a wrapper with an id set.
 *
 * @augments et2_baseWidget
 */
export class et2_box extends et2_baseWidget implements et2_IDetachedDOM
{
	static readonly _attributes: any = {
		// Not needed
		"rows": {"ignore": true},
		"cols": {"ignore": true}
	};

	div: JQuery;

	/**
	 * Constructor
	 *
	 * @memberOf et2_box
	 */
	constructor(_parent, _attrs? : WidgetConfig, _child? : object)
	{
		super(_parent, _attrs, _child);

		this.div = jQuery(document.createElement("div"))
			.addClass("et2_" + this.getType())
			.addClass("et2_box_widget");

		this.setDOMNode(this.div[0]);
	}

	_createNamespace() : boolean
	{
		return true;
	}

	/**
	 * Overriden so we can check for autorepeating children.  We only check for
	 * $ in the immediate children & grandchildren of this node.
	 *
	 * @param {object} _node
	 */
	loadFromXML(_node) {
		if(this.getType() != "old-box")
		{
			return super.loadFromXML(_node);
		}
		// Load the child nodes.
		var childIndex = 0;
		var repeatNode = null;
		for (var i=0; i < _node.childNodes.length; i++)
		{
			var node = _node.childNodes[i];
			var widgetType = node.nodeName.toLowerCase();

			if (widgetType == "#comment")
			{
				continue;
			}

			if (widgetType == "#text")
			{
				if (node.data.replace(/^\s+|\s+$/g, ''))
				{
					this.loadContent(node.data);
				}
				continue;
			}

			// Create the new element, if no expansion needed
			var id = et2_readAttrWithDefault(node, "id", "");
			if(id.indexOf('$') < 0 || ['box', 'grid', 'et2-box'].indexOf(widgetType) == -1 && typeof customElements.get(widgetType) == "undefined")
			{
				this.createElementFromNode(node);
				childIndex++;
			}
			else
			{
				repeatNode = node;
			}
		}

		// Only the last child repeats(?)
		if(repeatNode != null)
		{
			var currentPerspective = this.getArrayMgr("content").perspectiveData;
			// Extra content
			for(childIndex; typeof this.getArrayMgr("content").data[childIndex] != "undefined" && this.getArrayMgr("content").data[childIndex]; childIndex++) {
				// Adjust for the row
				var mgrs = this.getArrayMgrs();
				for(var name in mgrs)
				{
					if(this.getArrayMgr(name).getEntry(childIndex))
					{
						this.getArrayMgr(name).setRow(childIndex);
					}
				}

				this.createElementFromNode(repeatNode);
			}

			// Reset
			for(var name in this.getArrayMgrs()) {
				this.getArrayMgr(name).setPerspectiveData(currentPerspective);
			}
		}
	}

	/**
	 * Code for implementing et2_IDetachedDOM
	 * This doesn't need to be implemented.
	 * Individual widgets are detected and handled by the grid, but the interface is needed for this to happen
	 *
	 * @param {array} _attrs array to add further attributes to
	 */
	getDetachedAttributes(_attrs)
	{
		_attrs.push('data');
	}

	getDetachedNodes()
	{
		return [this.getDOMNode()];
	}

	setDetachedAttributes(_nodes, _values)
	{
		if (_values.data)
		{
			var pairs = _values.data.split(/,/g);
			for(var i=0; i < pairs.length; ++i)
			{
				var name_value = pairs[i].split(':');
				jQuery(_nodes[0]).attr('data-'+name_value[0], name_value[1]);
			}
		}
	}

}

et2_register_widget(et2_box, ["vbox", "box", "old-box",]);

/**
 * Details widget implementation
 * widget name is "details" and can be use as a wrapping container
 * in order to make its children collapsible.
 *
 * Note: details widget does not represent html5 "details" tag in DOM
 *
 * <details>
 *		<widgets>
 *		....
 * <details/>
 *
 */
export class et2_details extends et2_box
{
	static readonly _attributes: any = {
		"toggle_align": {
			name: "Toggle button alignment",
			description:" Defines where to align the toggle button, default is right alignment",
			type:"string",
			default: "right"
		},
		title: {
			name: "title",
			description: "Set a header title for box and shows it next to toggle button, default is no title",
			type: "string",
			default: "",
			translate: true
		}
	};

	private title: JQuery;
	private span: JQuery;
	private readonly wrapper: JQuery;

	constructor(_parent, _attrs?: WidgetConfig, _child?: object) {
		super(_parent, _attrs, _child);

		this.div = jQuery(document.createElement('div')).addClass('et2_details');
		this.title = jQuery(document.createElement('span'))
			.addClass('et2_label et2_details_title')
			.appendTo(this.div);
		this.span = jQuery(document.createElement('span'))
				.addClass('et2_details_toggle')
				.appendTo(this.div);
		this.wrapper = jQuery(document.createElement('div'))
				.addClass('et2_details_wrapper')
				.appendTo(this.div);


		this._createWidget();
	}

	/**
	 * Function happens on toggle action
	 */
	_toggle ()
	{
		this.div.toggleClass('et2_details_expanded');
	}

	/**
	 * Create widget, set contents, and binds handlers
	 */
	_createWidget() {
		const self = this;

		this.span.on('click', function (e) {
			self._toggle();
		});

		//Set header title
		if (this.options.title) {
			this.title
				.click(function () {
					self._toggle();
				})
					.text(this.egw().lang(this.options.title));
		}

		// Align toggle button left/right
		if (this.options.toggle_align === "left") this.span.css({float:'left'});
	}

	getDOMNode(_sender)
	{
		if (!_sender || _sender === this)
		{
			return this.div[0];
		}
		else
		{
			return this.wrapper[0];
		}
	}
}
et2_register_widget(et2_details, ["details"]);