<?php

/**
 * Main Class
 * @author franzz
 * @version 2.0
 */
class MyThoughts extends Main
{
	//Interface keywords
	const SUCCESS = 'success';
	const ERROR = 'error';
	const UNAUTHORIZED = 'unauthorized';
	const NOT_FOUND = 'unknown action';
	
	//SQL tables
	const USER_TABLE = 'users';
	const SETTINGS_TABLE = 'settings';
	
	//Mythoughts
	const URL_DATE_FORMAT = 'Ymd';
	const LAYOUT_DATE_FORMAT = 'F \t\h\e jS, Y';
	const MYSQL_DATE_FORMAT = 'Y-m-d';
	const LAYOUT_TIME_FORMAT = 'G:i';
	const WELCOME_MSG_FILE = 'welcome';
	const SETTING_LAYOUT = 'layout';
	const LAYOUT_ONE_PAGE = '1';
	const LAYOUT_TWO_PAGES = '2';
	const SETTING_FONT = 'font';
	const FONT_THOUGHTS = 'thoughts';
	const FONT_ARIAL = 'Arial';
	const FONT_VERDANA = 'Verdana';
	const SETTING_SIZE = 'Size';
	const SIZE_16 = '16';
	const SIZE_18 = '18';
	const SIZE_20 = '20';
	const LAST_THOUGHT_LIMIT = 60*60*24;
	
	//Format
	const OBJ = 'object';
	const ARRAY = 'array';
	const JSON = 'json';
	
	/**
	 * Auth Object
	 * @var Auth
	 */
	private $oAuth;	
	
	/**
	 * Main constructor [to be called from index.php]
	 * @param ClassManagement $oClassManagement
	 * @param string $sLang
	 */
	public function __construct($oClassManagement, $sProcessPage)
	{
		//Load classes
		//$this->oClassManagement->incClass('calendar', true);
		$asClasses = array(	array('name'=>'auth', 'project'=>true),
							array('name'=>'thought', 'project'=>true));
		
		parent::__construct($oClassManagement, $sProcessPage, $asClasses);
		
		//Init objects
		if($this->oDb->sDbState == Db::DB_PEACHY) $this->oAuth = new Auth($this->oDb, Settings::API_KEY);
	}
	
	protected function install()
	{
		$this->oAuth = new Auth($this->oDb, Settings::API_KEY, false);
		
		//Install DB
		$this->oDb->install();
		$this->oAuth->addUser('franzz', 'Franzz', '123456');
	}
	
	private function setContext($sProcessPage)
	{
		//Browser <> PHP <> MySql synchronization
		date_default_timezone_set(Settings::TIMEZONE);
		ini_set('default_charset', Settings::TEXT_ENC);
		header('Content-Type: text/html; charset='.Settings::TEXT_ENC);
		mb_internal_encoding(Settings::TEXT_ENC);
		mb_http_output(Settings::TEXT_ENC);
		mb_http_input(Settings::TEXT_ENC);
		mb_language('uni');
		mb_regex_encoding(Settings::TEXT_ENC);
		
		$this->asContext['process_page'] = basename($sProcessPage);
	
		$sServerName = array_key_exists('SERVER_NAME', $_SERVER)?$_SERVER['SERVER_NAME']:$_SERVER['PWD'];
		$sAppPath = 'http://'.str_replace('http://', '', $sServerName.dirname($_SERVER['SCRIPT_NAME']));
		$this->asContext['serv_name'] = $sAppPath.(mb_substr($sAppPath, -1)!='/'?'/':'');
	}
	
	public function addUncaughtError($sError)
	{
		$this->addError('Uncaught errors:'."\n".$sError);
	}
	
	/* Authorizations handling */
	
	public function register($sToken, $sNickname)
	{
		$asResult = $this->oAuth->register($sToken, $sNickname);
		
		if($asResult['success']) return $this->logMeIn($sToken);
		else return self::getJsonResult($asResult['success'], $asResult['desc']);
	}
	
	public function isLoggedIn()
	{
		return $this->oAuth->isLoggedIn();
	}
	
	public function logMeIn($sToken)
	{
		$asLogResult = $this->oAuth->logMeIn($sToken);
		return MyThoughts::getJsonResult($asLogResult['success'], $asLogResult['desc'], $this->getVars());
	}
	
	public function checkApiKey($sApiKey)
	{
		return $this->oAuth->checkApiKey($sApiKey);
	}
	
