module.exports = new Class({
	Extends: Vn.Object
	
	,isOpen: false
	,uiLoaded: false

	,initialize(gui) {
		this.gui = gui;
		this.conn = gui.conn;
		this.hash = gui.hash;
	}
	
	,async loadUi() {
		if (!this.isOpen)
			return;

		const conn = this.conn;
		const hash = this.hash;
	
		const builder = new Vn.Builder();
		builder.compileString(this.$constructor.Template.default);

		const scope = this.scope = this.builder = builder.load(null, this);
		this.$ = scope.$;
		scope.link({conn, hash});
		this.node = scope.$.form;
		this.node.$ctrl = this;

		const paramsLot = this.$.params;
		if (paramsLot) {
			paramsLot.source = hash;
			this.params = paramsLot;
		}

		function setConnection(tagName) {
			const objects = scope.getByTagName(tagName);
			for (let i = 0; i < objects.length; i++)
				objects[i].conn = conn;
		}

		const tags = ['db-model', 'db-query', 'db-lot'];
		for (let i = 0; i < tags.length; i++)
			setConnection(tags[i]);
			
		if (this.node) {
			this.gui.setForm(this.node);
			this.gui.setTitle(scope.$.title);
			this.gui.setActions(scope.$.actions);
			await this.activate();
		}
		
		this.uiLoaded = true;
	}
	
	,async unloadUi() {
		if (!this.uiLoaded)
			return;

		if (this.node) {
			await this.deactivate();
			this.gui.setTitle(null);
			this.gui.setActions(null);
			Vn.Node.remove(this.node);
			await this.deactivate();
			this.node = null;
		}
		if (this.builder) {
			this.builder.unref();
			this.builder = null;
		}
	}

	/**
	 * Called when the form is opened.
	 */
	,async open() {
		await this.close();
		this.isOpen = true;
		await this.loadUi();
	}

	/**
	 * Called when the form is closed.
	 */
	,async close() {
		if (!this.isOpen) return;
		this.isOpen = false;
		await this.unloadUi();
	}
	
	/**
	 * Called when the form is activated.
	 */
	,async activate() {}
	
	/**
	 * Called when the form is deactivated.
	 */
	,async deactivate() {}

	,_destroy() {
		this.close();
		if (this.scope) this.scope._destroy();
		Vn.Object.prototype._destroy.call(this);
	}
});