<?php

class SimplePagehandler
	//extends RequestHandler
	implements iRequestHandler
{

	protected $simpleUrl;
	protected $simpleDocument;
	protected $snippets;
	//protected $simpleWidgets;



	public function __construct(SimpleUrl $simpleUrl)
	{
		$this->simpleUrl = $simpleUrl;

		////////////////////////////////////////////////////////////////////////
		// просмотр возврата от SimpleURL
		if ($simpleUrl->debug()) $simpleUrl->get_urlinfo();
		////////////////////////////////////////////////////////////////////////
		//echo $simpleUrl->doc_id;

		$this->snippets = new SimplePageSnippets($this);
	}



	final public function run()
	{
		if ($this->authorizedAccess()
			&& !$this->user()->isAuthorized()
		) {
			$this->showLogin();
			return;
		}
		// echo $this->page_type;
		//	exit;
//		print_a($this);
		$this->snippets->run();

		if (!$this->snippets->isOutputPrevented()) {
			return $this->process();
		}
	}

	public function showLogin()
	{
		$this->renderer()->display('content.login.tpl');
	}

	final protected function authorizedAccess()
	{
		global $authorizedAccessPageAliases;
		//$authorizedPageTypes = array('panel');
		$authorizedPageIds = array();

		if (in_array($this->page_type, $authorizedAccessPageAliases)) {
			return true;
		}
		if (in_array($this->page_id, $authorizedPageIds)) {
			return true;
		}
		return false;
	}

	/**
	 * Предполагается вызов этой функции из потомков.
	 * Берётся первый сегмент URL-a, не являющийся разделом сайта, и вызывается
	 * метод с таким именем. Если такого метода нет -- выдаётся ошибка.
	 * Если URL состоит только из разделов, вызывается метод index();
	 * 
	 * В дальнейшем предполагается возможность разбора URL регулярным выражением,
	 * задаваемым потомком.
	 */
	final protected function executeAction() {
		$params = $this->simpleUrl()->params;
		$action = get("action", $params["url"][0]);
		if (empty($action)) {
			if (method_exists($this, "index")) {
				$this->index();
			} else {
				$this->renderDefault();
			}
			return;
		}
		if (method_exists($this, $action)) {
			$this->$action($params);
		} else {
			throw new NotFoundException("Unknown action: $action");
		}
		
	}
	/*
	* Метод выполняет запрощенное действие. Подлежит переопределению в
	* дочерних классах.
	* 
	*/
	protected function process()
	{
		$this->renderDefault();
	}
	
	
	/**
	 * Создание Smarty-шаблона с поиском файла с учётом имени namespace
	 */
	protected function createTemplate($templateName) {
		$reflection = new \ReflectionClass($this);
		$namespace = $reflection->getNamespaceName();
		$renderer = $this->renderer();
		$tpl = null;
		if ($renderer->templateExists($namespace . "/" . $templateName)) {
			$tpl = $renderer->createTemplate($namespace . "/" . $templateName);
		} else {
			$tpl = $renderer->createTemplate($templateName);
		}
		return $tpl;
	}
	
	protected function getDefaultTemplateName() {
		$pageType = $this->page_type;
		//Если $pageType содержит слеши (namespace) -- удаляем корень
		$namespaceUsed = false;
		if (strpos($pageType, "\\") !== false) {
			$namespaceUsed = true;
			$pageType = substr($pageType, 1);
			$path = explode('\\', $pageType);
			$pageType = array_pop($path);
			$templateFileName = implode(".", $path) . ".content.{$pageType}.tpl";
		} else {
			$templateFileName = "content.{$pageType}.tpl";
		}
		if (!$this->renderer()->templateExists($templateFileName)) {
			//Если не нашли {namespace}.content.{$pageType}.tpl --
			//попробуем найти {namespace}/content.{$pageType}.tpl
			if ($namespaceUsed) {
				$templateFileName = implode("/", $path) . "/content.{$pageType}.tpl";
				if (!$this->renderer()->templateExists($templateFileName)) {
					$templateFileName = BASE_TMPLT;
				}
			} else {
				$templateFileName = BASE_TMPLT;
			}
		}
		return $templateFileName;
	}

	protected function createDefaultTemplate() {
		$templateFileName = $this->getDefaultTemplateName();
		return $this->renderer()->createTemplate($templateFileName);
	}

	final protected function renderDefault() {
		$templateFileName = $this->getDefaultTemplateName();
		$this->renderer()->assign("pagehandler", $this);
		$this->renderer()->display($templateFileName);
	}

	/**
	* @todo пересмотреть назначение функции
	*/
	public function makeUrl($urlParts=array())
	{
		$url_obj = array(
			'region' => $this->simpleUrl->get_region(),
			'country' => $this->simpleUrl->get_country(),
			'section1' => $this->simpleUrl->get_section(0),
			'section2' => $this->simpleUrl->get_section(1),
			'section3' => $this->simpleUrl->get_section(2),
			'object' => $this->simpleUrl->get_objectname(),
		);

		$p = array();
		foreach ($urlParts as $k=>$v) {
			if ($k=='mode') {
				$url_obj['mode'] = $v;
			} else {
				$p []= "{$k}={$v}";
			}
		}

		$url = $this->simple_url->get_url($url_obj);
		if (count($p)) {
			$url = $url . '?' . join('&', $p);
		}
		return $url;
	}



	public function __get($name)
	{
		switch ($name)
		{
			case 'page_id':
				return $this->simpleUrl->doc_id;
			break;

			case 'page_type':
				return $this->simpleUrl->get_pagetype();
			break;

			case 'doc':
				return $this->simpleDocument;
			break;

			case 'simple_url':
				return $this->simpleUrl;
			break;

			default:
				throw new Exception('Unknown object property:' . $name);
			break;

		}
	}

	/**
	* @return SimpleUrl
	*/
	public function simpleUrl() {
		return $this->simpleUrl;
	}
	
	/**
	 * корневой адрес pagehandler-а
	 */
	public function baseUrl() {
		$baseUrl = $this->simpleUrl->url_str;
		if (defined("SUB_URL")) {
			$baseUrl = SUB_URL . $baseUrl;
		}
		return $baseUrl;
	}
	/**
	* @global WebUserAuth $currentUser
	* @return WebUserAuth
	*/
	public function user() {
		global $currentUser;
		return $currentUser;
	}
	
	/**
	 * 
	 * @return Smarty
	 */
	public function renderer() {
		return carabiSite::getRenderer();
	}
	
	/**
	 *
	 * @return SimpleDocument
	 */
	public function document() {
		return $this->simpleDocument;
	}

	public function __call($name, $args)
	{
		switch ($name) {
			case 'id':
				return $this->simpleDocument->document_id;
			break;

			default:
				throw new Exception('Unknow object method:' . $name);
			break;
		}
	}

	public function openedWithBot() {
		return carabiSite::openedWithBot();
	}

}

?>