var Assert = require('assert');

/**
* A class for managing UI elements.
*/
class UIController {
	constructor(elems) {
		this.event_running = false;
		this.elems = elems;

		for (let e of Object.values(elems)) {
			e.init(this);
		}
	}

	/**
	* Execute a function on all elements of this UIController.
	*
	* @param {function} func The function to execute. This function is added
	*                        to each UIElem object, executed and then removed.
	* @param {object}   data Data to pass to 'func'.
	* @param {string}   type Only execute 'func' on a specific type of elements.
	*                        This should match one of the type strings defined
	*                        in each class extending UIElem. Leave this null to
	*                        execute 'func' on all elements.
	*/
	all(func, data, type) {
		var ret = true;
		for (let k of Object.keys(this.elems)) {
			if (type == null || this.elems[k].type == type) {
				this.elems[k]._tmp = func;
				ret = this.elems[k]._tmp(data);
				this.elems[k]._tmp = null;
				if (ret == false) { break; }
			}
		}
	}

	event_set_fired()    { this.event_running = true;  }
	event_set_finished() { this.event_running = false; }
	is_event_running()   { return this.event_running;  }

	/**
	* Add an element.
	*
	* @param {string} name The name to use for the element.
	* @param {UIElem} elem The element object.
	*/
	add(name, elem) { this.elems[name] = elem; }

	/**
	* Remove an element.
	*
	* @param {string} name The name of the element to remove.
	*/
	rm(name) { delete this.elems[name]; }

	/**
	* Remove all elements.
	*/
	rm_all() { this.elems = {}; }

	/**
	* Get an element.
	*
	* @param {string} name The name of the element to get.
	*
	* @return {UIElem} The requested element object.
	*/
	get(name) { return this.elems[name]; }
}
module.exports = UIController;
