<?php

include_once('Database.php');
include_once('Application.php');

class System extends Application
{
  var $Database;
  var $Config;
  var $ModuleManager;
  var $PathItems;
  var $Menu;
  var $DoNotShowPage;
  
  function __construct()
  {
    $this->Config = array();
    $this->Menu = array();
    $this->RSSChannels = array();
    $this->DoNotShowPage = false;
  }
  
  function Init()
  {
  	global $Config;
  	    
    $this->Config = $Config;
    $this->Database = new Database();
    $this->Database->Connect($this->Config['Database']['Host'],
      $this->Config['Database']['User'], $this->Config['Database']['Password'],
      $this->Config['Database']['Database']);
    $this->Database->charset($this->Config['Database']['Charset']);
    $this->Database->ShowSQLQuery = $this->Config['Web']['ShowSQLQuery'];
    $this->Database->ShowSQLError = $this->Config['Web']['ShowSQLError'];
    $this->Database->LogSQLQuery = $this->Config['Web']['LogSQLQuery'];
    $this->ModuleManager = new AppModuleManager();

    $this->Menu = array
    (    		
    		array(
    				'Title' => 'Stav dokončení',
    				'Hint' => 'Stav dokončení překládů',
    				'Link' => $this->Link('/statistic.php'),
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),
    		array(
    				'Title' => 'Soubory',
    				'Hint' => 'Stahování různých pomocných souborů a programů',
    				'Link' => $this->Link('/download.php'),
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),
    		array(
    				'Title' => 'Pokyny',
    				'Hint' => 'Informace k překladu hry',
    				'Link' => $this->Link('/info.php'),
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),
    		array(
    				'Title' => 'Zdroje dat',
    				'Hint' => 'Informace o překladových skupinách',
    				'Link' => $this->Link('/TranslationList.php?action=grouplist'),
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),
    		array(
    				'Title' => 'Prezentace',
    				'Hint' => 'Prezentace a motivace překladu',
    				'Link' => $this->Link('/promotion.php'),
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),    		
    		array(
    				'Title' => 'IRC chat',
    				'Hint' => 'IRC chat pro překladatele',
    				'Link' => 'http://embed.mibbit.com/?server=game.zdechov.net%3A6667&amp;channel=%23wowpreklad&amp;forcePrompt=true&amp;charset=utf-8',
    				'Permission' => LICENCE_ANONYMOUS,
    				'Icon' => '',
    		),
    		array(
    				'Title' => 'Správa',
    				'Hint' => 'Volby pro správu',
    				'Link' => $this->Link('/admin/'),
    				'Permission' => LICENCE_ADMIN,
    				'Icon' => '',
    		),
    );    
  }
  
  function Run()
  {
    global $System, $ScriptStartTime, $TranslationTree, $User, $StopAfterUpdateManager,
	    $UpdateManager, $Config, $DatabaseRevision;

    $ScriptStartTime = GetMicrotime();

    if(isset($_SERVER['REMOTE_ADDR'])) session_start();

    if(!isset($Config)) die('Systém není nainstalován. Pokračujte v instalaci <a href="admin/install.php">zde</a>.');
    date_default_timezone_set($Config['Web']['Timezone']);
  
    $this->Init();

    // Check database persistence structure
    $UpdateManager = new UpdateManager();
    $UpdateManager->Database = $this->Database;
    $UpdateManager->Revision = $DatabaseRevision;
    if(!$UpdateManager->IsInstalled()) die('Systém vyžaduje instalaci databáze.');
    if(!$UpdateManager->IsUpToDate()) die('Systém vyžaduje aktualizaci databáze.');

    // SQL injection hack protection
    foreach($_POST as $Index => $Item)
    {
  	  if(is_array($_POST[$Index]))
  		  foreach($_POST[$Index] as $Index2 => $Item2) $_POST[$Index][$Index2] = addslashes($Item2);
    	else $_POST[$Index] = addslashes($_POST[$Index]);
    }
    foreach($_GET as $Index => $Item) $_GET[$Index] = addslashes($_GET[$Index]);
    
    // TODO: Global initialized variable should be removed
    $TranslationTree = GetTranslationTree();
  
    // Initialize application modules
    $this->ModuleManager->RegisterModule(new ModuleError($System));
    $this->ModuleManager->Modules['Error']->ShowError = $Config['Web']['ShowPHPError'];
    $this->ModuleManager->RegisterModule(new ModuleLog($System));
    $this->ModuleManager->RegisterModule(new ModuleUser($System));
    $this->ModuleManager->RegisterModule(new ModuleAoWoW($System));
    $this->ModuleManager->RegisterModule(new ModuleReferrer($System));
    $this->ModuleManager->Modules['Referrer']->Excluded[] = $System->Config['Web']['Host'];
    $this->ModuleManager->RegisterModule(new ModuleTeam($System));
    $this->ModuleManager->RegisterModule(new ModuleDictionary($System));
    $this->ModuleManager->RegisterModule(new ModuleTranslation($System));
    $this->ModuleManager->RegisterModule(new ModuleImport($System));
    $this->ModuleManager->RegisterModule(new ModuleExport($System));
    $this->ModuleManager->RegisterModule(new ModuleServer($System));
    $this->ModuleManager->RegisterModule(new ModuleClientVersion($System));
    $this->ModuleManager->RegisterModule(new ModuleShoutBox($System));
    $this->ModuleManager->RegisterModule(new ModuleNews($System));
    $this->ModuleManager->RegisterModule(new ModuleWiki($System));
    $this->ModuleManager->RegisterModule(new ModuleSearch($System));
    $this->ModuleManager->RegisterModule(new ModuleFrontPage($System));
    $this->ModuleManager->StartAll();
    
    $this->BaseView = new BaseView($this); 
    if($this->DoNotShowPage == false)
    {
      $this->PathItems = ProcessURL();
  	  $this->ShowPage();
    }  	 
  }
  
