<?php
/**
 * Класс для работы с роутерами 
 *
 * @copyright 
 * @link 
 * @package Majestic
 * @subpackage Core
 * @since 
 * @version SVN: $Id$
 * @filesource $URL$
 */

final class Router
{
    protected $routes = array();

    /**
     * Добавить роутер
     *
     * @param string $name - имя роутера
     * @param string $path - путь
     * @param string $action - имя действия
     * @param array $params - массив параметров
     */
    function add($name, $path, $action, $params = array())
    {
        $this->routes[$name] = new Route($path, $action, $params);
    }

    /**
     * Установить декоратор для роута (действия), отличный от стандартного
     *
     * @param string $name - имя роута (действия)
     * @param string $decorator - имя декоратора
     */
    function setDecorator($name, $decorator)
    {
        if (isset($this->routes[$name])) {
            $this->routes[$name]->decorator = $decorator.DECORATOR_POSTFIX;
        }
    }

    /**
     * Найти роутер соответствующий заданному пути
     *
     * @param stirng $path - путь
     * @return Route - роутер
     */
    function proccess($path)
    {
        $path = explode('/', $path);

        foreach ($this->routes as $name => $route) {
            if ($route->match($path)) {
                $route->action .= ACTION_POSTFIX;
                Env::setParams($route->params);
                return $route;
            }
        }
        throw new Exception(E_404);
    }
}

/**
 * Роутер
 *
 */
final class Route
{
    const URL_VARIABLE = '&';

    protected $path;

    public $decorator = DEFAULT_DECORATOR;
    public $action;
    public $params;

    function __construct($path, $action, $params=array())
    {
        $this->path     = $path;
        $this->action   = $action;
        $this->params   = $params;
    }

    /**
     * Проверяет соответствие роутера и пути
     *
     * @param string $path - путь для сравнения
     * @return boolean - соответствует или нет
     */
    function match($path_arr)
    {
        $parts = explode('/', $this->path);
        $cnt   = count($parts);
        if (end($parts) == self::URL_VARIABLE) {
            $cnt--;
        } elseif ($cnt != count($path_arr)) {
            return false;
        }

        for ($i=0; $i<$cnt; $i++) {
            if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) {
                $this->params[substr($parts[$i], 1)] = $path_arr[$i];
            } elseif ($parts[$i] != $path_arr[$i]) {
                return false;
            }
        }

        return true;
    }
}
?>