<?php
	class template{
		//公開屬性:模板內容(文本)
		public $template = "";

		//私有屬性:模板頁面元素
		private $m_elements = array();

		//私有屬性：模版控件元素
		private $m_controls = array();

		//構造函數
		public function template(){
		}

		//公開方法:從文件加載模板內容
		//參數說明:$templateFile:模板文件
		public function loadTemplate($templateFile){
			if(file_exists($templateFile)){
				$handler = fopen($templateFile,"rb");
				$this->template = fread($handler,filesize($templateFile));
				fclose($handler);
			}
		}

		//公開方法:添加模板頁面元素
		//參數說明：$name:元素名稱,模板裡以"<?# name ? >"表示
		//$name:元素值
		public function addElement($name,$value){
			$element = array();
			$element["name"] = $name;
			$element["value"] = $value;
			$this->m_elements[] = $element;
		}

		//添加模板控件,返回控件原始內容
		//參數說明：$ctrlName 控件名稱；$tagPrefix：控件前綴；$tagName：控件標籤名，$ctrlId：控件id
		public function addControl($ctrlName,$tagPrefix,$tagName,$ctrlId){
			$beginTag = "<".$tagPrefix.":".$tagName;
			$endTag = "</".$tagPrefix.":".$tagName.">";
			$posx = 0;
			while($posx < strlen($this->template)){
				$ctrl = $this->getNextControl($tagPrefix,$tagName,$posx);
				if($this->getControlId($ctrl) == $ctrlId){
					$this->template = str_replace($ctrl,"<?# template_control_".$ctrlName." ?>",$this->template);
					return $ctrl;
				}
				$posx = strpos($this->template,$beginTag,$posx+1);
				if($posx === false)
					return "";
			}
		}

		//公開方法：用控件內容填充控件占位
		public function loadControl($ctrlName,$ctrlContent){
			$this->addElement("template_control_".$ctrlName,$ctrlContent);
		}

		//公開方法:取模板客戶端內容
		public function getContent(){
			$filedata = $this->template;
			foreach($this->m_elements as $element){
				//替換頁面變量
				$filedata = preg_replace("/<\?# {0,}".$element["name"]." {0,}\?>/",$element["value"],$filedata);
			}

			//替換空值的頁面變量為空字符
			$filedata = preg_replace("/<\?#([0-9a-zA-Z_ ]{0,})\?>/","",$filedata);

			return $filedata;
		}

		//公開方法:呈現模板
		public function render(){
			echo $this->getContent();
		}

		//公開方法:釋放類內部對象
		public function dispose(){
			if(isset($template))
				unset($template);
			if(isset($m_elementList))
				unset($m_elementList);
		}

		//私有方法
		private function getNextControl($tagPrefix,$tagName,$start){
			$offset = 4;
			$beginTag = "<".$tagPrefix.":".$tagName;
			$endTag = "</".$tagPrefix.":".$tagName.">";
			$posx = strpos($this->template,$beginTag,$start);
			$posy = strpos($this->template,$endTag,$start);
			if($posy === false || $posx >= $posy){
				$posy = strpos($this->template,"/>",$start);
				$offset = -5;
			}
			if($posx === false || $posy === false || $posx >= $posy)
				return "";
			$length = $posy - $posx + strlen($tagPrefix) + strlen($tagName) + $offset;
			return substr($this->template,$posx,$length);
		}

		//私有方法
		private function getControlId($ctrlContent){
			$posx = strpos($ctrlContent,"id=");
			if($posx === false)
				$posx = strpos($ctrlContent,"ID=");
			if($posx === false)
				$posx = strpos($ctrlContent,"Id=");
			if($posx === false)
				$posx = strpos($ctrlContent,"iD=");
			if($posx === false)
				return "";
			$posy = strpos($ctrlContent," ",$posx);
			if($posy === false)
				$posy = strpos($ctrlContent,"/>",$posx);
			$posz = strpos($ctrlContent,">",$posx);
			if($posy === false || $posy > $posz)
				$ctrlId = substr($ctrlContent,$posx + 3,$posz - $posx - 3);
			else
				$ctrlId = substr($ctrlContent,$posx + 3,$posy - $posx - 3);
			$ctrlId = str_replace("\"","",$ctrlId);
			$ctrlId = str_replace("'","",$ctrlId);
			$ctrlId = str_replace(" ","",$ctrlId);
			return $ctrlId;
		}
	}
?>