<?php

class AKB_TEMPLATE
{
	// Private variables
	var $_tplName = '';
	var $_tplData = '';
	var $_tplPageTitle = '';
	
	var $panelid = false;
	
	/**
	* Constructor
	*
	* @return void
	*/
	function AKB_TEMPLATE()
	{

		// Load the language files
		$langFile = AKB_LANG_FILE;
		$wlFile = AKB_WL_LANG_FILE;

		if (!file_exists($langFile) || !file_exists($wlFile)) {
			// Trigger an error -- has to be in English though
			// because we can't load the language file
			trigger_error(sprintf("The language file (%s or %s) couldn't be opened.", AKB_LANG_FILE, AKB_WL_LANG_FILE), E_USER_WARNING);
		} else {
			// Parse the ArticleLive language file
			$GLOBALS['AKB_LANG'] = array_merge(parse_ini_file($wlFile), parse_ini_file($langFile));

			if (!is_array($GLOBALS['AKB_LANG'])) {
				// Couldn't load the language file
				trigger_error(sprintf("The language file (%s or %s) couldn't be loaded.", AKB_LANG_FILE, AKB_WL_LANG_FILE), E_USER_WARNING);
			}
		}
	}

	/**
	* SetTemplate
	* Set the template to $TplName
	*
	* @param string $TplName the template name without the extension
	*
	* @return void
	*/
	function SetTemplate($TplName)
	{
		$this->_tplName = $TplName;
	}

	/**
	* _GetTemplate
	* Returns the contents of a template if the template has been loaded
	*
	* @return string
	*/
	function _GetTemplate()
	{
		return $this->_tplData;
	}

	/**
	* SetPageTitle
	* Set the title of the page
	*
	* @param string $title The title to set the page to
	*
	* @return void
	*/
	function SetPageTitle($Title)
	{
		$this->_tplPageTitle = $Title;
	}

	/**
	* _GetPageTitle
	* Get the title of the page
	*
	* @return string The title of the page
	*/
	function _GetPageTitle()
	{
		return $this->_tplPageTitle;
	}

	/**
	* ParseTemplate
	* Parse any special variables in the currently set template
	*
	* @param bool $return If true the template will be returned as a string
	* rather then echo'd
	* @param mixed $parsePage If set to false then load the template from the
	* disk otherwise $parsePage will be treated like the template contents
	*
	* @return mixed returns the parsed template if $return is true otherwise it
	* returns nothing
	*/
	function ParseTemplate($return=false,$parsePage=false)
	{
		if ($parsePage === false) {
			$this->_tplData = $this->_LoadTemplateFile();
		} else {
			$this->_tplData = $parsePage;
		}

		$this->_tplData = $this->_ParseConstants();
		$this->_tplData = $this->_ParsePanels();
		$this->_tplData = $this->_ParseIncludes();
		$this->_tplData = $this->ParseSnippets($this->_tplData,$GLOBALS['SNIPPETS']);
		$this->_tplData = $this->ParseGL($this->_tplData);

		if ($return === true) {
			return $this->_GetTemplate();
		} else {
			echo $this->_GetTemplate();
		}
	}

	/**
	* _LoadTemplateFile
	* Load the template from disk. Private
	*
	* @return string The contents of the template file
	*/
	function _LoadTemplateFile()
	{
		$tplData = '';
		$matches = array();

		if (!isset($this->_tplName)) {
			// No template name specified
			trigger_error(sprintf('%s', GetLang('errNoTemplateNameSpecified')), E_USER_WARNING);
		} else {
			// Load the specified template
			if (strpos(str_replace(AKB_ROOT, '', AKB_TPL_LOAD_PATH), DIRECTORY_SEPARATOR.'admin/') !== FALSE) {
				$ext = '.tpl';
			} else {
				$ext = '.html';
			}
			$tplFile = AKB_TPL_LOAD_PATH.$this->_tplName.$ext;
			if (!file_exists($tplFile)) {
				trigger_error(sprintf('%s', sprintf(GetLang('errCouldntLoadTemplate'), AKB_TPL_LOAD_PATH.$this->_tplName.$ext)), E_USER_WARNING);
			} else {

				$tplData = $this->ReadFile($tplFile);

				// Parse out all constants
				return $tplData;
			}
		}
	}
	