  function GetMicrotime()
  {
    list($Usec, $Sec) = explode(' ', microtime());
    return ((float)$Usec + (float)$Sec);
  }
  
  function Link($Target)
  {
    return($this->Config['Web']['BaseURL'].$Target);
  } 
  
  function RegisterPage($Path, $Handler)
  {
  	if(is_array($Path))
    {
      $Page = &$this->Pages;
      $LastKey = array_pop($Path);
      foreach($Path as $PathItem)
      {
        $Page = &$Page[$PathItem];       
      }
      if(!is_array($Page)) $Page = array('' => $Page);
      $Page[$LastKey] = $Handler;
    } else $this->Pages[$Path] = $Handler;
  }
  
  function RegisterMenuItem($MenuItem, $Pos = NULL)
  {
  	if(is_null($Pos)) $this->Menu[] = $MenuItem;
  	  else {
  	  	array_splice($this->Menu, $Pos, 0, array($MenuItem));
  	  }
  }
  
  function SearchPage($PathItems, $Pages)
  {
    if(count($PathItems) > 0) $PathItem = $PathItems[0];
      else $PathItem = '';
    if(array_key_exists($PathItem, $Pages))
    {
      if(is_array($Pages[$PathItem])) 
      {
        array_shift($PathItems);
        return($this->SearchPage($PathItems, $Pages[$PathItem]));
      } else return($Pages[$PathItem]);
    } else return('');
  }
  
  function PageNotFound()
  {
    return('Page '.implode('/', $this->PathItems).' not found.');
  }
  
  function ShowPage()
  {
    /* @var $Page Page */
    $ClassName = $this->SearchPage($this->PathItems, $this->Pages);     
    if($ClassName != '') 
    {
      $Page = new $ClassName($this);
      $Output = $Page->GetOutput();
      if($Page->RawPage == false) $Output = $this->BaseView->ShowPage($Output);
      echo($Output);
    } else echo($this->PageNotFound());
  }
} 

class BaseView extends View
{
	function ShowTopBar()
	{
		$Output = '<div class="Menu">';
		if(!$this->System->User->Licence(LICENCE_USER))
			$Output .= '<div class="advert">'.$this->System->Config['Web']['Advertisement'].'</div>';
		$Output .= '<span class="MenuItem"></span>';
		if($this->System->User->Licence(LICENCE_USER))
		{
			//$DbResult = $System->Database->query('SELECT `Id`, `Name` FROM `Team` WHERE `Id`='.$this->System->User->Team);
			//$Team = $DbResult->fetch_assoc();
			//$Output .= ''<span class="MenuItem">Moje překlady: <a href="">Dokončené</a> <a href="">Rozpracované</a> <a href="">Exporty</a> Tým: <a href="">'.$Team['name'].'</a></span>';
			$Output .= '<span class="MenuItem2">'.$this->System->User->Name.' <a href="'.$this->System->Link('/?action=logout').'">Odhlášení</a>'.
					' <a href="'.$this->System->Link('/user.php?user='.$this->System->User->Id).'">Moje stránka</a>'.
					' <a href="'.$this->System->Link('/Options.php').'">Nastavení</a>'.
					' <a title="Vámi přeložené texty" href="'.$this->System->Link('/TranslationList.php?user='.
					$this->System->User->Id.'&amp;group=0&amp;state=2&amp;text=&amp;entry=').'">Přeložené</a>'.
					' <a title="Vaše rozpracované text" href="'.$this->System->Link('/TranslationList.php?user='.
					$this->System->User->Id.'&amp;group=0&amp;state=3&amp;text=&amp;entry=').'">Rozpracované</a>'.
					' <a title="Nikým nepřeložené texty" href="'.$this->System->Link('/TranslationList.php?user=0&amp;group=0&amp;state=1&amp;text=&amp;entry=').'">Nepřeložené</a>'.
					'</span>';
		} else
		{
			$Output .= '<span class="MenuItem2"><form action="'.$this->System->Link('/?action=login').'" method="post"> '.
					'Jméno: <input type="text" name="LoginUser" size="8 " /> '.
					'Heslo: <td><input type="password" name="LoginPass" size="8" /> '.
					'<input type="submit" value="Přihlásit" /></form> &nbsp; '.
					'<a href="'.$this->System->Link('/registrace.php').'">Registrace</a></span>';
		}
		$Output .= '</div>';
		return($Output);
	}
	
