
var Widget = require ('./widget');

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

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

	,initialize: function (props)
	{
		this._bgMouseDownHandler = this._bgMouseDown.bind (this);
		this.parent (props);
	}
	
	,render: function ()
	{
		var div = this.createRoot ('div');
		div.className = 'htk-popup';
	}

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

	,show: function (parent)
	{
		this._parent = parent;
		this.open ();
	}

	,isModal: function ()
	{
		return this._modal || Vn.isMobile ();
	}
	
	,open: function ()
	{
		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);

			Vn.Node.addClass (this.node, '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: function ()
	{
		if (this._bg)
			this._bg.style.opacity = 1;
	}

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

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

		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';
		}
		
		if (this.isModal ())
		{
			style.marginLeft = (-node.offsetWidth / 2) +'px';
			style.marginTop =  (-node.offsetHeight / 2) +'px';
		}
		else
		{
			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: function ()
	{
		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.signalEmit ('closed');
	}
	
	,_bgMouseDown: function (e)
	{
		if (e !== this._lastEvent)
			this.hide ();
			
		this._lastEvent = null;
	}
	
	,_onMouseDown: function (e)
	{
		this._lastEvent = e;
	}
});

