<?php namespace Majestic\App;
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage app
 * @since 2010-02-24
 */

class FrontController
{
    /**
     * @var Router\Router
     */
    protected $router;

    /**
     * @var string
     */
    protected $view = '\Majestic\View\PHPView';

    protected $base_url = '';

    /**
     * @var FrontController
     */
    protected static $instance;


    private function __construct()
    {
//        \Majestic\Exception\ErrorHandler::init();
        $this->router = new Router\Router();
    }

    /**
     * Refuse cloning
     * @codeCoverageIgnoreStart
     */
    private function __clone()
    {
    }

    /**
     * @codeCoverageIgnoreEnd
     */

    /**
     * @return FrontController
     */
    static public function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * @param string $view
     * @return FrontController
     */
    public function setView($view)
    {
        $this->view = $view;
        return $this;
    }

    /**
     *
     * @param null $view
     * @return ..\View\PHPView
     */
    public function getView($view = null)
    {
        $view = ($view) ? $view : $this->view;
        return new $view(\Majestic\Config::get($view));
    }

    /**
     * @param string $url
     * @return FrontController
     */
    public function setBaseUrl($url)
    {
        $this->base_url = rtrim($url, '/');
        return $this;
    }

    public function getBaseUrl()
    {
        return $this->base_url;
    }

    /**
     * @return Router\Router
     */
    public function getRouter()
    {
        return $this->router;
    }

    public function execute()
    {
        $request = \Majestic\Env::getRequestUri(true);
        $route = $this->getRouter()->route($request);
        if (!$route) {
	        $message = 'Route for "' . $request . '" not found';
	        \App::abort(404, $message);
        }

        $action_class = $route->getAction();
        if (!class_exists($action_class)) {
            throw new \Majestic\Exception\GeneralException('Action class "' . $action_class . '" not found.');
        }

        $action = new $action_class();
        $layout_class = $route->getLayout();
        if (!class_exists($layout_class)) {
            throw new \Majestic\Exception\GeneralException('Layout class "' . $layout_class . '" not found.');
        }

        /**
         * @var \Majestic\Layout\Layout $layout
         */
        $layout = new $layout_class();
        $html = $layout->fetch($action);
        if (\Majestic\Config::get('PROFILER')) {
            if (is_subclass_of($action, 'AjaxAction')) {
                \Majestic\Util\Profiler\Profiler::getInstance()->getJson();
            } else {
                $html = \Majestic\Util\Profiler\Profiler::getInstance()->end($html);
            }
        }
        return $html;
    }
}