	function ShowLoginBox()
	{
		$Output = '';
		if($this->System->User->Licence(LICENCE_USER))
		{
			// $Output .= 'Jste přihlášen jako: <b>'.$tUser->Id.'</b> <a href="index.php?Logout">Odhlásit</a>';
		} else
		{
			$Output .= '<strong>Přihlášení:</strong>
			<form action="" method="post">
			<table>
			<tr>
			<td><input type="text" name="LoginUser" size="13" /></td>
			</tr>
			<tr>
			<td><input type="password" name="LoginPass" size="13" /></td>
			</tr>
			<tr>
			<th><input type="submit" value="Přihlásit" /></th>
			</tr>
			</table>
			</form>';
		}
		return($Output);
	}
	
	function ShowSearchBox()
	{
		$Output = '<strong>Hledání:</strong>'.
				'<form action="'.$this->System->Link('/search/').'" method="get"><div>'.			
				'<table>'.
				'<tr>'.
				'<td><input type="text" name="text" size="13" /></td>'.
				'</tr>'.
				'<tr>'.
				'<th><input type="submit" value="Hledat" /></th>'.
				'</tr>'.
				'</table></div>'.
				'</form>';
		return($Output);
	}
	
	function ShowMainMenu()
	{
		$Output = '<strong>Nabídka:</strong>'.
				'<div class="verticalmenu"><ul>';
		foreach($this->System->Menu as $MenuItem)
			if($this->System->User->Licence($MenuItem['Permission']))
			{
				if(isset($MenuItem['Click'])) $OnClick = ' onclick="'.$MenuItem['Click'].'"';
				else $OnClick = '';
				if($MenuItem['Icon'] != '') $Icon = '<img src="'.$this->System->Link('/images/menu/'.$MenuItem['Icon']).'"/>';
				else $Icon = '';
				$Output .= '<li>'.$Icon.'<a class="verticalmenua" title="'.$MenuItem['Hint'].'" href="'.
					$MenuItem['Link'].'"'.$OnClick.'>'.$MenuItem['Title'].'</a></li>';
			}
			$Output .= '</ul></div>';
			return($Output);
	}
	