	/**
	* _LoadTemplateFile
	* Load the template from disk. At the moment just a wrapper for _LoadTemplateFile
	*
	* @return string The contents of the template file
	*/
	function LoadTemplateFile()
	{
		return $this->_LoadTemplateFile();
	}

	/**
	* _ParseIncludes
	* Parse any includes in the template and insert the required data
	*
	* @return string The template with includes parsed in it
	*/
	function _ParseIncludes()
	{
		$matches = array();
		// Parse out all of the panels in the template
		$tplData = $this->_GetTemplate();

		if (!isset($this->_tplName)) {
			// No template name specified
			trigger_error(sprintf('%s', GetLang('errNoTemplateNameSpecified')), E_USER_WARNING);
		} else {
			// Parse out the panel tokens in the template file

			preg_match_all('`(?siU)(%%Include.(.*)%%)`', $tplData, $matches);

			foreach ($matches[0] as $key=>$k) {
				$pattern1 = $k;
				$pattern2 = str_replace('%', '', $pattern1);
				$pattern2 = str_replace('Include.', '', $pattern2);
				ob_start();
				if (eregi('http://',$pattern2)) {
					// Is a URL
					$readSite = '';
					// Trick the site into thinking it a regular user as some sites stop'
					// other servers from taking files
					ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');

					if ($openSite = fopen ($pattern2,'r')) {
						while (!feof($openSite)) {
							$readSite  .= fread($openSite, 4096);
						}
						fclose($openSite);
					}
					echo $readSite;
				} else if (eregi('/',$pattern2)) {
					// Has a path to the file
					include_once($pattern2);
				} else {
					// Must be in the panels folder
					include_once($_SERVER['DOCUMENT_ROOT'].$GLOBALS['appPath'].'/'.AKB_PANEL_LOAD_PATH.$pattern2);
				}
				$includeData = ob_get_contents();
				ob_end_clean();
				$tplData = str_replace($pattern1, $includeData, $tplData);
			}
		}

		return $tplData;
	}

	/**
	* _ParseConstants
	* Parse any constants in the template, replacing them with their values
	*
	* @return string the template with it's constants parsed in it
	*/
	function _ParseConstants()
	{
		/*
		Parse out all constants in the template
		*/
		$tplData = $this->_GetTemplate();

		$constants = array (
			'%%Config.ImagePath%%',
			'%%Page.Title%%',
			'%%Config.HomePath%%',
			'%%Config.KnowledgebaseName%%',
			'%%Config.Current.KnowledgebaseUrl%%',
		);

		$replace = array (
			AKB_TPL_IMAGE_PATH,
			$this->_GetPageTitle(),
			$GLOBALS['pathToKB'],
			$GLOBALS['knowledgebaseName'],
			$GLOBALS['pathToKB'],
		);

		if (!isset($this->_tplName)) {
			// No template name specified
			trigger_error(sprintf('%s', GetLang('errNoTemplateNameSpecified')), E_USER_WARNING);
		} else {
			$tplData = str_replace($constants, $replace, $tplData);
			$tplData = str_replace('%%Config.CurrentTemplatePath%%', ereg_replace('/$', '', AKB_TPL_HTTP_PATH), $tplData);
		}

		return $tplData;
	}

