Converter = Class.create();
Converter.prototype = {
	_form: null,
	_processor: null,
	_input: null,
	_output: null,
	_status: null,
	_code: null,
	_type: 0,
	
	initialize: function(form, processor)
	{
		this._form = $(form);
		this._processor = $(processor);
		
		new Event.observe(this._form, 'submit', this.process.bindAsEventListener(this));
		
		this._input = this._form.down('#input');
		this._output = this._form.down('#output');
		this._status = this._form.down('#status');
		this._code = [];
	},
	
	process: function(e)
	{
		Event.stop(e);
		
		if (this._form.down('input[type=radio][value=1]').checked)
			this._type = 1;
		else
			this._type = 0;
		
		if (this._input.value.length == 0)
		{
			alert('Please enter your HTML!');
			return;
		}
		
		if (this._input.value.match(/<body>|<\/body>/i))
		{
			alert('We only convert stuff inside the body tags!');
			return;
		}
		
		this._processor.innerHTML = this._input.value;
		this._output.value = '';
		this._code = [];
		
		
		// create cont
		if (this._type == 0)
			this.addCode("var cont = document.createElement('div');\n");
		else
			this.addCode("var cont = new Element('div');\n")
		
		this.recurse(this._processor, 'cont', 1);
		
		this._output.value = this._code.join('');
		
		this._status.innerHTML = 'Done!';
	},
	
	recurse: function(el, parent, depth)
	{
		this._status.innerHTML = 'Processing... (Depth ' + depth + ')';
		
		var els = el.childNodes;
		
		for(var i = 0; i < els.length; i++)
		{	
			if (els[i].nodeType == 3)
			{
				// text node
				var elName = 'tx' + depth + 'n' + i;
				
				if (this.trim(els[i].nodeValue).length > 0)
				{
					if (this._type == 0 || i != 0)
					{
						this.addCode("var " + elName + ' = document.createTextNode("' + this.trim(els[i].nodeValue) + '");', depth);
						this.addCode(parent + ".appendChild(" + elName + ");\n", depth);
					} else {
						this.addCode(parent + '.update("' + this.trim(els[i].nodeValue) + '");', depth);
					}
				}
			} else if (els[i].nodeType == 1) {
				// element node
				
				var elName = els[i].tagName.toLowerCase() + depth + 'n' + i;
				
				if (this._type == 0)
				{
					this.addCode("var " + elName + " = document.createElement('" + els[i].tagName.toLowerCase() + "');", depth);
				
					var as = els[i].attributes;
				
					for(var a = 0; a < as.length; a++)
					{
						this.addCode(elName + ".setAttribute('" + as[a].nodeName + "', '" + as[a].nodeValue + "');", depth);
					}
				} else {
					var as = els[i].attributes;
					
					var atarray = [];
					
					for(var a = 0; a < as.length; a++)
					{
						atarray[atarray.length] = "'" + as[a].nodeName + "':'" + as[a].nodeValue + "'";
					}
					
					if (atarray.length > 0)
						this.addCode("var " + elName + " = new Element('" + els[i].tagName.toLowerCase() + "', {" + atarray.join(', ') + "});", depth);
					else
						this.addCode("var " + elName + " = new Element('" + els[i].tagName.toLowerCase() + "');", depth);
				}
				
				this.recurse(els[i], elName, depth + 1);
				
				this.addCode(parent + ".appendChild(" + elName + ");\n", depth);
			} else {
				alert('Unhandled node type ' + els[i].nodeType + '!\n' + els[i])
			}
		}
	},
	
	addCode: function(t, depth)
	{
		var tabs = '';
		for(var i = 0; i < (depth - 1); i++)
			tabs = tabs + '\t';
		
		this._code[this._code.length] = tabs + t + "\n";
	},
	
	trim: function(val)
	{
	     return val.replace(/^\s*|\s*$/g,'').replace(/"/g, "\\\"").replace(/\n/g, "\\n");
	}
}
