require('./style.scss');
var ColumnText = require('../columns/text');

module.exports = new Class({
	Extends: Htk.Field
	,Implements: Db.Iterator
	,Tag: 'htk-combo'
	,Properties: {
		/**
		 * The model associated to this form.
		 */
		model: {
			type: Db.Model
			,set(x) {
				this.link({_model: x}, {'status-changed-after': this._onModelChange});
				this._onModelChange();
			}
			,get() {
				return this._model;
			}
		},
		/**
		 * The row where the form positioned, has -1 if the row is unselected.
		 */
		row: {
			type: Number
			,set(x) {
				if (!this._model || this._model.numRows <= x || x < -1)
					x = -1;
				if (x == this._row)
					return;

				this._row = x;
				this.iterChanged();
			}
			,get() {
				return this._row;
			}
		},
		/**
		 * The number of rows in the form.
		 */
		numRows:{
			type: Number
			,get() {
				if (this._model)
					return this._model.numRows;

				return 0;
			}
		},
		/**
		 * Checks if the form data is ready.
		 */
		ready:{
			type: Boolean
			,get() {
				return this._model && this._model.ready;
			}
		},
		/**
		 * Checks if the form data is ready.
		 */
		placeholder:{
			type: String
			,set(x) {
				this._placeholder = x;
				this._refreshShowText(x);
			}
			,get() {
				return this._placeholder;
			}
		},
		/**
		 * Wether to allow null values.
		 */
		notNull:{
			type: Boolean
			,set(x) {
				this._notNull = x;
			}
			,get() {
				return this._notNull;
			}
		},
		/**
		 * The row object.
		 */
		$: {
			type: Object
			,get() {
				return this._model.getObject(this._row) || {};
			}
		},
		params: {
			type: Object
			,get() {
				return this.$;
			}
		}
	}
	
	,_row: -1
	,_model: null
	,valueColumnIndex: 0
	,valueColumnName: null
	,showColumnIndex: 1
	,showColumnName: null
	,_notNull: true
	,_webkitRefresh: false

	,render() {
		const button = this.createRoot('button');
		button.type = 'button';
		button.classList.add('input');
		button.addEventListener('mousedown',
			e => this._onButtonMouseDown(e));

		this.label = this.createElement('span');
		button.appendChild(this.label);

		const erase = new Htk.Icon({
			name: 'close',
			title: _('Erase')
		});
		erase.classList.add('erase');
		erase.addEventListener('mousedown',
			e => this._onEraseMouseDown(e));
		button.appendChild(erase.node);

		const dropDown = new Htk.Icon({
			name: 'expand_more'
		});
		button.appendChild(dropDown.node);
	}
	
	,_setRow(row) {
		this._row = row;
		this._refreshShowText();
		this.iterChanged();
	}
	
	,_onButtonMouseDown(event) {
		if (this._popup) {
			this._popup.hide();
			return;
		}

		if (event.defaultPrevented) return;
		event.preventDefault();
	
		var model = this._model;

		var menu = this.createElement('div');
		menu.className = 'htk-select-menu';
		
		var grid = new Htk.Grid({showHeader: false});
		menu.appendChild(grid.node);
		
		var gridNode = grid.node;
		gridNode.addEventListener('click', this._onGridClicked.bind(this, grid));
		
		var column = new ColumnText({columnIndex: this.showColumnIndex});
		grid.appendColumn(column);
		grid.model = model;
		
		var popup = this._popup = new Htk.Popup({childNode: menu});
		popup.on('closed', this._onPopupClose.bind(this));
		popup.show(this.node, event);

		this.emit('menu-show');
	}
	
	,_onGridClicked(grid, e) {
		let cell;
		let target = e.target;
		
		while (target !== grid.tbody) {
			cell = target;
			target = target.parentNode;
		}

		if (!cell) return;

		let value;
		const row = cell.rowIndex - 1;

		if (row >= 0)
			value = this._model.getByIndex(row, this.valueColumnIndex);
		else
			value = null;

		this._setMyValue(row, value);
		this._popup.hide();
		
		e.stopPropagation();
	}

	,_onEraseMouseDown(event) {
		if (event.defaultPrevented) return;
		event.preventDefault();
		this._setMyValue(-1, undefined);
	}

	,_setMyValue(row, value) {
		this._myValue = value;
		this._setRow(row);
		this.valueChanged(value);
	}
	
	,_onPopupClose() {
		this._popup = null;
		this.emit('menu-hide');
	}
	
	,_refreshShowText() {
		const model = this._model;
		let showText = '';

		if (this._row !== -1)
			showText = model.getByIndex(this._row, this.showColumnIndex);
		else if (model && model.status === Db.Model.Status.LOADING)
			showText = _('Loading...');
		else if (this._myValue != null)
			showText = this._myValue;
		else if (this._placeholder)
			showText = this._placeholder;

		Vn.Node.setText(this.label, showText);
	}
	
	,_onModelChange() {
		var model = this._model;
		this.emit('status-changed');
		
		if (this._popup)
			this._popup.reset();

		if (model && model.ready) {
			this._selectOption();
			this.emit('ready');
		} else
			this._setRow(-1);
	}
	
	,setEditable(editable) {
		this.node.disabled = !editable;
	}

	,_selectOption() {
		var row;
	
		if (this._model && this._model.ready)
			row = this._model.searchByIndex(this.valueColumnIndex, this._myValue);
		else
			row = -1;

		this._setRow(row);
	}

	,putValue() {
		this._myValue = this._value;
		this._selectOption();
	}
});