	/**
	* _ParsePanels
	* Parse any panels in the template, inserting the panel if required
	*
	* @param mixed $input if input is false load the template from disk otherwise
	* $input is treated like the contents of the template
	*
	* @return string The template with panels parsed in it
	*/
	function _ParsePanels($input=false)
	{
		$matches = array();
		// Parse out all of the panels in the template
		if ($input == false) {
			$tplData = $this->_GetTemplate();
		} else {
			$tplData = $input;
		}

		if (!isset($this->_tplName)) {
			// No template name specified
			trigger_error(sprintf('%s', GetLang('errNoTemplateNameSpecified')), E_USER_WARNING);
		} else {
			// Parse out the panel tokens in the template file
			preg_match_all('/(?siU)(%%Panel[\._][a-zA-Z0-9]{1,}%%)/', $tplData, $matches);

			foreach ($matches[0] as $key=>$k) {
				$pattern1 = $k;
				$pattern2 = str_replace('%', '', $pattern1);
				$pattern2 = str_replace('Panel_', '', $pattern2);
				$pattern2 = str_replace('Panel.', '', $pattern2);
				// Add id tags around each panel

				$data = $this->_GetPanelContent($pattern2);

				if (is_numeric(strpos($data,'%%Panel'))) {
					$data = $this->_ParsePanels($data);
				}
				$data = sprintf("\n<!-- Start %s -->\n%s\n<!-- End %s -->\n", $pattern2, $data, $pattern2);
				$tplData = str_replace($pattern1, $data, $tplData);
			}
		}
		
		return $tplData;
	}

	/**
	* _GetPanelContent
	* Get the contents for a given panel
	*
	* @param string $PanelId the name of the panel without the file extension
	*
	* @return string the html to put into the template to replace the keyword
	*/
	function _GetPanelContent($PanelId)
	{
		// Parse the PHP panel and return its content
		$panelData = '';
		$htmlPanelData = '';
		
		$panelHTMLFile = sprintf('%s%s.html', AKB_PANEL_LOAD_PATH, $PanelId);
		$panelPHPFile  = sprintf('%s%s.php', AKB_TPL_PHP_PATH, $PanelId);

		// If the panel can be shown, show it
		if (!isset($GLOBALS['HidePanels'])) {
			$GLOBALS['HidePanels'] = array();
		}

		if (!in_array($PanelId, $GLOBALS['HidePanels'])) {
			if (file_exists($panelHTMLFile) && file_exists($panelPHPFile)) {
				// Each panel has a generic panel parsing class. We will include
				// that file and parse the template
				$panelName = str_replace('PANEL', '_PANEL', strtoupper($PanelId));
				$panelClass = 'AKB_'.$panelName;

				include_once($panelPHPFile);

				$objPanel = new $panelClass();

				$objPanel->SetHTMLFile($panelHTMLFile);
				$panelData = $objPanel->ParsePanel();

			} else if (file_exists($panelHTMLFile) && !file_exists($panelPHPFile)) {
				$htmlPanelData = $this->ReadFile($panelHTMLFile);

				$parsedPanelData = $GLOBALS['AKB_CLASS_TEMPLATE']->ParseGL($htmlPanelData);
				$panelData = $parsedPanelData ;
			} else {
				$panelData = "<div>[Panel not found: '".$PanelId."']</div>";
			}
		}
		$panelData = $this->ParseTemplate(true, $panelData);
		return $panelData;
	}

	/**
	* GetSnippet
	* Load a snippet from disk
	*
	* @param string $PanelId The name of the snippet without the file extension
	*
	* @return string The snippet with global and language strings parsed from it
	*/
	function GetSnippet($PanelId)
	{

		$this->panelid = $PanelId;

		// grab the snippet file and return the content
		$snippetData = '';
		$snippetHTMLFile = sprintf('%s%s.html', AKB_SNIPPET_LOAD_PATH, $PanelId);
		


		if (file_exists($snippetHTMLFile)) {
			$snippetData = $this->ReadFile($snippetHTMLFile);

			if (isset($GLOBALS['DesignModeOn']) && $GLOBALS['DesignModeOn'] == 1) {
				$panelData = '<div class="Error">'.$panelData.'</div>';
			}
		} else {
			// snippet not found. output error
			$snippetData = "<div>[Snippet not found: '".$PanelId."']</div>";
		}
		
		

		return $this->ParseGL($snippetData);
	}

