// JavaScript Document
function block(tag,opts,args) {
	var content = "<" + tag + " ";
	for(var p in opts) {
	    if(opts[p] != null) {
		content += p + "=\"" + opts[p] + "\" ";
	    } else {
		content += p + " ";
	    }
	}	
	if(args.length) {
	    content += ">";
	    // to do process internals
	    for(var i = 0 ; i < args.length ; i ++) {
		if(typeof args[i] == 'string') {
			content += args[i];
		} else if (typeof args[i] == 'function') {
			content += args[i]();
		} else if (typeof args[i] == 'number') {
			content += args[i];
		}							
	    }
	    content += "</" + tag + ">";
	} else {
	    content += " />";
	}
	return content;
}

function table() { 	return block('table',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function tr() {	return block('tr',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function td() {	return block('td',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function th() {	return block('th',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function thead() {	return block('thead',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function tbody() {	return block('thead',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function div() { return block('div',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function span() { return block('span',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function p() { return block('p',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function b() { return block('b',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function a() { return block('a',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function ul() { return block('ul',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function ol() { return block('ol',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function li() { return block('li',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function select() { return block('select',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function option() { return block('option',arguments[0],Array.prototype.slice.call(arguments).slice(1));	}
function input() { return block('input',arguments[0],Array()); }
function img() { return block('img',arguments[0],Array()); }

function cssArgs(opts) {
    var content = "";
    for(var p in opts) {
        if(opts[p] != null) {
	    content += p + ": " + opts[p] + "; ";
	}
    }
    return content;
}

function br() {return block('br',{},Array()); }

//
// Create proper-derivable "class".
//
// Version: 1.2
//

function newClass(parent, prop) {
    // Dynamically create class constructor.
    var clazz = function() {
	// Stupid JS need exactly one "operator new" calling for parent
	// constructor just after class definition.
	if (clazz.preparing) return delete(clazz.preparing);
	// Call custom constructor.
	if (clazz.constr) {
	    this.constructor = clazz; // we need it!
	    clazz.constr.apply(this, arguments);
	}
    }
    clazz.prototype = {}; // no prototype by default
    if (parent) {
	parent.preparing = true;
	clazz.prototype = new parent;
	clazz.prototype.constructor = parent;
	clazz.constr = parent; // BY DEFAULT - parent constructor
    }
    if (prop) {
	var cname = "constructor";
	for (var k in prop) {
	    if (k != cname) clazz.prototype[k] = prop[k];
	}
	if (prop[cname] && prop[cname] != Object)
	    clazz.constr = prop[cname];
    }
    return clazz;
}
