require('./style.scss');
var Component = require('vn/component');

/**
 * Class to handle popups.
 */
module.exports = new Class({
	Extends: Component
	,Tag: 'htk-popup'
	,Properties: {
		/**
		 * The popup child.
		 */
		child: { 
			type: Component
			,set(x) {
				this._child = x;
				this._setChildNode(x.node);
			}
			,get() {
				return this._child;
			}
		}
		/**
		 * The popup child Node.
		 */
		,childNode: { 
			type: Object
			,set(x) {
				this._child = null;
				this._setChildNode(x);
			}
			,get() {
				return this.node.firstChild;
			}
		}
		/**
		 * Indicates how the dialog must be displayed.
		 */
		,modal: { 
			type: Boolean
			,set(x) {
				this._modal = x;
			}
			,get() {
				return this._modal;
			}
		}
	}

	,_parent: null
	,_modal: false
	,_isOpen: false
	,_child: null

	,initialize(props) {
		this._bgMouseDownHandler = this._bgMouseDown.bind(this);
		Component.prototype.initialize.call(this, props);
	}
	
	,render() {
		this.createRoot('div');
	}

	,_setChildNode(childNode) {
		Vn.Node.removeChilds(this.node);
		this.node.appendChild(childNode);
	}

	,show(parent, event) {
		this._parent = parent;
		this._lastEvent = event;
		this.open();
	}

	,isModal() {
		return this._modal || Vn.isMobile();
	}
	
	,open() {
		if (this._isOpen) {
			this.reset();
			return;
		}
	
		this.node.addEventListener('mousedown', this._onMouseDown.bind(this));

		if (this.isModal()) {
			var bg = this._bg = this.createElement('div');
			bg.className = 'htk-background';
			bg.addEventListener('mousedown', this._bgMouseDownHandler);
			Htk.Toast.pushTop(bg);

			this.node.classList.add('modal');
			bg.appendChild(this.node);

			this.doc.body.appendChild(bg);
			setTimeout(this._onOpacityTimeout.bind(this), 0);
		} else {
			this.doc.addEventListener('mousedown', this._bgMouseDownHandler);
			this.doc.body.appendChild(this.node);
		}
		
		this._isOpen = true;
		this.reset();
		setTimeout(this._onResetTimeout.bind(this), 0);
	}
	
	,_onOpacityTimeout() {
		if (this._bg)
			this._bg.style.opacity = 1;
	}

	,_onResetTimeout() {
		this.reset();
	}
	
	,reset() {
		if (!this._isOpen)
			return;
			
		var node = this._node;

		var style = node.style;
		style.height = '';
		style.width = '';

		if (!this.isModal()) {
			var margin = 20;
			var dblMargin = margin * 2;
			var width = node.offsetWidth;
			var height = node.offsetHeight;
			var innerWidth = window.innerWidth;
			var innerHeight = window.innerHeight;
	
			if (width + dblMargin > innerWidth) {
				width = innerWidth - dblMargin;
				style.width = width +'px';
			}
			if (height + dblMargin > innerHeight) {
				height = innerHeight - dblMargin;
				style.height = height +'px';
			}

			var spacing = 4;
			var rect = this._parent.getBoundingClientRect();
			var left = rect.left;
			var top = rect.top + spacing + this._parent.offsetHeight;

			if (left + width > innerWidth)
				left -= (left + width) - window.innerWidth + margin;
			if (top + height > innerHeight)
				top -= height + this._parent.offsetHeight + spacing * 2;

			if (left < 0)
				left = margin;
			if (top < 0)
				top = margin;

			style.top = (top) +'px';
			style.left = (left) +'px';
		}
	}

	,hide() {
		if (!this._isOpen)
			return;

		if (this._bg) {
			Htk.Toast.popTop();
			Vn.Node.remove(this._bg);
			Vn.Node.removeClass(this._node, 'modal');
			this._bg = null;
		} else
			this.doc.removeEventListener('mousedown', this._bgMouseDownHandler);

		Vn.Node.remove(this._node);
		this._parent = null;
		this._isOpen = false;
		this.emit('closed');
	}
	
	,_bgMouseDown(e) {
		if (e !== this._lastEvent)
			this.hide();
			
		this._lastEvent = null;
	}
	
	,_onMouseDown(e) {
		this._lastEvent = e;
	}
});