	/**
	* ParseSnippets
	* Parse the snippets from a template
	*
	* @param string $string the string to parse for snippets
	* @param mixed $snippets an array of snippets to parse
	*/
	function ParseSnippets($string,$snippets)
	{
		$matches = array();
		// Parse out the snippets
		preg_match_all('/(?siU)(%%SNIPPET_[a-zA-Z0-9_]{1,}%%)/', $string, $matches);

		foreach ($matches[0] as $key=>$val) {
			$pattern1 = $val;
			$pattern2 = str_replace('%', '', $pattern1);
			$pattern2 = str_replace('SNIPPET_', '', $pattern2);
			$string = str_replace($pattern1, @$snippets[$pattern2], $string);
		}
		if (is_numeric(strpos($string,'%%SNIPPET'))) {
			$string =$this->ParseSnippets($string,$snippets);
		}
		
		return $string;
	}

	/**
	* ParseGL
	* Parse global and language vars from a template/panel/snippet
	*
	* @param string $TemplateData The string to parse for vars
	*
	* @return string The string with the vars replaced
	*/
	function ParseGL($TemplateData)
	{
		// Parse out global and language variables from template data and
		// return it. This is used from the generic panel class for each panel
		$tplData = $TemplateData;
		$matches = array();
		
		// Parse out the language pack variables in the template file
		preg_match_all('/(?siU)(%%LNG_[a-zA-Z0-9]{1,}%%)/', $tplData, $matches);

		foreach ($matches[0] as $key=>$k) {
			$pattern1 = $k;
			$pattern2 = str_replace('%', '', $pattern1);
			$pattern2 = str_replace('LNG_', '', $pattern2);

			$tplData = str_replace($pattern1, @$GLOBALS['AKB_LANG'][$pattern2], $tplData);
		}

		// Parse out the global variables in the template file
		preg_match_all('/(?siU)(%%GLOBAL_[a-zA-Z0-9_]{1,}%%)/', $tplData, $matches);

		foreach ($matches[0] as $key=>$k) {
			$pattern1 = $k;
			$pattern2 = str_replace('%', '', $pattern1);
			$pattern2 = str_replace('GLOBAL_', '', $pattern2);
			
			$tplData = str_replace($pattern1, @$GLOBALS[$pattern2], $tplData);
		}
		
		$this->panelid = "";
		
		return $tplData;
	}

	/**
	* GetAndParseFile
	* Load a file from the network and parse it for global and lang strings
	*
	* @param string $File The file on the server to parse
	*
	* @return string the data that has been loaded and parsed
	*/
	function GetAndParseFile($File)
	{
		// Open a file, parse out tokens and return it

		$file = eregi_replace('[^http:]/{2,}', '/', sprintf('%s/%s', $GLOBALS['siteURL'], $File));
		$fdata = '';

		$_SERVER['SCRIPT_FILENAME'] = preg_replace('#/[A-Za-z]+\.php#','',$_SERVER['SCRIPT_FILENAME'] );
		$file = str_replace('//','/',str_replace($_SERVER['PHP_SELF'],'',$_SERVER['SCRIPT_FILENAME']).'/'.$File);

		if ($fp = fopen($file, 'rb')) {
			while (!feof($fp)) {
				$fdata .= fgets($fp, 4096);
			}
			fclose($fp);
		} else {
			$file = sprintf('../%s/%s', $GLOBALS['appPath'], $File);
			if ($fp = fopen($file, 'rb')) {
				while (!feof($fp)) {
					$fdata .= fgets($fp, 4096);
				}
				fclose($fp);
			}
		}

		$fdata = $this->ParseGL($fdata);

		return $fdata;
	}

	/**
	* ReadFile
	* Read a file from disk and return it's contents
	*
	* @param $file The path to and name of the file
	*
	* @return string The file's contents
	*/
	function ReadFile($file)
	{
		$contents = '';
		if (file_exists($file)) {
			if ($fp = fopen($file, 'rb')) {
				while (!feof($fp)) {
					$contents .= fgets($fp, 4096);
				}
				fclose($fp);
			}
		}
		return $contents;
	}
}

?>