<?php
/**
 * HTML for N.u.C.o.K.e.
 * Requires N.u.C.o.K.e. v2.0.1664
 * © Hsilamot 2011
 * developed by Hidalgo Rionda
 * This library is intended to be used aside N.u.C.o.K.e. Class
 *
 * +----------------------------------------------------------------------+
 * |                            HTML v 1.0.55                              |
 * |             released under Creative Commons BY-NC-SA 3.0             |
 * |          http://creativecommons.org/licenses/by-nc-sa/3.0/           |
 * +----------------------------------------------------------------------+
 *
 * +----------------------------------------------------------------------+
 * |                              changelog                               |
 * | v1.0.1 (Hsilamot) first release                                      |
 * +----------------------------------------------------------------------+
 *
 * @access public
 * @author Hsilamot <php@hsilamot.com>
 * @license http://creativecommons.org/licenses/by-nc-sa/3.0/
 * @version 1.5.65
 */
class HTML extends NuCoKe {
	/**
	 * Charset to be used
	 * @access protected
	 * @var string charset to use
	 */
	protected $charset='UTF-8';
	/**
	 * doctype to use
	 * @access protected
	 * @var string doctype to use
	 */
	protected $doctype='html401strict';
	/**
	 * doctype is xml
	 * @access protected
	 * @var bool if doctype is xml
	 */
	protected $doctype_xml=false;
	/**
	 * HTML headers
	 * @access protected
	 * @var array array of headers
	 */
	protected $headers=array();
	/**
	 * HTML templates
	 * Array which contains 'start' and 'end' for each 'theme'
	 * array( 'theme_name' => array('start' => 'HTML', 'end' => 'HTML') )
	 * @access protected
	 * @var array array of themes
	 */
	protected $themes=array();
	/**
	 * will initialize the class
	 * @access public
	 * @version 1.1.47
	 * @param array $config array containing any extra configuration from the user
	 * @param object $nucoke previously initialized nucoke
	 * @return boolean if success
	 */
	public function __construct($config=array(),&$nucoke=null) {
		parent::__construct(null,$nucoke);
		$version = $this->version(); $this->user_agent_add('HTML v'.$version[0].'.'.$version[1]); /* will add self to the user agent string */
		/* we will now set the default configuration */
		$this->config['html_name_on_title'] = true;
		$this->config['html_theme'] = 'default';
		/* we will parse any configuration added from user end */
		if (!is_array($config)) { $config = array(); trigger_error('NuCoKe (HTML): Unknown configuration type passed on __initialize($config)',E_USER_NOTICE); }
		foreach ($config as $name => $value) {
			switch ($name) {
				case 'name_on_title':
					if ($value===true) {
						$value = true;
					} else {
						$value = false;
					}
					$this->config['html_name_on_title'] = $value; break;
				default:
					trigger_error('NuCoKe (HTML): Unknown configuration name \''.$name.'\'',E_USER_NOTICE); break;
			}
		}
		$this->headers_add('meta',date(DATE_RFC822,time()),'date');
		if (php_sapi_name()!='cli') {
			$apache_version = explode(chr(32),$_SERVER['SERVER_SOFTWARE']);
			$apache_version = $apache_version[0].';';
		} else {
			$apache_version = '';
		}
		$nucoke_version = parent::version();
		$this->headers_add('meta',$apache_version.'PHP/'.phpversion().';NuCoKe/'.$nucoke_version[0].'.'.$nucoke_version[1].'.'.$nucoke_version[2],'generator');
		$this->headers_add('meta','unknown','author');
		$this->headers_add('meta','unknown','description');
		$this->headers_add('meta','unknown','keywords');
		$this->headers_add('meta','1 day','Revisit-after');
		$this->headers_add('meta','index,follow','robots');
		$this->headers_add('title','unknown');
		return true;
	}
	/**
	 * will set the charset of the document
	 * @access public
	 * @version 1.0.55
	 * @param string $charset charset to use
	 * @return bool if success
	 */
	public function charset_set($charset) {
		$this->charset=$charset;
		return true;
	}
	/**
	 * returns the HTML html Tag
	 * @access public
	 * @param string String to return 'start' or 'end' tag of HTML
	 * @version 1.2.15
	 * @return string HTML
	 */
	public function get_html($where='start') {
		if ($where!='start'&&$where!='end') {
			return false;
		}
		if ($where=='end') {
			return chr(13).chr(10).'</html>';
		}
		if ($where=='start') {
			$return = '';
			if ($this->doctype_xml==true) {
				$return .= '<?xml version="1.0" encoding="'.$this->charset.'"?>'.chr(13).chr(10);
			}
			switch ($this->doctype) {
				case 'html401strict':
					$return .= '<!DOCTYPE HTML PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD HTML 4.01//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/html4/strict.dtd">'.chr(13).chr(10);
					break;
				case 'html401loose':
					$return .= '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/html4/loose.dtd">'.chr(13).chr(10);
					break;
				case 'html401frames':
					$return .= '<!DOCTYPE HTML PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD HTML 4.01 Frameset//EN" '.chr(13).chr(10).'  "http://www.w3.org/TR/html4/frameset.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml10strict':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML 1.0 Strict//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml10trans':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML 1.0 Transitional//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml10frames':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML 1.0 Frameset//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml10basic':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML Basic 1.0//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml11basic':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML Basic 1.1//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml11':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD XHTML 1.1//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml10mobile':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"'.chr(13).chr(10).'  "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml11mobile':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//WAPFORUM//DTD XHTML Mobile 1.1//EN"'.chr(13).chr(10).'  "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd">'.chr(13).chr(10);
					break;
				case 'xhtml12mobile':
					$return .= '<!DOCTYPE html PUBLIC'.chr(13).chr(10).'  "-//WAPFORUM//DTD XHTML Mobile 1.2//EN"'.chr(13).chr(10).'  "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'.chr(13).chr(10);
					break;
				case 'html5':
					$return .= '<!doctype html>'.chr(13).chr(10);
					break;
				default:
					$return .= '<!DOCTYPE HTML PUBLIC'.chr(13).chr(10).'  "-//W3C//DTD HTML 4.01//EN"'.chr(13).chr(10).'  "http://www.w3.org/TR/html4/strict.dtd">'.chr(13).chr(10);
					trigger_error('NuCoKe (URI): the doctype \''.$this->doctype_xml.'\' is unknown for me',E_USER_NOTICE);
					break;
			}
			$return .= '<html';
			if ($this->doctype_xml) {
				$return .= ' xmlns="http://www.w3.org/1999/xhtml" xml:lang="es"';
			}
			$return .= '>'.chr(13).chr(10);
			return $return;
		}
	}
	/**
	 * returns the HTML head before the HTML body
	 * @access public
	 * @version 1.2.15
	 * @return string HTML start
	 */
	public function get_head() {
		$return  = '';
		$return .= '<head>'.chr(13).chr(10);
		$return .= $this->headers_html();
		$return .= '</head>'.chr(13).chr(10);
		return $return;
	}
	/**
	 * returns the HTML body
	 * @access public
	 * @param string String 'start' or 'end' of the Body, if none specified 'start' will be returned
	 * @param string String with the Theme to return
	 * @version 1.2.15
	 * @return string HTML body
	 */
	public function get_body($where='start',$theme='') {
		if ($where!='start'&&$where!='end') {
			return false;
		}
		if (strlen($theme)==0) {
			$theme = $this->config['html_theme'];
		}
		if (!isset($this->themes[$theme])) {
			$this->themes[$theme] = array('start' => '','end' => '');
		}
		return $this->themes[$theme][$where];
	}
	/**
	 * adds a Header to the headers list
	 * @access public
	 * @version 1.0.55
	 * @param string $headertype type of header, use 'raw' to print content as is (useful for <style> and <script>)
	 * @param string $content content of the header
	 * @param string $href href of the header
	 * @param string $rel rel of the header
	 * @param string $type type of content
	 * @param string $title title of the content
	 * @param string $media media of content
	 * @param string $http_equiv HTTP equivalency
	 * @return string <head> start
	 */
	public function headers_add($headertype='meta',$content=null,$name=null,$href=null,$rel=null,$type=null,$title=null,$media=null,$http_equiv=null) {
		$prepara = array();
		if ($headertype!=null) {	$prepara['headertype']	= $headertype; }
		if ($content!=null) {		$prepara['content']		= $content; }
		if ($name!=null) {			$prepara['name']		= $name; }
		if ($href!=null) {			$prepara['href']		= $href; }
		if ($rel!=null) {			$prepara['rel']			= $rel; }
		if ($type!=null) {			$prepara['type']		= $type; }
		if ($title!=null) {			$prepara['title']		= $title; }
		if ($media!=null) {			$prepara['media']		= $media; }
		if ($http_equiv!=null) {	$prepara['http_equiv']	= $http_equiv; }
		if ($headertype=='title') {
			$found=false;
			foreach($this->headers as $number => $header) {
				if ($header['headertype']=='title') {
					$found=true;
					$this->headers[$number] = $prepara;
					return true;
				}
			}
		}
		if ($headertype=='charset') {
			$found=false;
			foreach($this->headers as $number => $header) {
				if ($header['headertype']=='charset') {
					$found=true;
					$this->headers[$number] = $prepara;
					return true;
				}
			}
		}
		if ($headertype=='link') {
			$found=false;
			foreach($this->headers as $number => $header) {
				if ($header['headertype']=='meta'&&$header['name']==$name) {
					$found=true;
					$this->headers[$number] = $prepara;
					return true;
				}
			}
		}
		if ($headertype=='meta'&&$name!=null) {
			$found=false;
			foreach($this->headers as $number => $header) {
				if ($header['headertype']=='meta'&&$header['name']==$name) {
					$found=true;
					$this->headers[$number] = $prepara;
					return true;
				}
			}
		}
		if ($headertype=='meta'&&$http_equiv!=null) {
			$found=false;
			foreach($this->headers as $number => $header) {
				if ($header['headertype']=='meta'&&$header['http_equiv']==$http_equiv) {
					$found=true;
					$this->headers[$number] = $prepara;
					return true;
				}
			}
		}
		$this->headers[] = $prepara;
		return true;
	}
	/**
	 * return string with list of headers in html format
	 * @access public
	 * @version 1.0.55
	 * @param bool $tab prefix tab character
	 * @param bool $new_line separate each header as a line
	 * @return string headers list in HTML
	 */
	public function headers_html($tab=true,$new_line=true) {
		$return = '';
		foreach ($this->headers as $header) {
			if ($tab) { $return .= '	'; }
			switch ($header['headertype']) {
				case 'meta':
					$return .= '<';
					$return .= 'meta';
					if (strlen($header['http_equiv'])>0) { $return .= ' http-equiv="'.$header['http_equiv'].'"'; }
					if (strlen($header['name'])>0) { $return .= ' name="'.$header['name'].'"'; }
					if (strlen($header['content'])>0) { $return .= ' content="'.$header['content'].'"'; }
					if ($this->doctype_xml) { $return .= ' /'; }
					$return .= '>';
					break;
				case 'link':
					$return .= '<';
					$return .= 'link';
					if (strlen($header['name'])>0) { $return .= ' name="'.$header['name'].'"'; }
					if (strlen($header['content'])>0) { $return .= ' content="'.$header['content'].'"'; }
					if (strlen($header['rel'])>0) { $return .= ' rel="'.$header['rel'].'"'; }
					if (strlen($header['title'])>0) { $return .= ' title="'.$header['title'].'"'; }
					if (strlen($header['href'])>0) { $return .= ' href="'.$header['href'].'"'; }
					if (strlen($header['type'])>0) { $return .= ' type="'.$header['type'].'"'; }
					if (strlen($header['media'])>0) { $return .= ' media="'.$header['media'].'"'; }
					if ($this->doctype_xml) { $return .= ' /'; }
					$return .= '>';
					break;
				case 'charset':
					$return .= '<meta charset="'.$header['content'].'">';
					break;
				case 'raw':
					$return .= $header['content'];
					break;
				case 'title':
					$return .= '<title>';
					$return .= $header['content'];
					if ($this->config['html_name_on_title']) {
						$return .= ' - '.$this->config['name'];
					}
					$return .= '</title>';
					break;
				default:
					trigger_error('NuCoKe (HTML): Unknown header type \''.$header['headertype'].'\'',E_USER_NOTICE); break;
			}
			if ($new_line) { $return .= chr(13).chr(10); }
		}
		return $return;
	}
	/**
	 * will set the doctype of the document
	 * @access public
	 * @version 1.0.55
	 * @param string $doctype doctype to use, consult doctypes.txt in doc folder
	 * @return bool if success
	 */
	public function doctype_set($doctype) {
		switch ($doctype) {
			case 'html401strict':
				$this->doctype_xml=false;
				$this->doctype='html401strict';
				return true;
			case 'html401loose':
				$this->doctype_xml=false;
				$this->doctype='html401loose';
				return true;
			case 'html401frames':
				$this->doctype_xml=false;
				$this->doctype='html401frames';
				return true;
			case 'xhtml10strict':
				$this->doctype_xml=true;
				$this->doctype='xhtml10strict';
				return true;
			case 'xhtml10trans':
				$this->doctype_xml=true;
				$this->doctype='xhtml10trans';
				return true;
			case 'xhtml10frames':
				$this->doctype_xml=true;
				$this->doctype='xhtml10frames';
				return true;
			case 'xhtml10basic':
				$this->doctype_xml=true;
				$this->doctype='xhtml10basic';
				return true;
			case 'xhtml11basic':
				$this->doctype_xml=true;
				$this->doctype='xhtml11basic';
				return true;
			case 'xhtml11':
				$this->doctype_xml=true;
				$this->doctype='xhtml11';
				return true;
			case 'xhtml10mobile':
				$this->doctype_xml=true;
				$this->doctype='xhtml10mobile';
				return true;
			case 'xhtml11mobile':
				$this->doctype_xml=true;
				$this->doctype='xhtml11mobile';
				return true;
			case 'xhtml12mobile':
				$this->doctype_xml=true;
				$this->doctype='xhtml12mobile';
				return true;
			case 'html5':
				$this->doctype_xml=false;
				$this->doctype='html5';
				return true;
			default:
				$this->doctype_xml=false;
				$this->doctype='html401strict';
				trigger_error('NuCoKe (URI): the doctype \''.$doctype.'\' is unknown for me',E_USER_NOTICE);
				return false;
		}
		return false;
	}
	/**
	 * adds text to the Theme
	 * @access public
	 * @version 1.3.54
	 * @param string String to add
	 * @param string 'start' or 'end' of the theme to add the string to, if none specified 'start' will be used
	 * @param string Name of the theme to add, if none specified default will be used
	 * @return bool if success
	 */
	public function theme_add($txt='',$where='start',$theme='') {
		if (strlen($txt)>0) {
			if ($where!='start'&&$where!='end') {
				return false;
			}
			if (strlen($theme)==0) {
				$theme = $this->config['html_theme'];
			}
			if (!isset($this->themes[$theme])) {
				$this->themes[$theme] = array('start' => '','end' => '');
			}
			if ($where=='start') {
				$this->themes[$theme][$where] .= $txt.chr(13).chr(10);
			}
			if ($where=='end') {
				$this->themes[$theme][$where] .= chr(13).chr(10).$txt;
			}
			return true;
		}
	}
	/**
	 * replace text to the Theme
	 * @access public
	 * @version 1.3.38
	 * @param string String to search
	 * @param string String to replace
	 * @param string 'start' or 'end' of the theme to replace the string to, if none specified 'start' will be used
	 * @param string Name of the theme to replace, if none specified default will be used
	 * @return bool if success
	 */
	public function theme_replace($search='',$replace='',$where='start',$theme='') {
		if (strlen($search)>0) {
			if ($where!='start'&&$where!='end') {
				return false;
			}
			if (strlen($theme)==0) {
				$theme = $this->config['html_theme'];
			}
			if (!isset($this->themes[$theme])) {
				$this->themes[$theme] = array('start' => '','end' => '');
			}
			$this->themes[$theme][$where] = str_replace($search,$replace,$this->themes[$theme][$where]);
			return true;
		}
	}
	/**
	 * will return the version of the class in Mayor, Minor and Release
	 * @access public
	 * @version 1.0.65
	 * @return array ( main, minor, release )
	 */
	public function version() {
		return array( 1, 5, 65 );
	}
}
?>
