const Compiler = require('./compiler');
const Component = require('./component');
const VnNode = require('./node');

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

	,compile(builder, node, tagName) {
		const context = {
			tagName,
			attributes: {},
			childs: [],
			events: {}
		};
		const {attributes} = context;

		const a = node.attributes;
		for (let i = 0; i < a.length; i++) {
			const attribute = a[i].nodeName;
			const value = a[i].nodeValue;
	
			if (this.isEvent(attribute)) {
				const handler = this._getMethod(value);
				if (handler) context.events[attribute.substr(3)] = handler;
			} else if (!/^(id|property)$/.test(attribute)) {
				if (this.isExpr(value))
					this.compileExpr(context, attribute, value);
				else
					attributes[attribute] = this._translateValue(value);
			}
		}

		let childContext;
		const childNodes = node.childNodes;

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

		return context;
	}
	
	,instantiate(doc, context, scope) {
		const object = doc.createElement(context.tagName);

		const attributes = context.attributes;
		for (const attribute in attributes)
			object.setAttribute(attribute, attributes[attribute]);

		if (context.nodeId) {
			const id = context.nodeId;
			object.setAttribute('id', scope.getHtmlId(id));
			VnNode.addClass(object, '_'+ id);
		}

		return object;
	}

	,setProperty(object, property, value) {
		object.setAttribute(property, value);
	}
	
	,link(context, object, objects, scope) {
			const childs = context.childs;
		for (let i = 0; i < childs.length; i++) {
			let child = objects[childs[i]];
		
			if (child instanceof Component)
				child = child.node;
			if (child instanceof Node)
				object.appendChild(child);
		}
		
		const events = context.events;
		for (const event in events) {
			const listener = this.bindMethod(events[event], scope, true);
			if (listener)
				object.addEventListener(event, listener);
		}
	}
});
