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

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

var Klass = new Class ();
module.exports = Klass.implement
({
	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.
		 */
		className:
		{
			type: String
			,set: function (x)
			{
				this._className	 = x;
				this._refreshClass ();
			}
			,get: function ()
			{
				return this._className;
			}
		},
		/**
		 * CSS classes to be appendend to the node classes.
		 */
		class:
		{
			type: String
			,set: function (x)
			{
				this._className	 = x;
				this._refreshClass ();
			}
		},
		/**
		 * 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);
	}

	,appendChild: function (child)
	{
		if (child instanceof Klass)
			this._node.appendChild (child.node);
		else if (child instanceof Element)
			this._node.appendChild (child);
	}
	
	,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)
	{
		var node = this.createElement (tagName);
		this._setNode (node);	
		return node;
	}

	,_setNode: function (node)
	{
		if (this.htmlId)
			node.id = this.htmlId;
		if (this.$constructor.Tag)
			node.className = this.$constructor.Tag;

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

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

	,_refreshClass: function ()
	{
		if (this._node && this._className)
			this._node.className = this._className +' '+ 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;
		scope.link ();
		this.$ = scope.$;
		this._setNode (this.$.main);
		return scope;
	}

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

		this.parent ();
	}
});

