<?php

/**
 * Exception extention.
 */
class PHPDS_exception extends Exception
{
	protected $ignoreLines = 0;
	protected $extendedMessage = '';

	public function __construct($message = "", $code = 0, $previous = null)
	{
		if (is_a($previous, 'Exception')) {
			$this->file = $previous->getFile();
			$this->line = $previous->getLine();
			$this->message .= $previous->getMessage();
			$this->trace = $previous->getTrace();
			$this->code = $previous->getCode();
			if (empty($this->code)) $this->code = $code;
			if (is_a($previous, 'PHPDS_exception')) $this->extendedMessage .= $previous->getExtendedMessage();
			if ($message) $this->extendedMessage .= $message;
		} else {
			$this->message = $message;
			$this->code = $code;
		}

		/*$this->ignoreLines = $code;
		$this->code = 0;*/
	}

	public function getignoreLines()
	{
		return $this->ignoreLines;
	}

	public function getExtendedMessage()
	{
		return $this->extendedMessage;
	}

	public function getExtendedTrace()
	{
		return empty($this->trace) ? $this->getTrace() : $this->trace;
	}

	/**
	 * some Exception may choose to display some possible cause for the error, to help tracking down the error
	 */
	public function hasCauses()
	{
		return false;
	}

	/**
	 *  returns a special message and a list of possible causes
	 */
	public function getCauses()
	{
		return null;
	}
}

class PHPDS_fatalError extends PHPDS_exception
{
	public function __construct($message = "", $code = 0, $previous = null)
	{
		$error = error_get_last();

		if (isset($error['message'])) $this->message = $error['message'];
		if (isset($error['type'])) $this->code = $error['type'];
		if (isset($error['file'])) $this->file = $error['file'];
		if (isset($error['line'])) $this->line = $error['line'];

		//$this->ignoreLines = 2;
	}
}

class PHPDS_databaseException extends PHPDS_exception
{

	public function hasCauses()
	{
		return in_array($this->getCode(), array(
			1045, // access denied
			0,  // unknown error
			1049,  // unknown database
			2002,
			1146 // table doesn't exist
			));
	}

	public function getCauses()
	{
		switch ($this->getCode()) {
			case 1045: $special = 'db_access_denied'; break;
			case 0: $special = 'db_unknown'; break;
			case 1049: $special = 'db_unknown'; break;
			case 2002: $special = 'db_silent'; break;
			case 1146: $special = 'db_noexist'; break;
		}

		$coding_error = array(
			'<div class="warning">PHP Coding error interrupted query model, see uncaught exception below.</div>',
			'This is normally nothing too serious just check your code and find the mistake you made by following the exception below.'
		);
		$phpds_not_installed = array(
			'<div class="warning">PHPDevShell received a database error, did you run the install script yet?</div>',
			'If you haven\'t run the installation procedure yet, you should <a href="other/service/index.php">run it</a> now.'
		);
		$db_wrong_cred = array(
			'<div class="warning">It is possible that the wrong credentials have been given in the configuration file.</div>',
			'Please check the content of your configuration file(s).'
		);
		$db_wrong_dbname = array(
			'<div class="warning">It is possible that the wrong database name has been given in the configuration file.</div>',
			'Please check the content of your configuration file(s).'
		);
		$db_denies = array(
			'<div class="warning">The server won\'t accept the database connection.</div>',
			'Please check if the database server is up and running.'
		);

		switch ($special) {
			case 'db_access_denied': $result = array(
				'Access to the database was not granted using the parameters set in the configuration file.',
				array($phpds_not_installed, $db_wrong_cred, $db_denies)
			); break;
			case 'db_silent': $result = array(
				'Unable to connect to the database.',
				array($db_wrong_cred, $db_denies)
			); break;
			case 'db_unknown': $result = array(
				'The connection to the server is ok but the database could not be found.',
				array($coding_error, $phpds_not_installed, $db_wrong_dbname)
			); break;
			case 'db_noexist': $result = array(
				'The connection to the server is ok and the database is known but the table doesn\'t exists.',
				array($phpds_not_installed, $db_wrong_dbname)
			); break;
			default: $result = array(
				'Unknown special case.',
				array()
			);
		}
		return $result;
	}

}


class PHPDS_accessException extends PHPDS_exception
{
	public $HTTPcode;
}

class PHPDS_securityException extends PHPDS_accessException
{
	public $HTTPcode = 401;
}

class PHPDS_securityException403 extends PHPDS_accessException
{
	public $HTTPcode = 403;
}

class PHPDS_pageException404 extends PHPDS_accessException
{
	public $HTTPcode = 404;
}

class PHPDS_pageException418 extends PHPDS_accessException
{
	public $HTTPcode = 418;
}



class PHPDS_sprintfnException extends PHPDS_exception
{

	public function __construct($message = "", $code = 0, $previous = null) // CAUTION this declaration is NOT correct
	{
		$msg = '<p>The faulty string source is:<br /><pre class="ui-state-highlight ui-corner-all">'.htmlentities($message).'</pre><br />';
		if (!empty($code)) $msg .= 'The parameters were:<br /><tt>'.PU_dumpArray($code, null, true).'</tt></p>';

		parent::__construct($msg, 0, $previous);
	}

	public function hasCauses()
	{
		return true;
	}

	public function getCauses()
	{
		$result = array(
			'Unable to build a string with <i>sprintfn</i>',
			array(
				array('Some template or theme file has altered a module which doesn\'t comply to the given parameters.', 'Try a different theme or check for possible typos in the theme module list')
			)
		);

		return $result;
	}

}
