<?php


/**
 * Html tag factory
 */
class Html {


	function &_($tag_name, $content = '', $params = array()) {
		$tag_class_name = 'Html_' . $tag_name;
		if (class_exists($tag_class_name)) {
			$tag = new $tag_class_name($content, $params);
		} else {
			$tag = new Html_tag($tag_name, $content, $params);
		}
		return $tag;
	}


}


class Html_tag {


	var $name;
	var $attr;
	var $cnt;
	var $_empty;
	var $_childrens;


	function __construct($name, $cnt = null, $params = array()) {
		$this->name = $name;
		$this->cnt = $cnt;
		$this->_empty = false;// default false
		$this->_childrens = array();
		if (array_key_exists('empty', $params)) {
			$this->setEmpty();
		}
		$this->attr = $params;
	}


	function getAttr($name) {
		if (array_key_exists($name, $this->attr)) {
			$this->attr[$name];
		}
		return null;
	}


	function setAttr($name, $value = '') {
		$this->attr[$name] = $value;
	}


	function removeAttr($name, $value = '') {
		unset($this->attr[$name]);
	}


	function setEmpty($bool) {
		$this->_empty = ($bool)? true : false;
	}


	function isEmpty() {
		return $this->_empty;
	}


	function hasChildNodes() {
		return !empty($this->_childrens);
	}


	function &getChildNodes() {
		return $this->_childrens;
	}


	/**
	 * String or object Html_tag
	 */
	function appendChild($tag) {
		$this->_childrens[] = $tag;
	}


	/**
	 * overwrite in sub class
	 */
	function _prepareHtml() {
	}


	function toHtml() {
		$this->_prepareHtml();
		$ret = '';
		$attr_out = '';
		if (!empty($this->attr)) {
			$attr_arr = array();
			foreach ($this->attr as $k_attr => $v_attr) {
				$attr_arr[] = $k_attr . '="' . $v_attr . '"';
			}
			if (!empty($attr_arr)) {
				$attr_out = ' ' . implode(' ', $attr_arr);
			}
		}

		if ($this->_empty) {
			$ret .= '<' . $this->name . $attr_out . ' />';
		}
		else {
			$ret .= '<' . $this->name . $attr_out . '>';
			if (is_string($this->cnt)) {
				$ret .= $this->cnt;
			} else if (is_object($this->cnt)) {
				$ret .= $this->cnt->toHtml();
			}
			if (!empty($this->_childrens)) {
				foreach ($this->_childrens as $v_child) {
					if (is_string($v_child)) {
						$ret .= $v_child;
					} else if (is_object($v_child)) {
						$ret .= $v_child->toHtml();
					}
				}
			}
			$ret .= '</' . $this->name . '>';
		}
		return $ret;
	}


	function &wrap($tag_name, $params = array()) {
		$tag = Html::_($tag_name, $this, $params);
		return $tag;
	}

}


class Html_table extends Html_tag {


	var $thead;
	var $tfoot;
	var $tbody;


	function __construct($content, $params = array()) {
		parent::__construct('table', $content, $params);
		$this->thead = null;
		$this->tfoot = null;
		$this->tbody = null;
	}


	/**
	 * add row to thead
	 */
	function addHeadRow($html_row) {
		if (!$this->thead) $this->thead = Html::_('thead');
		$this->thead->appendChild($html_row);
	}


	/**
	 * add row to tfoot
	 */
	function addFootRow($html_row) {
		if (!$this->tfoot) $this->tfoot = Html::_('tfoot');
		$this->tfoot->appendChild($html_row);
	}


	/**
	 * add row to tbody
	 */
	function addBodyRow($html_row) {
		if (!$this->tbody) $this->tbody = Html::_('tbody');
		$this->tbody->appendChild($html_row);
	}


	function _prepareHtml() {
		$this->cnt = null;// remove all set cnt ?
		$this->_childrens = null;// remove all childrens ?
		if ($this->thead) $this->appendChild($this->thead);
		if ($this->tfoot) $this->appendChild($this->tfoot);
		if ($this->tbody) $this->appendChild($this->tbody);
	}


}
