var NodeBuilder = require ('./node-builder');

var nativeEvents = {
	 click     : 1
	,mousedown : 1
	,focusout  : 1
};

module.exports = new Class
({
	Extends: NodeBuilder
	,Properties:
	{
		/**
		 * Main HTML node that represents the component
		 */
		node:
		{
			type: Object
			,get: function ()
			{
				this.renderBase ();
				return this._node;
			}
		},
		/**
		 * CSS classes to be appendend to the node classes.
		 */
		class:
		{
			type: String
			,set: function (x)
			{
				this._cssClass = x;
				this._refreshClass ();
			}
			,get: function ()
			{
				return this._node.className;
			}
		},
		/**
		 * The HTML id of the element.
		 */
		htmlId:
		{
			type: String
			,set: function (x)
			{
				this._htmlId = x;

				if (this._node)
					this._node.id = x;
			}
			,get: function ()
			{
				return this._htmlId;
			}
		}
	}

	,_node: null
	,scope: null
	
	,initialize: function (props)
	{
		this.doc = document;
		this.renderBase ();
		this.parent (props);
	}
	
	,on: function (id, callback, instance)
	{
		if (nativeEvents[id])
			this.node.addEventListener (id,
				callback.bind (instance, this));
		else
			this.parent (id, callback, instance);
	}
	
	,createRoot: function (tagName)
	{
		this._node = this.createElement (tagName);

		if (this.htmlId)
			this._node.id = this.htmlId;
	
		return this._node;
	}
	
	,renderBase: function ()
	{
		if (this._node)
			return;

		this.render ();
		this._refreshClass ();
	}

	,_refreshClass: function ()
	{
		if (this._node && this._cssClass)
			this._node.className = this._cssClass +' '+ this._node.className;
	}
	
	,remove: function ()
	{
		Vn.Node.remove (this._node);
	}
	
	,loadTemplateFromFile: function (path)
	{
		var builder = new Vn.Builder ();
		builder.compileFile (path);
		this.loadScope (builder);
	}
	
	,loadTemplateFromString: function (xmlString)
	{
		var builder = new Vn.Builder ();
		builder.compileString (xmlString);
		this.loadScope (builder);
	}
	
	,loadScope: function (builder, parentScope, extraObjects)
	{
		var scope = builder.load (this.doc, this, parentScope, extraObjects);
		this.scope = scope;
		this._node = this.$('main');
		scope.link ();
		return scope;
	}
	
	/**
	 * Gets an object from the scope associated to this component.
	 *
	 * @param {String} id The object identifier
	 * @return {Object} The object, or %null if not found
	 */
	,$: function (id)
	{
		if (this.scope)
			return this.scope.$(id);
			
		return null;
	}

	,_destroy: function ()
	{
		if (this.builder)
			this.builder.unref ();

		this.parent ();
	}
});