<?php

function __autoload($className)
{
	$dirs = array('classes', 'models', 'controllers');

	$loaded = false;
	foreach ($dirs as $dir) {
		$fileName = dirname(__FILE__) . '/../ground/' . $dir . '/' . $className . '.php';

		if (file_exists($fileName)) {
			$loaded = (bool) include $fileName;
		}
	}

	if (!$loaded) {
		App::error404('Class ' . $className . ' was not loaded!');
		return false;
	}

	return true;
}

class App
{

	private static $url = array();
	private static $controller = 'IndexController';
	private static $action = 'actionIndex';
	private static $basedir = false;
	private static $config = array();
	private static $urlParams = array();
	private static $DB = null;
	public static $user = null;
	public static $request = array();

	/**
	 * Разбивает урл на контроллер, метод и выбирает параметры.
	 */
	private static function parseUrl()
	{
		$url = explode('?', $_SERVER['REQUEST_URI']);
		self::$url = explode('/', $url[0]);
		self::$controller = isset(self::$url[1]) && self::$url[1] ? ucfirst(self::$url[1]) . 'Controller' : self::$controller;
		self::$action = isset(self::$url[2]) && self::$url[2] ? 'action' . ucfirst(self::$url[2]) : self::$action;

		// Разбираем параметры из урла
		if ((count(self::$url) > 3) && (self::$url[3])) {
			for ($index = 3; $index < count(self::$url); $index = $index + 2) {
				$paramName = self::$url[$index];
				$paramValue = isset(self::$url[$index + 1]) && self::$url[$index + 1] ? self::$url[$index + 1] : NULL;
				self::$urlParams[$paramName] = $paramValue;
			}
		}
	}

	/**
	 * Основной метод для запуска приложения.
	 * @param string $config имя файла с конфигом
	 */
	public static function run($config = '')
	{
		ob_start();
		session_start();
		self::$config = $config ? include_once $config : array();
		self::parseUrl();

		self::userInit();

		$controller = self::$controller;
		$action = self::$action;

		self::fillRequest();

		if (method_exists($controller, $action)) {
			$controller::$action();
//			if (method_exists($controller, '__construct')) {
//				$class = new $controller();
//				$class->$action();
//			} else {
//				$controller::$action();
//			}
		} else {
			self::error404();
		}
	}

	public static function DB()
	{
		if (self::$DB === NULL && self::getConfig('DB')) {
			try {
				$confDB = self::getConfig('DB');
				self::$DB = new PDO('mysql:host=' . $confDB['host'] . ';dbname=' . $confDB['dbname'] . ';charset=utf8;', $confDB['user'], $confDB['password']);
			} catch (PDOException $e) {
				echo $e->getMessage();
			}
		}

		return self::$DB;
	}

	public static function error404($message = '')
	{
		header("HTTP/1.0 404 Not Found");
		PageController::action404($message ? $message : '404 - Not Found');
		die;
	}

	// Пытаемся восстановить пользователя из сессии
	public static function userInit()
	{
		if (isset($_SESSION['user_id']) && isset($_SESSION['user_key']) && $_SESSION['user_id'] && $_SESSION['user_key']) {
			$user = User::model()->getByPK((int) $_SESSION['user_id']);

			if ($user && md5($user->uid) == $_SESSION['user_key']) {
				App::$user = $user;
			}
		}
	}

	public static function userLogin($user)
	{
		$_SESSION['user_id'] = $user->id;
		$_SESSION['user_key'] = md5($user->uid);
		return true;
	}

	public static function userLogout()
	{
		$_SESSION['user_id'] = null;
		$_SESSION['user_key'] = null;
		return true;
	}

	/**
	 * Перенаправление на другой URL
	 * @param type $url
	 * @param type $httpCode - по умолчанию 307, временный редирект
	 */
	public static function redirect($url, $httpCode = 307)
	{
		header('Location: ' . $url, true, $httpCode);
		die;
	}

	/**
	 * Возвращает директорию фреймворка /full/path/ground/
	 * @return type
	 */
	public static function getBasedir()
	{
		if (!self::$basedir)
			self::$basedir = dirname(__FILE__) . '/';

		return self::$basedir;
	}

	/**
	 * Возвращает значение параметра из конфига
	 * @param string $paramName
	 * @return multi
	 */
	public static function getConfig($paramName)
	{
		return isset(self::$config[$paramName]) ? self::$config[$paramName] : NULL;
	}

	/**
	 * Устанавливает значение в конфиге
	 * @param string $paramName
	 * @param multi $paramValue
	 * @return true
	 */
	public static function setConfig($paramName, $paramValue)
	{
		self::$config[$paramName] = $paramValue;
		return true;
	}

	/**
	 * Возвращает значение параметра, переданного в URL
	 * @param string $paramName
	 * @return string
	 */
	public static function getParam($paramName)
	{
		return isset(self::$urlParams[$paramName]) ? self::$urlParams[$paramName] : NULL;
	}

	/**
	 * 	Возвращает массив параметров, переданных в URL
	 * @return	array
	 */
	public static function getParams()
	{
		return self::$urlParams;
	}

	private static function fillRequest()
	{
		self::$request = array(
			'method' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '',
			'ajax' => isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest',
			'refferer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
		);
	}

	public static function log($logName, $value)
	{
		$fileName = App::getBasedir() .
				'../logs/' .
				$logName . '.log';

		return file_put_contents(
				$fileName, date('d-m-Y H:i:s') . " - " .
				print_r($value, true) .
				"\n-------------------\n", FILE_APPEND
		);
	}

}