	function ShowTranslatedMenu()
	{
		global $TranslationTree;
	
		$Output = '<strong>Překladové skupiny:</strong><br /><div id="TranslationMenu">';
		$DbResult = $this->System->Database->select('Group', '`Id`, `Name`', '1 ORDER BY `Name`');
		while($Group = $DbResult->fetch_assoc())
		{
			$Output .= '<div id="menuitem-group'.$Group['Id'].'" onmouseover="show(\'group'.$Group['Id'].'\')" onmouseout="hide(\'group'.$Group['Id'].'\')">'.
					'<a href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;action=filter').'">'.$Group['Name'].'</a></div>'.
					'<div id="group'.$Group['Id'].'" class="hidden-menu-item" onmouseover="show(\'group'.$Group['Id'].'\')" onmouseout="hide(\'group'.$Group['Id'].'\')">';
			$Output .= '&nbsp;<a title="Zde můžete začít překládat" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=1&amp;user=0&amp;entry=&amp;text=').'">Nepřeložené</a><br />'.
					'&nbsp;<a title="Přeložené texty, můžete zde hlasovat, nebo opravovat překlady" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=2&amp;user=0&amp;entry=&amp;text=').'">Přeložené</a><br />';
			if($this->System->User->Licence(LICENCE_USER))
			{
				$Output .= '&nbsp;<a title="Nedokončené překlady" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=3').'">Rozepsané</a><br />
				&nbsp;<a title="Všechny překlady, které jste přeložil" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;state=1&amp;user='.$this->System->User->Id).'&amp;entry=&amp;text=">Vlastní</a><br />';
			}
			$Output .= '&nbsp;<a title="Sestavit speciální filtr" href="'.$this->System->Link('/TranslationList.php?group='.$Group['Id'].'&amp;action=filter').'">Filtr</a><br />';
			$Output .= '</div>';
		}
		$Output .= '</div>';
		return($Output);
	}
	
	function ShowHeader()
	{
		$Output = '<?xml version="1.0" encoding="'.$this->System->Config['Web']['Charset'].'"?>'.
		'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'.
		'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cz">'.
		'<head>'.
		'<meta http-equiv="content-type" content="application/xhtml+xml; charset='.$this->System->Config['Web']['Charset'].'" />'.
		'<meta name="keywords" content="wow, quest, questy, questů, preklad, mangos, překlad, překládání, přeložený, přeložení, čeština, world of warcraft, open source, free, addon" />'.
		'<meta name="description" content="'.$this->System->Config['Web']['Title'].'" />'.
		'<meta name="robots" content="all" />'.
		'<link rel="stylesheet" href="'.$this->System->Link('/style/style.css').'" type="text/css" media="all" />'.
		'<script type="text/javascript" src="'.$this->System->Link('/style/global.js').'"></script>'.
		'<link rel="shortcut icon" href="'.$this->System->Link('/images/favicon.ico').'" />';
		$Output .= $this->System->ModuleManager->Modules['News']->ShowRSSHeader();
		$Output .= '<title>'.$this->System->Config['Web']['Title'].'</title>'.
		'</head><body>';
	
		$Output .= $this->ShowTopBar();
		$Output .= '<table class="page"><tr><td class="menu">';
		$Output .= $this->ShowMainMenu();
		$Output .= $this->System->ModuleManager->Modules['User']->ShowOnlineList();
		$Output .= '<br />';
		$Output .= $this->ShowSearchBox();
		$Output .= '</td><td id="border-left"></td><td class="content">';
		return($Output);
	}
	
	function ShowFooter()
	{
		global $ScriptStartTime, $Revision, $ReleaseTime;
	
		$ScriptGenerateDuration = round(GetMicrotime() - $ScriptStartTime, 2);
	
		$Output = '</td>'.
      '<td class="menu2">';
		$Output .= $this->ShowTranslatedMenu();
		$Output .= '</td>'.
      '</tr><tr>'.
      '<td colspan="4" class="page-bottom">Verze: '.$Revision.' ('.HumanDate($ReleaseTime).')'.
      ' &nbsp; <a href="http://svn.zdechov.net/trac/wowpreklad/browser/trunk">Zdrojové soubory</a> &nbsp; '.
      '<a href="http://svn.zdechov.net/trac/wowpreklad/log/trunk?verbose=on">Novinky</a> &nbsp; '.
      $this->System->Config['Web']['WebCounter'];
	
		$Output .= '</td></tr>';
		if($this->System->Config['Web']['ShowRuntimeInfo'] == true)
			$Output .= '<tr><td colspan="3" style="text-align: center;">Doba generování: '.
		$ScriptGenerateDuration.' s / '.ini_get('max_execution_time').' s &nbsp;&nbsp; Použitá paměť: '.
		HumanSize(memory_get_peak_usage(FALSE)).' / '.ini_get('memory_limit').'B &nbsp;&nbsp; <a href="http://validator.w3.org/check?uri='.
		htmlentities('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'?'.$_SERVER['QUERY_STRING']).'">HTML validator</a></td></tr>';
		$Output .= '</table>'.
      '</body>'.
      '</html>';
		$this->System->User->Store();
		return($Output);
	}
	
	function ShowPage($Content)
	{
		$Output = $this->ShowHeader().$Content.$this->ShowFooter();
		//if($this->System->Config['Web']['FormatOutput']) $Output = $this->FormatOutput($Output);
		return($Output);
	}
	
	function FormatOutput($s)
	{
		$out = '';
		$nn = 0;
		$n = 0;
		while($s != '')
		{
			$start = strpos($s, '<');
			$end = strpos($s, '>');
			if($start != 0)
			{
				$end = $start - 1;
				$start = 0;
			}
			$line = trim(substr($s, $start, $end + 1));
			if(strlen($line) > 0)
				if($line[0] == '<')
				{
					if($s[$start + 1] == '/')
					{
						$n = $n - 2;
						$nn = $n;
					} else
					{
						if(strpos($line, ' ')) $cmd = substr($line, 1, strpos($line, ' ') - 1);
						else $cmd = substr($line, 1, strlen($line) - 2);
						//echo('['.$cmd.']');
						if(strpos($s, '</'.$cmd.'>')) $n = $n + 2;
					}
				}// else $line = '['.$line.']';
				//if($line != '') echo(htmlspecialchars(str_repeat(' ',$nn).$line."\n"));
				if($line != '') $out .= (str_repeat(' ', $nn).$line."\n");
				$s = substr($s, $end + 1, strlen($s));
				$nn = $n;
		}
		return($out);
	}	
}
