
var Compiler = require ('./compiler');
var Component = require ('./component');
var kebabToCamel = require ('./string-util').kebabToCamel;

var specialAttrs = {
	id       : 1,
	property : 1
};
var objectAttrs = {
	for      : 1
};

/**
 * Compiles a @HTML.Node from element tag.
 */
module.exports = new Class
({
	Extends: Compiler

	,compile: function (builder, node, tagName)
	{
		if (!tagName)
			return null;

		var props = {};
		var objectProps = {};
		var childs = [];
		var events = {};

		var a = node.attributes;

		for (var i = 0; i < a.length; i++)
		{
			var attribute = a[i].nodeName;
			var value = a[i].nodeValue;

			if (this.isEvent (attribute))
				events[attribute.substr (3)] = value;
			else if (objectAttrs[attribute])
				objectProps[attribute] = kebabToCamel(value);
			else if (!specialAttrs[attribute])
				props[attribute] = this.translateValue (value);
		}

		var childContext;
		var childNodes = node.childNodes;

		if (childNodes)
		for (var i = 0; i < childNodes.length; i++)
		if (childContext = builder._compile (childNodes[i]))
			childs.push (childContext.id);

		return {
			tagName: tagName,
			props: props,
			objectProps: objectProps,
			childs: childs,
			events: events
		};
	}
	
	,instantiate: function (doc, context, scope)
	{
		var object = doc.createElement (context.tagName);

		var props = context.props;
		for (var prop in props)
			object.setAttribute (prop, scope.interpolate (props[prop]));

		if (context.nodeId)
			object.setAttribute ('id', scope.getHtmlId (context.nodeId));

		return object;
	}
	
	,link: function (context, object, objects, scope)
	{
		var props = context.objectProps;
		for (var prop in props)
		{
			var objectValue = scope.$[props[prop]];
			var htmlId;

			if (objectValue instanceof Component)
				htmlId = objectValue.htmlId;
			if (objectValue instanceof Node)
				htmlId = objectValue.id;
	
			object.setAttribute (prop, htmlId);
		}

		var childs = context.childs;
		for (var i = 0; i < childs.length; i++)
		{
			var child = objects[childs[i]];
		
			if (child instanceof Component)
				child = child.node;
			if (child instanceof Node)
				object.appendChild (child);
		}
	}

	,connect: function (context, object, objects, scope)
	{
		var events = context.events;
		for (var event in events)
		{
			var method = scope.getMethod (events[event], true);
			
			if (method)
				object.addEventListener (event, method);
		}
	}
});
