<?php
 
namespace elanpl\L3;
 
class Application{
    public $config; // L3 Config object
    public $request; // build from received HTTP request or created in L3 Config object
    public $response; // response to be send
    public $router; // routing engine
    public $serialization; // serialization engine
    public $viewEngines; // view engines configuration
    public $baseDirectory; // directory root of the application
    public $controllersDirectory; // subdirectory/namespace part added to controller class 
    public $viewsDirectory; // subdirectory to search for the view files
    public $applicationDirectory; // subdirectory/namespace part of the application
    public $controller; //Active controller
    public $module; //Active module
    public $action; //Active action
 
    public function __construct($config){
        //set L3 application config
        $this->config = $config;
        // directory root of the application
        $this->baseDirectory = $config->getBaseDirectory();
        // subdirectory/namespace part added to controller class
        $this->controllersDirectory = $config->getControllersDirectory();
        // subdirectory to search for the view files 
        $this->viewsDirectory = $config->getViewsDirectory();
        // subdirectory/namespace part of the application
        $this->applicationDirectory = $config->getApplicationDirectory();
        //create request object
        $this->request = $this->config->getRequest();
        //create router object
        $this->router = new Router($this->config->getRouting());
        //create response objcet
        $this->response = new Response();
 
        //create serialization object
        $this->serialization = new Serialization(); 
        //create view engines configuretion object
        $this->viewEngines = new ViewEngine();
 
        //perform configuration operations
        $this->config->configure($this);
    }
 
    public function basePath(){
        return strstr($_SERVER['REQUEST_URI'], $this->request->path, true);
    }
 
    public function getServerURL(){
        return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://{$_SERVER['HTTP_HOST']}";
    }
 
    public function getURL(){
        return $this->getServerURL().$_SERVER['REQUEST_URI'];
    }
 
    public function relPath($file){
        return ($this->router->depth>0 ? str_repeat("../", substr($this->request->path,-1)=='/'?$this->router->depth:$this->router->depth-1) : "" ).$file; 
    }
 
    public function link($name, $parameters){
        return $this->router->link($name, $parameters);
    }
 
    /*
    //not need - PSR-4 autoload handles that
    function IncludeControler($Controller){
        include_once(_L3_CONTROLLER_PATH.$Controller.'.php');
    }*/
 
    public function findControllerInCallStack($search_level=5){
        //search for controller, action and module if present
        $controller = "";
        $module = "";
        $action = "";
        $match = array();
 
        //analize the call stack
          $call_stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $search_level);
        
        for($i=0; $i<$search_level; $i++){
            if(preg_match(
                    $pattern = '#('.$this->applicationDirectory.')(\\\\(?P<module>.+))?\\\\'.$this->controllersDirectory.'\\\\(?P<controller>.+)#',
                    $call_stack[$i]['class'],
                    $match
                )
            ){
                $action = $call_stack[$i]['function'];
                $module = $match['module'];
                $controller = $match['controller'];
                break;
            }
        }
 
        return array(
            'module' => $module,
            'controller' => $controller,
            'action' => $action
        );
    }