<?php
 
namespace elanpl\L3;
 
define('_L3_ROUTE_404_NAME', '_L3_404');
class Router{
 
    protected $routes; // The defined routes collection
    protected $routeNameIndex; // An array with elements that reference to the routes ordered by a route names
    public $parsedParameters; // Parameters parsed from Request Path
    public $depth; // Number of nested nodes in Request Path
    public $routeInfo; // The RouteInfo object if the route was matched
 
    public function __construct($routing)
    {
        $this->routes = array(); 
        $this->routeNameIndex = array();
        //Set the routing from configuration object
        $routing->set($this);
    }
 
    public function add($method, $path, $result, $name = ''){
        $this->routes[] = new RouteInfo($method, $path, $result, $name);
        if(isset($name)&&$name!='') $this->routeNameIndex[$name] = &$this->routes[count($this->routes)-1];
        return $this;
    }
 
    public function add_preg($method, $path, $result, $name = ''){
        $this->routes[] = new RouteInfo($method, $path, $result, $name, RouteInfo::REGEX);
        if(isset($name)&&$name!='') $this->routeNameIndex[$name] = &$this->routes[count($this->routes)-1];
        return $this;
    }
 
    public function add404($result){
        return $this->add('404', '', $result, _L3_ROUTE_404_NAME);
    }
 
    public function get($path, $result, $name = ''){
        return $this->add('GET', $path, $result, $name);
    }
 
    public function post($path, $result, $name = ''){
        return $this->add('POST', $path, $result, $name);
    }
 
    public function put($path, $result, $name = ''){
        return $this->add('PUT', $path, $result, $name);
    }
 
    public function patch($path, $result, $name = ''){
        return $this->add('PATCH', $path, $result, $name);
    }
 
    public function delete($path, $result, $name = ''){
        return $this->add('DELETE', $path, $result, $name);
    }
 
    public function any($path, $result, $name = ''){
        return $this->add('ANY', $path, $result, $name);
    }
 
    // Regular expression based routes
 
    public function get_preg($path, $result, $name = ''){
        return $this->add_preg('GET', $path, $result, $name);
    }
 
    public function post_preg($path, $result, $name = ''){
        return $this->add_preg('POST', $path, $result, $name);
    }
 
    public function put_preg($path, $result, $name = ''){
        return $this->add_preg('PUT', $path, $result, $name);
    }
 
    public function patch_preg($path, $result, $name = ''){
        return $this->add_preg('PATCH', $path, $result, $name);
    }
 
    public function delete_preg($path, $result, $name = ''){
        return $this->add_preg('DELETE', $path, $result, $name);
    }
 
    public function any_preg($path, $result, $name = ''){
        return $this->add_preg('ANY', $path, $result, $name);
    }
 
    public function addBeforeAction($event_handler){
        $this->routes[count($this->routes)-1]->addBeforeAction($event_handler);
        return $this;
    }
 
    public function addAfterAction($event_handler){
        $this->routes[count($this->routes)-1]->addAfterAction($event_handler);
        return $this;
    }
 
    public function addAfterResult($event_handler){
        $this->routes[count($this->routes)-1]->addAfterAction($event_handler);
        return $this;
    }
 
    public function cleanPregMatch($match){