	/* Building main pages */
	
	public function getPage()
	{
		//Constants
		$asGlobalVars = array(
			'consts'	=> array(
				'token_sep'	=> Auth::TOKEN_SEP,
				'error'		=> self::ERROR,
				'success'	=> self::SUCCESS,
				'context'	=> $this->asContext,
				'cookie'	=> Auth::USER_COOKIE_PASS
			),
			'vars'		=> $this->getVars()
		);
		
		//Pages
		$asPages = array('logon', 'logoff', 'write', 'read', 'settings', 'template', 'editor');
		foreach($asPages as $sPage) $asGlobalVars['consts']['pages'][$sPage] = $this->getPageContent($sPage);
		
		//Main Page
		$sPage = $this->getPageContent('index');
		$sPage = str_replace('asGlobalVars', json_encode($asGlobalVars), $sPage);
		return $sPage;
	}
	
	private function getVars() {
		return array(
			'id'		=> $this->oAuth->getUserId(),
			'log_in'	=> $this->isLoggedIn()
		);
	}
	
	/* DB structure. See Db::__construct */
	
	protected function getSqlOptions()
	{
		return array(
			'tables' =>	array(
				self::USER_TABLE		=> array(Db::getText(self::USER_TABLE), 'nickname', 'pass', 'cookie'),
				Thought::THOUGHT_TABLE	=> array(Db::getId(self::USER_TABLE), Db::getText(Thought::THOUGHT_TABLE), 'created'),
				self::SETTINGS_TABLE	=> array(Db::getId(self::USER_TABLE), Db::getText(self::SETTINGS_TABLE), 'value')
			),
			'types'	=>	array(
				Db::getText(self::USER_TABLE)		=> "varchar(32) NOT NULL",
				'nickname'							=> "varchar(60) NOT NULL",
				'pass'								=> "varchar(256) NOT NULL",
				'cookie'							=> "varchar(255)",
				Db::getText(Thought::THOUGHT_TABLE)	=> "longtext",
				'created'							=> "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP",
				Db::getText(self::SETTINGS_TABLE)	=> "varchar(20) NOT NULL",
				'value'								=> "varchar(20) NOT NULL"
			),
			'constraints' => array(
				self::USER_TABLE	=> "UNIQUE KEY `unique_username` (`".Db::getText(self::USER_TABLE)."`)"
			),
			'cascading_delete' => array(
				self::USER_TABLE	=> array(self::SETTINGS_TABLE, Thought::THOUGHT_TABLE)
			)
		);
	}
	
	/* Thoughts */
	
	public function getThought($iThoughtId, $sFormat=self::OBJ)
	{
		$oThought = new Thought($this->oDb, $this->oAuth->getUserId());
		
		if($iThoughtId=='last') $oThought->openLast(self::LAST_THOUGHT_LIMIT);
		else $oThought->open($iThoughtId);
		
		switch($sFormat)
		{
			case self::OBJ:
				return $oThought; break;
			case self::ARRAY:
				return $oThought->get(); break;
			case self::JSON:
				return self::getJsonResult(true, '', $oThought->get()); break;
		}
	}

	public function updateThought($asOps, $iThoughtId=0)
	{
		$oThought = new Thought($this->oDb, $this->oAuth->getUserId(), $iThoughtId);
		
		$oThought->setOps($asOps);
		$iThoughtId = $oThought->save();
		
		$bSuccess = ($iThoughtId>0);
		$sDesc = 'thought '.($bSuccess?'':'not ').'saved';
		return self::getJsonResult($bSuccess, $sDesc, $this->getThought($iThoughtId, self::ARRAY));
	}
	
	public function getThoughtDates()
	{
		$asThoughts = Thought::getThoughtDates($this->oDb, $this->oAuth->getUserId());
		foreach($asThoughts as &$asThought) $asThought['created_f'] = self::formatDate($asThought['created'], 'j M');
		return self::getJsonResult(true, '', $asThoughts);
	}
	
	/* Static toolbox functions */

	public static function getSafeNickName($sNickName)
	{
		return $sNickName;
	}
	
	private static function formatDate($iTime, $sFormat, $sField='')
	{
		$iTime = ($sField == '')?$iTime:$iTime[$sField];
		$iTime = is_numeric($iTime)?$iTime:strtotime($iTime);
		return date($sFormat, $iTime);
	}
}

?>