<?php

/**
 * This class is a simplified version of the one implemented in includes/class_core.php
 */
class vB5_Template
{
	const WIDGET_ERROR_TEMPLATE = 'widget_error';

	/**
	 * Name of the template to render
	 *
	 * @var	string
	 */
	protected $template = '';

	/**
	 * Array of registered variables.
	 * @see vB5_Template::preRegister()
	 *
	 * @var	array
	 */
	protected $registered = array();

	/**
	 * List of templates rendered (for debugging output)
	 *
	 * @var array
	 */
	protected static $renderedTemplates = array();
	protected static $renderedTemplatesStack = array();

	/*
	 * jQuery URL
	 */
	protected static $jQueryUrl = '';
	protected static $jQueryUrlLogin = '';

	/**
	 * Constructor
	 */
	public function __construct($templateName)
	{
		$this->template = $templateName;

		$this->register('admincpdir', vB5_Config::instance()->admincpdir);
		$this->registerjQuery();
	}

	/**
	 * Register a variable with the template.
	 *
	 * @param	string	Name of the variable to be registered
	 * @param	mixed	Value to be registered. This may be a scalar or an array.
	 * @param	bool	Whether to overwrite existing vars
	 * @return	bool	Whether the var was registered
	 */
	public function register($name, $value, $overwrite = true)
	{
		if (!$overwrite AND $this->isRegistered($name))
		{
			return false;
		}

		$this->registered[$name] = $value;

		return true;
	}

	/**
	 * Determines if a named variable is registered.
	 *
	 * @param	string	Name of variable to check
	 * @return	bool
	 */
	public function isRegistered($name)
	{
		return isset($this->registered[$name]);
	}

	protected function registerjQuery()
	{
		if (!self::$jQueryUrl)
		{
			// create the path to jQuery depending on the version
			$customjquery_path = vB::getDatastore()->getOption('customjquery_path');
			$remotejquery = vB::getDatastore()->getOption('remotejquery');
			if ($customjquery_path)
			{
				$path = str_replace('{version}', JQUERY_VERSION, $customjquery_path);
				if (!preg_match('#^https?://#si', $customjquery_path))
				{
					$path = REQ_PROTOCOL . '://' . $path;
				}
				self::$jQueryUrlLogin = self::$jQueryUrl = $path;
			}
			else if ($remotejquery == 1)
			{	// Google CDN
				self::$jQueryUrlLogin = self::$jQueryUrl = REQ_PROTOCOL . '://ajax.googleapis.com/ajax/libs/jquery/' . JQUERY_VERSION . '/jquery.min.js';
			}
			else if ($remotejquery == 2)
			{	// jQuery CDN
				self::$jQueryUrlLogin = self::$jQueryUrl = REQ_PROTOCOL . '://code.jquery.com/jquery-' . JQUERY_VERSION . '.min.js';
			}
			else if ($remotejquery == 3)
			{	// Microsoft CDN
				self::$jQueryUrlLogin = self::$jQueryUrl = REQ_PROTOCOL . '://ajax.aspnetcdn.com/ajax/jquery/jquery-' . JQUERY_VERSION . '.min.js';
			}
			else
			{
				self::$jQueryUrl = vB5_Config::instance()->baseurl . '/js/jquery/jquery-' . JQUERY_VERSION . '.min.js';
				self::$jQueryUrlLogin = vB5_Config::instance()->baseurl_login . '/js/jquery/jquery-' . JQUERY_VERSION . '.min.js';
			}
		}

		$this->register('jqueryurl', self::$jQueryUrl);
		$this->register('jqueryurl_login', self::$jQueryUrlLogin);
		$this->register('jqueryversion', JQUERY_VERSION);
	}

	/**
	 * Renders the output after preperation.
	 * @see vB5_Template::render()
	 *
	 * @param boolean	Whether to suppress the HTML comment surrounding option (for JS, etc)
	 * @return string
	 */
	public function render($isParentTemplate = true)
	{
		extract($this->registered, EXTR_SKIP | EXTR_REFS);

		$baseurl = vB5_Config::instance()->baseurl;
		$baseurl_core = vB5_Config::instance()->baseurl_core;
		$baseurl_login = vB5_Config::instance()->baseurl_login;
		$user = vB5_User::instance();

		$baseurl_data = parse_url($baseurl);

		if (isset($baseurl_data['path']))
		{
			$baseurl_path = $baseurl_data['path'];
		}
		$baseurl_path = isset($baseurl_path) ? ($baseurl_path . (substr($baseurl_path, -1) != '/' ? '/' : '')) : '/'; //same as cookie path

		$cookie_prefix = vB5_Config::instance()->cookie_prefix;

		$templateCode = vB5_Template_Cache::instance()->getTemplate($this->template);

		$vb5_config = vB5_Config::instance();
		$vboptions = vB5_Template_Options::instance()->getOptions();
		$vboptions = $vboptions['options'];

		$timenow = time();

		// debug info for the templates that have been used
		if ($vb5_config->debug)
		{
			self::$renderedTemplates[$this->template] = array(
				'isParentTemplate' => (bool) $isParentTemplate,
				'indent' => str_repeat('|----', count(self::$renderedTemplatesStack)),
			);
			self::$renderedTemplatesStack[] = $this->template;

			// variable accessed from the footer template.
			$renderedTemplates = array(
				'count' => count(self::$renderedTemplates),
				'templates' => self::$renderedTemplates,
				'styleid' => vB5_Template_Stylevar::instance()->getPreferredStyleId(),
			);

		}

		// todo: remove this once we can remove notices from template code
		// allow developers to turn notices off for templates -- to avoid having them turn off notices entirely
		$config = vB5_Config::instance();
		if ($config->no_template_notices)
		{
			$oldReporting = error_reporting(E_ALL & ~E_NOTICE);
		}

		if (strpos($templateCode, '$final_rendered') !== false)
		{
			@eval($templateCode);
		}
		else
		{
			@eval('$final_rendered = "' . $templateCode . '";');
		}

		if ($config->no_template_notices)
		{
			error_reporting($oldReporting);
		}

		// always replace placeholder for templates, as they are process by levels
		$templateCache = vB5_Template_Cache::instance();
		$templateCache->replacePlaceholders($final_rendered);

		if ($isParentTemplate)
		{
			// we only replace phrases, insert javascript and stylesheets at the parent template
			$javascript = vB5_Template_Javascript::instance();
			$javascript->insertJs($final_rendered);
			$javascript->resetPending();

			$stylesheet = vB5_Template_Stylesheet::instance();
			$stylesheet->insertCss($final_rendered);
			$stylesheet->resetPending();

			$phrase = vB5_Template_Phrase::instance();
			$phrase->replacePlaceholders($final_rendered);
			$phrase->resetPending();
		}

		// debug info for the templates that have been used
		if ($vb5_config->debug)
		{
			array_pop(self::$renderedTemplatesStack);
		}

		// add template name to HTML source for debugging
		if (!empty($vboptions['addtemplatename']) AND $vboptions['addtemplatename'])
		{
			$final_rendered = "<!-- BEGIN: $this->template -->$final_rendered<!-- END: $this->template -->";
		}

		return $final_rendered;
	}
}
