<?php
	class cTestPage extends cStudentPage
	{
		
		protected $action; 
		protected $testTemplateId;
		protected $answerSetId;
		protected $testId;
		protected $testAnswerId;
		protected $qIndex;
		protected $timeOut;
		protected $unauthorizedAccess;
    
		function PrepareParams()
		{
			// nacitaj potrebne parametre

			$this->qIndex = (isset($this->getParams["qId"]) && $this->getParams["qId"]<>'')?$this->getParams["qId"]:1; // ak nie je nastaveny index otazky, zober prvu otazku
      $this->testId = $_SESSION['testId'];
			
      // zisti answerSetId na zaklade indexu otazky

			$query = "SELECT A.id_answerSet AS idAS, TA.id AS idTA
								FROM tTestAnswer AS TA
								INNER JOIN tTestAnswerToAnswer AS TAT ON TAT.id_testAnswer = TA.id
								INNER JOIN tAnswer AS A ON A.id = TAT.id_answer
								WHERE TA.index='".$this->qIndex."' AND TA.id_test='".$this->testId."';";
			$data = $this->db->QueryToRow($query);

			if ($data!==0) 
			{
				$this->answerSetId = $data['idAS'];
				$this->testAnswerId = $data['idTA'];
			}
			else 
			{
				return false; //otazka s danym indexom sa nenasla...
			}

		}
		
		function Process()
    {
			$this->unauthorizedAccess = false;

      if ( !$this->bLoggedIn ) 
			{
        return true;
      }    

	    // ako parameter dostavam examId
			$this->examId = $this->getParams["examId"];
			
			$this->action = $this->getParams["action"];
			
			// zisti ci ma prihlaseny uzivatel pravo spustit tento test
			$query = "SELECT *
								FROM tExamToUser AS tETU
								WHERE tETU.id_user='".$this->userId."' AND tETU.id_exam='".$this->examId."';";
			$data = $this->db->QueryToRow($query);
			if ($data === 0)
			{
				$this->unauthorizedAccess = true;
				return true;
			}

			// zisti ci nevyprsal cas
			$query = "SELECT totalTime - ".time()." AS time
								FROM tTest
								WHERE id='".(isset($_SESSION['testId'])?$_SESSION['testId']:0)."';";
			$data = $this->db->QueryToRow($query);
			if ($data !== 0 && $data['time'] <= 0)
			{
				$this->timeOut=true;
				return true;
			} 
			else
			{
				$this->timeOut=false;
			}

			// kontrola ci sa nejedna o neopravneny vstup (ak nie je nastavena testOpen to znamena ze je test prave spusteny, alebo pokus o neautorizovany pristup po unlocku)
			if (!isset($_SESSION["testOpen"]) && $this->action !== 'startTest' && $this->action !== 'unlockTest')
			{
				$this->action = 'lockTest';
			}
			
			if ($this->action === 'startTest')

			{
				// zisti ci je test uz inicializovany (existuje zaznam v tTest s prislusnym examId a userId, ale bez vyplnenej znamky, teda ze nebol ete ohodnoteny a prebieha...)
	      $query = "SELECT id, id_testTemplate
									FROM tTest
									WHERE id_user='".$this->userId."' AND id_exam='".$this->examId."';";
				$data = $this->db->QueryToRow($query);
	      if ($data===0) // zaznam v tTest neexistuje
	      {
					// zvol nahodne zodpovedajuci test template
		      $query = "SELECT tTT.id
										FROM tTestTemplate AS tTT
										INNER JOIN tExam AS tE ON tTT.id_course = tE.id_course 
										WHERE tTT.printed <> 1 AND tTT.obsolete <> 1 AND tE.id='".$this->examId."'
										ORDER BY RAND()
										LIMIT 1;";
					$data = $this->db->QueryToRow($query);
		      if ($data===0) return false; // nie su ziadne pripravene testy
					$this->testTemplateId=$data['id'];
					// zistit kolko ma test trvat
					$query = "SELECT duration
										FROM tCourse AS tC
										INNER JOIN tTestTemplate AS tTT ON tTT.id_course = tC.id
										WHERE tTT.id = '".$this->testTemplateId."';";
					$duration = $this->db->QueryToRow($query);
					// vytvor zaznam v tTest
					$query = "INSERT INTO tTest (id_user,id_testTemplate,id_exam,comment,totalTime) VALUES ('".$this->userId."','".$this->testTemplateId."','".$this->examId."','','".(time()+(60*$duration['duration']))."');";
					$result = $this->db->Query($query);
		      $this->testId = $this->db->InsertId();
		      if ($result===0) return false; 
					
		      //zobrat vsetky otazky a pripravit poradie (pridat zaznamy do tTestAnswer)
					$query = "SELECT tAS.id
										FROM tQuestion AS tQ
										INNER JOIN tAnswerSet AS tAS ON tAS.id_question = tQ.id
										INNER JOIN tTestItems AS tTI ON tTI.id_answerSet = tAS.id
										INNER JOIN tTestTemplate AS tTT ON tTT.id = tTI.id_testTemplate
										INNER JOIN tTest AS tT ON tT.id_testTemplate = tTT.id
										WHERE tT.id='".$this->testId."';";
			    $questions = $this->db->QueryToArray($query);
			    shuffle($questions);
			    $i = 1;
			    foreach ($questions as $q)
			    {
			      $query = "INSERT INTO tTestAnswer (id_test,comment,totalTime,tTestAnswer.index) VALUES ('".$this->testId."','','0','".$i++."');";
						$result = $this->db->Query($query);
			      $tTestAnswerId = $this->db->InsertId();
			      //zobrat vsetky odpovede pre tuto otazku a pripravit poradie (pridat zaznamy do tTestAnswerToAnswer)
						$query = "SELECT tA.id
											FROM tAnswer AS tA
											WHERE tA.id_answerSet='".$q['id']."';";
				    $answers = $this->db->QueryToArray($query);
			    	shuffle($answers);
				    $j = 1;
						foreach ($answers as $a)
				    {
				      $query = "INSERT INTO tTestAnswerToAnswer (id_testAnswer,id_answer,value,tTestAnswerToAnswer.index) VALUES ('$tTestAnswerId','".$a['id']."','0','".$j++."');";
							$result = $this->db->Query($query);
				    } // foreach ($answers as $a)
			    } // foreach ($questions as $q)
		      // priprave tabulku na timestampove pingy
					$query = "INSERT INTO tTimeStamps (id_test,id_user,timeStamp) VALUES ('".$this->testId."','".$this->userId."','".time()."');";
					$result = $this->db->Query($query);
		      // zapamataj si info o tom, ze test bol uz nastartovany
		      $_SESSION["testOpen"] = 1;
	      } // if ($data===0)
	      else
	      {
	      	// test bol uz spusteny, pravdepodobne spadol system, predpokladame pripravene vsetky potrebne tabulky (tTest,tTestAnswer,tTestAnswerToAnswer)
	      	// todo: naplnit hodnoty z temporary tabulky s pingami a timestampami a zistit cas vypadku...
	      	$this->testId = $data['id'];
	      	// kontrola ci je pristup opravneny (ak nie je nastavena testOpen, tak ide o neautorizovany pristup po unlocku...)
					if (!isset($_SESSION["testOpen"]))
					{
						$this->action = 'lockTest';
					}
	      } // else
	      
	      $_SESSION['testId'] = $this->testId;
	      $this->PrepareParams();
	    }

			elseif ($this->action === 'saveAnswer')

			{
	      $this->PrepareParams();
	      // poznam $this->testAnswerId
				// spracovanie odpovedi...
				$query = "UPDATE tTestAnswer SET comment='".$this->postParams["poznamka"]."' WHERE id='".$this->testAnswerId."';";
				$result = $this->db->Query($query);
				$odpovede = $this->postParams["odpoved"];
				// vymaz stare hodnoty
				$query = "UPDATE tTestAnswerToAnswer SET value='0' WHERE id_testAnswer='".$this->testAnswerId."';";
				$result = $this->db->Query($query);
				// prejdi vsetky odpovede a zaznac do DB
				if (is_array($odpovede))
				{
					foreach ($odpovede as $odpoved)
					{
						$index = array("A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5, "F" => 6, "G" => 7, "H" => 8, "I" => 9, "J" => 10);
						$query = "UPDATE tTestAnswerToAnswer SET value='1' WHERE id_testAnswer='".$this->testAnswerId."' AND tTestAnswerToAnswer.index='".$index[$odpoved]."';";
						$result = $this->db->Query($query);
					}
				}
			}

			elseif ($this->action === 'lockTest')

			{
				$this->qIndex = (isset($this->getParams["qId"]) && $this->getParams["qId"]<>'')?$this->getParams["qId"]:1; // ak nie je nastaveny index otazky, zober prvu otazku				
        unset($_SESSION["testOpen"]);
			}

			elseif ($this->action === 'unlockTest')

			{
        $login=$this->postParams["login"];
        $password=$this->postParams["password"];
        $query = "SELECT U.id, U.name, U.surname 
									FROM tUser AS U, tStudents AS S 
									WHERE U.id = '".$this->userId."' AND
												U.id = S.id AND 
												U.login='".$this->postParams["login"]."' AND 
												U.password=MD5(CONCAT(U.passPrefix,'".$this->postParams["password"]."'));";
				$result = $this->db->QueryToRow($query);
        if ( $result != 0 )                                         
        {
          $_SESSION["testOpen"] = 1;
          $this->action = 'showTest';
          $this->PrepareParams();
        }
        else
        {
          $this->smarty->assign('badLogin',true);
        }
			}

			elseif ($this->action === 'markAsUnread')

			{
      	$this->PrepareParams();
	      $query = "UPDATE tTestAnswer SET answerMark = 'unread' WHERE id = '".$this->testAnswerId."';";
				$result = $this->db->Query($query);
			}

			elseif ($this->action === 'markAsAnswered')

			{
      	$this->PrepareParams();
	      $query = "UPDATE tTestAnswer SET answerMark = 'answered' WHERE id = '".$this->testAnswerId."';";
				$result = $this->db->Query($query);
			}

			elseif ($this->action === 'markAsUndone')

			{
      	$this->PrepareParams();
	      $query = "UPDATE tTestAnswer SET answerMark = 'undone' WHERE id = '".$this->testAnswerId."';";
				$result = $this->db->Query($query);
			}

			elseif ($this->action === 'markAsUnknown')

			{
      	$this->PrepareParams();
	      $query = "UPDATE tTestAnswer SET answerMark = 'unknown' WHERE id = '".$this->testAnswerId."';";
				$result = $this->db->Query($query);
			}

			elseif ($this->action === 'markAsElse')

			{
      	$this->PrepareParams();
	      $query = "UPDATE tTestAnswer SET answerMark = 'else' WHERE id = '".$this->testAnswerId."';";
				$result = $this->db->Query($query);   
			}

			else

			{
      	$this->PrepareParams();
			}
			
			// v pripade ze su poslane nasledujuce parametre, tak ich spracuj (pocitanie casu straveneho nad otazkou)
			if (isset($this->getParams["oldQId"]) && isset($this->getParams["time"]))
			{
				$qid = $this->getParams["oldQId"];
				$timeDif = time() - (is_numeric($this->getParams["time"])?$this->getParams["time"]:time());
	      $query = "UPDATE tTestAnswer SET totalTime = totalTime + $timeDif WHERE id_test = '".$this->testId."' AND tTestAnswer.index = '$qid';";
				$result = $this->db->Query($query);   
			}
						

      return true;
    }
    
    function Draw()
    {
      if ( !$this->bLoggedIn )
      {
        $this->smarty->display("login.tpl");
      }
      elseif ($this->unauthorizedAccess)
      {
        $this->smarty->display("accessDenied.tpl");
      }
      elseif ($this->timeOut)
      {
				$this->smarty->assign('timeOut','1');
				$this->testId = (isset($_SESSION['testId']))?$_SESSION['testId']:0;
				$this->smarty->assign('testId',$this->testId);
  			$this->qIndex = (isset($this->getParams["qId"]) && $this->getParams["qId"]<>'')?$this->getParams["qId"]:1; // ak nie je nastaveny index otazky, zober prvu otazku
				$this->smarty->assign('qIndex',$this->qIndex);
				$this->smarty->assign('timeStamp',time());
				// naplnit hodnotu userIsic 
	      $query = "SELECT ISIC
									FROM tUser
									WHERE id='".$this->userId."';";
	      $data = $this->db->QueryToRow($query);
				$this->smarty->assign('userIsic',$data['ISIC']);
				$this->smarty->assign("userFullName",$_SESSION["userFullName"]);
				$this->smarty->display("test.tpl");
	      // znic sessiony ohladom testovania
	      if (isset($_SESSION['testId']))
	      {
	      	unset($_SESSION['testId']);
	      }
	      if (isset($_SESSION['testOpen']))
	      {
	      	unset($_SESSION['testOpen']);
	      }	      
      }
      else
      {
				$this->smarty->assign('timeOut','0');
				$this->testId = (isset($_SESSION['testId']))?$_SESSION['testId']:0;
				$this->smarty->assign('userId',$this->userId);
				$this->smarty->assign('testId',$this->testId);
				$this->smarty->assign('examId',$this->examId);
				// naplnit hodnotu userIsic 
	      $query = "SELECT ISIC
									FROM tUser
									WHERE id='".$this->userId."';";
	      $data = $this->db->QueryToRow($query);
				$this->smarty->assign('userIsic',$data['ISIC']);

				// naplnit hodnotu totalTime
	      $query = "SELECT totalTime
									FROM tTest
									WHERE id='".$this->testId."';";
	      $data = $this->db->QueryToRow($query);
				$this->smarty->assign('totalTime',(is_numeric($data['totalTime'])?$data['totalTime']:time()) - time());
				$this->smarty->assign('timeStamp',time());

	    	if (($this->action === 'lockTest') || ($this->action === 'unlockTest'))
	    	{                     
					$urlParams = "?site=test&amp;action=unlockTest&amp;examId=".$this->examId."&amp;qId=".$this->qIndex;
					$this->smarty->assign('urlParams',$urlParams);
					$this->smarty->assign('userIsic',$data['ISIC']);
					$this->smarty->assign("userFullName",$_SESSION["userFullName"]);
					$this->smarty->display("lockTest.tpl");
				}
				else
	    	{
					// naplnit questions hodnotami qMark, qIndex (poradie otazky), question (znenie otazky)
		      $query = "SELECT DISTINCT TA.index AS qIndex, Q.question, TA.answerMark AS qMark
										FROM tTest AS T
										INNER JOIN tTestTemplate AS TT ON T.id_testTemplate = TT.id
										INNER JOIN tTestItems AS TI ON TI.id_testTemplate = TT.id
										INNER JOIN tAnswerSet AS tAS ON tAS.id = TI.id_answerSet
										INNER JOIN tQuestion AS Q ON tAS.id_question = Q.id
										INNER JOIN tAnswer AS A ON A.id_answerSet = tAS.id
										INNER JOIN tTestAnswerToAnswer AS TAT ON TAT.id_answer = A.id
										INNER JOIN tTestAnswer AS TA ON (TA.id = TAT.id_testAnswer AND TA.id_test = T.id)
										WHERE T.id='".$this->testId."'
										ORDER BY qIndex;";
					$data = $this->db->QueryToArray($query);
					$questionCount = count($data);
		      if ( $questionCount > 0 )
		      {
						$qIndexNext = ($this->qIndex + 1) % $questionCount;
						$qIndexNext = ($qIndexNext==0)?$questionCount:$qIndexNext;
						$qIndexPrev = ($this->qIndex + $questionCount - 1) % $questionCount;
						$qIndexPrev = ($qIndexPrev==0)?$questionCount:$qIndexPrev;
		        $this->smarty->assign('questionCount', $questionCount);
		        $this->smarty->assign('qIndex', $this->qIndex);
		        $this->smarty->assign('qIndexNext', $qIndexNext);
		        $this->smarty->assign('qIndexPrev', $qIndexPrev);
		        $this->smarty->assign('questions', $data);
		      }
		      else
		      {
						$qIndexNext = 0;
						$qIndexPrev = 0;
		        $this->smarty->assign('questionCount', $questionCount);
		        $this->smarty->assign('qIndex', $this->qIndex);
		        $this->smarty->assign('qIndexNext', $qIndexNext);
		        $this->smarty->assign('qIndexPrev', $qIndexPrev);
						$this->smarty->assign('questions', array());
		      } 
	
					// naplnit answers hodnotami aChecked, answer (znenie), aIndex (oznacenie poradia)
		      $query = "SELECT A.text AS answer, TAT.value AS aChecked, TAT.index AS aIndex
										FROM tAnswer AS A
										INNER JOIN tAnswerSet AS tAS ON A.id_answerSet = tAS.id
										INNER JOIN tQuestion AS Q ON Q.id = tAS.id_question
										INNER JOIN tTestAnswerToAnswer AS TAT ON TAT.id_answer = A.id
										WHERE tAS.id = '".$this->answerSetId."' AND TAT.id_testAnswer = '".$this->testAnswerId."'
										ORDER BY aIndex;";
					$answers = $this->db->QueryToArray($query);
		      if ( $answers !== 0 )
		      {
						$letters = array(1 => "A", 2 => "B", 3 => "C", 4 => "D", 5 => "E", 6 => "F", 7 => "G", 8 => "H", 9 => "I", 10 => "J");
						foreach ($answers as $k => $a)
						{
							$answers[$k]['aLetter'] = $letters[$a['aIndex']];
						}
						$this->smarty->assign('answers', $answers);
		      }
		      else
		      {
						$this->smarty->assign('answers', array());
		      }
		
					// naplnit question hodnotami question (znenie otazky), note (poznamka k otazke)
		      $query = "SELECT Q.question, TA.comment, TA.totalTime AS time
										FROM tQuestion AS Q 
										INNER JOIN tAnswerSet AS tAS ON tAS.id_question = Q.id
										INNER JOIN tAnswer AS A ON A.id_answerSet = tAS.id
										INNER JOIN tTestAnswerToAnswer AS TAT ON TAT.id_answer = A.id
										INNER JOIN tTestAnswer AS TA ON TAT.id_testAnswer = TA.id
										WHERE tAS.id = '".$this->answerSetId."' AND TA.id_test='".$this->testId."';";
		      $this->AssignQueryResult($query,'question','noarray');
		
					$this->smarty->assign("userFullName",$_SESSION["userFullName"]);
					$this->smarty->display("test.tpl");
				}
	    }
    }
	}
?>
