<?php

/**
 * Front controller
 *
 * Instantiates request and response objects, does request and response filtering,
 * dispatches request to concrete application controller and pushes returned view
 * into response object when needed.
 *
 * @version DR1.7
 */
class FrontCtrl {



	private $request;
	private $response;
	private $filters = array();



	/**
	 * Front controller constructor
	 *
	 * Instantiates request and response objects.
	 */
	public function __construct() {
		$this->request = RequestContext::getInstance();
		$this->response = ResponseContext::getInstance();
	}



	/**
	 * Appends given filter to filters chain
	 *
	 * @param InterceptingFilter $filter
	 */
	public function addFilter(InterceptingFilter $filter) {
		$this->filters[] = $filter;
	}



	/**
	 * Filters request, dispatches it to concrete application controller and filters its response
	 */
	public function dispatch() {
		$i = 0;
		$n = count($this->filters);
		while ($i < $n) {
			$this->filters[$i++]->preProcess($this->request, $this->response);
		}
		$action = $this->request->getAction();
		$args = $this->request->getArgs();
		if ($action) {
			$output = ActionService::execAction($action, $args);
			if ($output instanceof View) {
				$output->update();
			} elseif ($output) {
				$this->response->update($output);
			}
		}
		while ($i) {
			$this->filters[--$i]->postProcess($this->request, $this->response);
		}
	}



	/**
	 * Sends response to stdout
	 */
	public function finalize() {
		print($this->response);
	}



} // class FrontCtrl

?>