function _HtmlBase()
{
	var el;
}
_HtmlBase.prototype.add = function(o) {
	this.el.appendChild(o.getEl());
}
_HtmlBase.prototype.getEl = function() {
	return(this.el);
}
_HtmlBase.prototype.setClass = function(className) {
	this.el.className = className;
}
_HtmlBase.prototype.removeAllChildren = function() {
	for(var i=this.el.childNodes.length-1; i>=0; i--) {
		this.el.removeChild(this.el.childNodes[i]);
	}
}

/*
 * Body
 */
function Body()
{
	this.el = document.body;
}
Body.prototype = new _HtmlBase;

/*
 * Paragraph
 */
function Paragraph(el)
{
	//this.el = document.createElement('p');
	this.el = el ? el : document.createElement('p');
}
Paragraph.prototype = new _HtmlBase;

/*
 * Input
 */
function Input(el)
{
	this.el = el ? el : document.createElement('input');
}
Input.prototype = new _HtmlBase;

/*
 * Select
 */
function Select(el)
{
	this.el = el ? el : document.createElement('select');
}
Select.prototype = new _HtmlBase;

/*
 * Text
 */
function Text(text)
{
	this.el = (text) ? document.createTextNode(text) :
        document.createTextNode('');
}
Text.prototype = new _HtmlBase;
Text.prototype.setText = function(str) {
	this.el.nodeValue = str;
}

/*
 * Br
 */
function Br()
{
	this.el = document.createElement('br');
}
Br.prototype = new _HtmlBase;

/*
 * Button
 */
function Button(label)
{
	this.el = document.createElement('button');
	this.setLabel(label);
}
Button.prototype = new _HtmlBase;
Button.prototype.setLabel = function(label) {
	this.removeAllChildren();
	this.add(new Text(label));
}

/*
 * Table and friends
 */

// Table
function Table(width, length) {
	var width, length;
	var thead;
	var tbody;

	this.el = document.createElement('table');

	if(width) {
		this.width = width;
	} else {
		this.width = 1;
	}

	if(length) {
		this.length = length;
	} else {
		this.length = 0;
	}
	
	this.thead = new Thead(width);
	this.tbody = new Tbody();

	this.add(this.thead);
	this.add(this.tbody);
}
Table.prototype = new _HtmlBase;
Table.prototype.setHeader = function(i, str) {
	this.thead.setHeader(i, str);
}
Table.prototype.setHeaders = function(strArray) {
	for(var i=0; i<strArray.length; i++) {
		this.thead.setHeader(i, strArray[i]);
	}
}
Table.prototype.addRows = function(rows) {
	//rows should be a 2d array
	for(var i=0; i<rows.length; i++) {
		var r = new Tr();
		for (var j=0; j<rows[i].length; j++) {
			var td = new Td();
			if(rows[i][j]!=null) {
				td.setText(rows[i][j]);
			}
			r.add(td);
		}
		this.tbody.add(r);
	}
}
Table.prototype.clearRows = function() {
	this.tbody.removeAllChildren();
}
Table.prototype.getTbody = function() {
	return(this.tbody);
}

// Thead
function Thead(width) {
	var width;
	var row;
	var ths;

	this.el = document.createElement('thead');

	this.width = width;
	this.ths = new Array(this.width);
	this.row = new Tr();

	//setup the array of <th>s.
	for(var i=0; i<this.width; i++) {
		this.ths[i] = new Th();
		this.row.add(this.ths[i]);
	}

	//add the row to ourselves
	this.add(this.row);
}
Thead.prototype = new _HtmlBase;
Thead.prototype.setHeader = function(i, str) {
	this.ths[i].setText(str);
}

// Tbody
function Tbody() {
	this.el = document.createElement('tbody');
}
Tbody.prototype = new _HtmlBase;

// Tr
function Tr() {
	this.el = document.createElement('tr');
}
Tr.prototype = new _HtmlBase;

// Th
function Th() {
	this.el = document.createElement('th');
}
Th.prototype = new _HtmlBase;
Th.prototype.setText = function(str) {
	this.add(new Text(str));
}

// Td
function Td() {
	this.el = document.createElement('td');
}
Td.prototype = new _HtmlBase;
Td.prototype.setText = function(str) {
	this.add(new Text(str));
}


/*
 * event adding function
 */
function setEvent(owner, obj, eventName, func, arg1, arg2, arg3, arg4) {
	if(arg4) {
		obj[eventName] = function(){func.call(owner, arg1, arg2, arg3, arg4);}
	} else if(arg3) {
		obj[eventName] = function(){func.call(owner, arg1, arg2, arg3);}
	} else if(arg2) {
		obj[eventName] = function(){func.call(owner, arg1, arg2);}
	} else if(arg1) {
		obj[eventName] = function(){func.call(owner, arg1);}
	} else {
		obj[eventName] = function(){func.call(owner);}
	}
}

/*
 * manual implementation of Array.prototype.indexOf
 * 2006-12-10
 */
function pnIndexOf(haystack, needle) {

	var position = -1;

	for(var i=0; i<haystack.length; i++) {
		if(haystack[i] == needle) {
			position = i;
		}
	}

	return(position);

}
