<?php
/*
 * 各コアクラスを制御するクラス
*/
abstract class Application
{
	protected $debug = false;
	protected $request;
	protected $response;
	protected $session;
	protected $db_manager;

	public function __construct($debug=null){

		$this->setDebugMode($debug);
		$this->initialize();
		$this->configure();

	}

	/*
	 * デバッグモードに応じてエラー表示処理を変更する処理
	 */
	public function setDebugMode($debug){

		if($debug){
			$this->debug = true;
			ini_set('desplay_errors', 1);
			error_reporting(-1);
		} else {
			$this->debug = false;
			ini_set('desplay_errors', 0);
		}

	}

	/*
	 * クラスの初期化処理を行う処理
	 */
	public function initialize(){

		$this->request = new Request();
		$this->response = new Response();
		$this->session = new Session();
		$this->db_manager = new DbManager();
		$this->router = new Router($this->registerRoutes());

	}

	protected function configure(){}

	abstract public function getRootDir();

	abstract protected function registerRoutes();

	public function isDebugMode(){

		return $this->debug;

	}

	public function getRequest(){

		return $this->request;

	}

	public function getResponse(){

		return $this->response;

	}

	public function getSession(){

		return $this->session;

	}

	public function getDbManager(){

		return $this->db_manager;

	}

	public function getControllerDir(){

		return $this->getRootDir(). '/controllers';

	}

	public function getViewDir(){

		return $this->getRootDir(). '/Views';

	}

	public function getModelDir(){

		return $this->getRootDir(). '/models';

	}

	public function getWebDir(){

		return $this->getRootDir(). '/web';

	}

	/*
	 * コントローラーを特定し、レスポンス返信を管理する処理
	 */
	public function run(){

		try {
			$params = $this->router->resolve($this->request->getPathInfo());
			if($params === false){
				throw new HttpNotFoundException('No route fonud for' . $this->request->getPathInfo());
			}
			
			$controller = $params['controller'];
			$action = $params['action'];
			
			$this->runAction($controller, $action, $params);
		} catch (HttpNotFoundException $e) {
			$this->render404page($e);
		}
		

		$this->response->send();

	}

	/*
	 * アクションを実行する処理
	 */
	public function runAction($controller_name, $action, $params=array()){

		$controller_class = ucfirst($controller_name) . 'Controller';

		$controller = $this->findController($controller_class);
		if($controller === false){
			throw new HttpNotFoundException($controller_class . 'controller is not found');
		}

		$content = $controller->run($action, $params);

		$this->response->setContent($content);

	}

	/*
	 * コントローラークラスを生成する処理
	 */
	public function findController($controller_class){

		if(!class_exists($controller_class)){
			$controller_file = $this->getControllerDir() . '/' . $controller_class . '.php';
		}

		if(!is_readable($controller_file)){
			return false;
		} else {
			require_once $controller_file;

			if(!class_exists($controller_class)){
				return false;
			}
		}

		return new $controller_class($this);

	}




}