<?php
include_once("_dirinfo.php");
include_once(PATH_TO_ROOT."init.php");
include_once(PATH_TO_ROOT."webcati/init.php");
include_once(PATH_TO_ROOT."_support/class.db.php");
//include_once(PATH_TO_ROOT."_support/.php");
include_once(PATH_TO_ROOT.'_class/createQuestion/Question.php');
include_once(PATH_TO_ROOT."webcati/_class/class.errorReport.php");
include_once(PATH_TO_ROOT.'webcati/_class/class.Engine.php');
include_once(PATH_TO_ROOT.'webcati/_class/class.Display.php');
include_once(PATH_TO_ROOT.'webcati/_class/class.SurveySession.php');
include_once(PATH_TO_ROOT.'webcati/_class/class.CodeValiditor.php');
//razredi za različne tipe vprašanj
include_once(PATH_TO_ROOT.'_class/createQuestion/SingleResponse.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/SingleMultiResponse.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/MultiResponse.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/Scale.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/Open.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/SystemQuestion.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/Timestamp.php');
include_once(PATH_TO_ROOT.'_class/createQuestion/Instruction.php');
//uporabniške metode za skripte
include_once(PATH_TO_ROOT.'survey/usrs_methods.php');
include_once(PATH_TO_ROOT.'survey/users_methods_custom.php');

// we need this to get system constants from _config table in database
$dbConfig = configLoader::loadConfig('aufo_fill_questionnair');
define("MAX_FILTER_TRIES", intval($dbConfig['max_filter_tries']));
define("MAX_QUESTION_REPETE", intval($dbConfig['max_question_repete']));

//var_dump(MAX_FILTER_TRIES);

//session_start();
$tmpSession = $_SESSION;
//ini_set("display_errors", "1");
//session_write_close();


function saveAndExit($attrArray,$startTime, $errorReport,$projName, $flag_bad = 76)
{
	global $db;
	$tmpSql = array();
	$fieldsArray = array();
	$valuesArray = array();
	foreach($attrArray as $field => $value)
	     $tmpSql[] = $field . " = '" . $value . "'";

	$tmpSql[] = "user_id = -777";
	$tmpSql[] = "status = 1";
	$tmpSql[] = "status_rec = 1";
	$tmpSql[] = "flag_bad = " . $flag_bad;
	$tmpSql[] = "t_start =  " . $startTime;
	$tmpSql[] = "t_stop = " . time() ;
	var_dump($attrArray);
	if(count($attrArray) > 0)
	{
	    //zapis vprašalnika v tabelo ProjectName_structure
	    $db->ChangeDatabase(DB_WARPIT_WEBCATI_BASE);
	    $sql = "UPDATE " . $projName . "_structure SET " . implode(',', $tmpSql) . " WHERE id = " .$_SESSION['id_record'];
		//print $sql;

	    try {
	    	$db->SQLexecute($sql);
	    	//echo "{ success: true}";
	    }
	    catch(Exception $e) {
	    	$errorReport->addError("End of questioner","Can\'t update _structure table", array("SQL error"=> $e->getMessage()) );
	    	echo "\nNapaka pri zapisovanju v bazo.\n".$e->getMessage() . "<br/>";
	        echo $sql;
	    }
	}
	$errorReport->save();

}

/**
 * Z stringa odgovorov vrne array njihovih vrednosti
 *
 * @param $str string odgovorov
 * @return array vrednosti odgovorov vprašanj
 */

function getStringValues($str, $q = NULL) {

    //Section #1 Tanis 20151602
    /*This code was added becouse we have problem with html in answers, so now we  clean string before parsing */
    $str = str_replace("/","<*>",$str);
    $str = str_replace("<<*>","</",$str);
    $str = str_replace("<*>>","/>",$str);
    $str = str_replace("<*> ","/ ",$str);
    $str = str_replace("\n<*>","<*>",$str);
    $str = str_replace("<*>\n","<*>",$str);

    $str = explode('<*>',$str);
	//$str = explode("/", $str);
    //Section 1 END

	foreach ($str as $key => $val) {
		$tmp[] = explode(" ", $val,2);
		$vals[] = $tmp[$key][0];
	}

	return $vals;
}

/**
 * Funkcija vrne naključno izbrane ključe z podanega polja Te funkcije vbistvu ne potrebujem ker se nahaja v Question.. Nekega dne bom počistil to skripto in bo lepa skripta.. z goto stavkom..
 *
 * @param $array polje z akterega želimo pridobiti ključe
 * @param $num število željenih ključev
 * @return array naključno izbranih ključev
 */
function randomArrayKeys($array, $num) {
	$temp = array_rand($array, $num);

	if(is_array($temp)){
		return $temp;
	} else {
		$array = array();
		array_push($array, $temp);
		return $array;
	}
}

function isAllowed($q_name, $currentVal, $values, $valuesOrder)
{
	//najprej ugotovimo zaporedno številko fielda, ki ga polnimo
	$fieldNum = intval(str_replace($q_name . "_", "", $currentVal));
	//nato preverimo kateri value pripada trenutnemu fieldu
	$valueForField = $valuesOrder[$fieldNum];

	//preverimo, če smo ta field odstranili v answer filtru
	return in_array($valueForField, $values);
}

function prepareScriptForAutofill($script)
{
	//V normalni verziji teh funkcije se podatki berejo in pišejo direktno v bazo. Pri autofillerju, pa si pišemo vrednosti v polje in jih shranimo v bazo šele na koncu.
	//Zamenjati je potrebno vse uporabniške funkcije, ki delajo z bazo z prilagojenimi funkcijami
	$oldFunctionNames = array('getVar(','saveVar(', 'getVar (','saveVar (');
	$newFunctionNames = array('getVarAutoFill(','saveVarAutoFill(', 'getVarAutoFill(','saveVarAutoFill(');

	return str_replace($oldFunctionNames, $newFunctionNames, $script);
}

/**
 * Vrne random izbrane odgovore ali odgovor, odvisno od tipa vprašanja
 *
 * @param $db objekt za delo z podatkovno bazo
 * @param $values vrednosti odgovora
 * @param $attrArray polje atributov
 * @param $question array podatkov posameznega vprašanja
 * @param $e objekt razreda Engine
 * @param $allQuestionFields polje vseh atributov vprašanj, ločenih po njihovih id-jih (vsebuje samo single, multi in scale polja vprašanj)
 */
function selectRandomAnswer($db, $values, &$attrArray, $question, $e, &$allQuestionFields, $errorReport) {

    $repetCnt = 0;

	//Pripravimo si začasno variablo v katero shranimo vrstni red odgovorov, ker bomo s filtriranjem ta vrstni red izgubili
	$valuesOrder = array();
	$i = 1;
	foreach($values as $value)
	{
		$valuesOrder[$i] = $value;
		$i++;
	}

	//upoštevanje filtrov odgovorov
	if($question['filter_answer'] != ""){
		filterAnswers($e, $question['filter_answer'], $values, $attrArray);
	}


	$legend = getStringValues($question['leg_sql']);

	//upoštevanje filtrov legende
	if($question['filter_legend'] != ""){
		filterAnswers($e, $question['filter_legend'], $legend, $attrArray);
	}

	reselect:

    $q = Question::createQuestion($question['tip_sql'], $db, $question);
    $fields = $q->getStructureFields();

	switch ($question['tip_sql']) {
		//single response -------------------------------------------------------
		case 1:
            //die;
            //return;
			$allQuestionFields[$question['id']] = $fields;
			//upoštevanje 'attachAnswer' opcije
			if($question['attachAnswers'] > 0){
				removeAttachedAnswers($values, $fields, null, $$question, "single", $allQuestionFields, $attrArray);
			}


			$n = array_rand($values, 1);
			//če je označen odgovor z open odgovoru in ga je potrebno izpolniti
			if($values[$n] == $question['open_answers'] && $question['answers_filter'] == 0 and !is_null($values[$n])){
				/*$attrArray[] = $fields['o_0'];
				$valArray[] = "'sample single response text'";*/
			//	var_dump($question['open_answers']);
             //   var_dump($values[$n]);
				$attrArray[$fields['o_0']] = "sample single response text";

			}

            $v = strval($values[$n]);
			/*$attrArray[] = $fields[0];
			$valArray[] = $values[$n];*/

			$attrArray[$fields[0]] = $values[$n];

		//    $valArray[] = "656";
			break;
		//scale -----------------------------------------------------------------
		case 2:
		//	$scale = new Scale($db, $question);
			//$fields = $q->getStructureFields();
			//11.12.2014 Zakomentiral Tanis
			//$dropAttributes = getStringValues($question['atr_sql']);
			$allQuestionFields[$question['id']] = $fields;

			//upoštevanje 'attachAnswer' opcije
			if($question['attachAnswers'] > 0){
				removeAttachedAnswers($values, $fields, $legend, $question, "scale_multi", $allQuestionFields, $attrArray);
			}

           /* print "<pre>";
            var_dump($fields);
            print "#################################################################";

            print "</pre>";*/
			//najprej ven odstranimo vse open answer odgovore in jih shranimo v $openAnswers
			 $openAnsIds = explode(':', $question['open_answers']);

            //najprej ven odstranimo vse open answer odgovore in jih shranimo v $openAnswers
            $openAnswers = array();
            foreach($fields as $key => $val)
            {
                foreach($openAnsIds as $openId)
                {
                    if(strval($key) == 'o_'.$openId)
                    {
                        array_push($openAnswers, $fields[$key]);
                        unset($fields[$key]);
                    }
                }

            }

			/*$openAnswers = array();
			foreach($fields as $key => $val){
				if(strval($key) == 'o_5'){
					array_push($openAnswers, $fields[$key]);
					unset($fields[$key]);
				}
			}
			*/
			//scale z tipi prikaza: radio buttons, drop - down menu, slider
			if($question['les_sql'] == 1 OR $question['les_sql'] == 2 OR $question['les_sql'] == 7){
				//če ni potrebno odgovoriti na vse odgovore (MA unchecked)
				if($question['must_answer'] == 0){
					$st = rand(0, count($fields));
					if($st > 0){
						$randKeys = randomArrayKeys($fields, $st);
						foreach($randKeys as $val){
							$n = array_rand($legend, 1);

							if(isAllowed($question['q_name'], $fields[$val], $values, $valuesOrder))
								$attrArray[$fields[$val]] = $legend[$n];
						}
					}
				}
				//če je potrebno odgovoriti na vse odgovore (MA checked)

				else {

					foreach($fields as $key => $val){
						$n = array_rand($legend, 1);
						/*$attrArray[] = $val;
						$valArray[] = $legend[$n];*/
						//tukaj
						if(isAllowed($question['q_name'], $val, $values, $valuesOrder))
							$attrArray[$val] = $legend[$n];
							//$attrArray[$val[$v]] = $legend[$v];
						//if(in_array($val, $values))
					}
				}
			}

			//scale z tipu prikaza: inverted radio
			else if($question['les_sql'] == 5){
				$answerValues = getStringValues($question['odg_sql']);
				//če ni potrebno odgovoriti na vse odgovore (MA unchecked)
				if($question['must_answer'] == 0){
					$st = rand(0, count($fields));
					if($st > 0){
						$randKeys = randomArrayKeys($fields, $st);

						foreach($randKeys as $val){
							$n = array_rand($answerValues, 1);
							/*$attrArray[] = $fields[$val];
							$valArray[] = $answerValues[$n];*/
							$attrArray[$fields[$val]] = $answerValues[$n];
							unset($answerValues[$n]);
						}
					}
				}
				//če je potrebno odgovoriti na vse odgovore (MA checked)
				else {
					foreach($fields as $key => $val){
						$n = array_rand($answerValues, 1);
					/*	$attrArray[] = $val;
						$valArray[] = $answerValues[$n];*/
						$attrArray[$val] = $answerValues[$n];
						unset($answerValues[$n]);
					}
				}
			}

			//scale z tipu prikaza: drag&drop
			else if($question['les_sql'] == 8){
				//TODO: še ni podprto v webcati
			}

			//odgovor na open vprašanja
			if($question['answers_filter'] == 0 && count($openAnswers) > 0){
				foreach($openAnswers as $key => $val){
					/*$attrArray[] = $val;
					$valArray[] = "'sample scale response text'";*/
					$attrArray[$val] = "sample scale response text";
				}
			}

			break;
		//multi response --------------------------------------------------------
		case 3:

			//$q = new MultiResponse($db, $question);
			//$fields = $q->getStructureFields();
			$allQuestionFields[$question['id']] = $fields;


			//upoštevanje 'attachAnswer' opcije
			if($question['attachAnswers'] > 0){
				removeAttachedAnswers($values, $fields, $legend, $question, "scale_multi", $allQuestionFields, $attrArray);
			}


			$minAnswers = 1;

			//če ni potrebno odgovoriti na vse odgovore (MA unchecked)
			if($question['must_answer'] == 0){
				$minAnswers = 0;
			}

            $openAnsIds = explode(':', $question['open_answers']);

			//najprej ven odstranimo vse open answer odgovore in jih shranimo v $openAnswers
			$openAnswers = array();
			foreach($fields as $key => $val)
			{
			    foreach($openAnsIds as $openId)
                {
                    if(strval($key) == 'o_'.$openId)
                    {
                        array_push($openAnswers, $fields[$key]);
                        unset($fields[$key]);
                    }
                }

			}

			//multiresponse brez legende
			if($question['leg_sql'] == ""){
				$st = rand($minAnswers, count($values));
				if($st > 0)
				{
					$randKeys = randomArrayKeys($values, $st);
					//če ni 'nogo together' pogojev
					if($question['multi_nogo_answers'] == "")
					{
						foreach ($randKeys as $k => $v)
						{
							if(isAllowed($question['q_name'], $fields[$v], $values, $valuesOrder))
								$attrArray[$fields[$v]] = $values[$v];
						}
					}
					//če so 'nogo together' pogoji
					else
					{
						$nogo_answers = explode(",", $question['multi_nogo_answers']);
						$tempArry = array();
						//$tempVal = array();
					//	$nogo_selected = false;
						foreach ($randKeys as $v) {
							if(in_array($values[$v], $nogo_answers))
							{
								/*$tempAttr = array();
								$tempVal = array();*/

								$tempArry = array();
								if(isAllowed($question['q_name'], $fields[$v], $values, $valuesOrder))
								{
									$tempArry[$fields[$v]] = $values[$v];
									break;
								}
							}
							else
							{

								if(isAllowed($question['q_name'], $fields[$v], $values, $valuesOrder))
									$tempArry[$fields[$v]] = $values[$v];

							}

                            //$attrArray[$fields[$v]] = $values[$v];
						}
						foreach($tempArry as $key => $val)
								$attrArray[$key] = $val;
					}
				}
			}
			//multiresponse z legendo
			else {
				$questions = array_chunk($fields, count($legend));
				//če ni 'nogo_together' pogojev
				if($question['multi_nogo_answers'] == "" AND $question['multi_nogo_legends'] == ""){
					foreach ($questions as $key => $val) {

						$st = rand($minAnswers, count($legend));
						if($st > 0){
							$randKeys = randomArrayKeys($val, $st);
							foreach ($randKeys as $v) {

								$legVal = array_rand($legend);
								$legVal = $legend[$legVal];

								if(isAllowed($question['q_name'], $val[$v], $values, $valuesOrder))
									$attrArray[$val[$v]] = $legVal;
							}
						}
					}
				}
				//če so 'nogo together' pogoji (odgovori in/ali legenda)
				else {
					$nogo_answers = explode(",", $question['multi_nogo_answers']);
					$nogo_legend = explode(",", $question['multi_nogo_legends']);

					foreach ($questions as $key => $val) {
						$st = rand($minAnswers, count($legend));
						if($st > 0){
							$randKeys = randomArrayKeys($val, $st);
							$tempAttr = array();
							$tempVal = array();
							$nogo_leg = false;
							//var_dump($values);
							foreach($randKeys as $randKey)
							{
								//če so odgovori v nogo_answers
								if(in_array($values[$key], $nogo_answers))
								{
									//pobriši trenuten $randKey column(values in fields) z $attrArray in $valArray
									foreach($questions as $q)
									{
										/*if(in_array($q[$randKey], $attrArray)){
											$index = array_search($q[$randKey], $attrArray);
											unset($attrArray[$index]);
											unset($valArray[$index]);
										}*/
                                        unset($attrArray[$q[$randKey]]);
									}
								}
								//če niso, je potrebno vseeno gledati za nazaj, če je njihov column označen, g moremo pobirati, enako kot zgoraj
								else
								{

									//pobriši trenuten $randKey column(values in fields) z $attrArray in $valArray
									foreach($questions as $questionKey => $q)
									{
										/*if(in_array($q[$randKey], $attrArray) AND in_array($values[$questionKey], $nogo_answers)){
											$index = array_search($q[$randKey], $attrArray);
											unset($attrArray[$index]);
											unset($valArray[$index]);
										}*/

										if(in_array($values[$questionKey], $nogo_answers))
                                        {
                                            unset($attrArray[$q[$randKey]]);
                                        }
									}
								}


								if(in_array($legend[$randKey], $nogo_legend))
								{
									/*$tempAttr = array();
									$tempVal = array();*/
									//var_dump($values);
									$tempArry = array();
									if(isAllowed($question['q_name'], $fields[$randKey], $values, $valuesOrder))
									{
										//$tempArry[$fields[$randKey]] = $values[$randKey];
										$tempArry[$fields[$randKey]] = $values[$randKey];
										break;
									}


								//	$nogo_selected = true;
									/*$tempAttr[] = $fields[$v];
									$tempVal[] = $values[$v];*/
								}
								else
								{
									/*if($nogo_selected == true)
									{
										/*$tempAttr = array();
										$tempVal = array();
										$tempArry = array();
										$nogo_selected = false;
									}*/
									if(isAllowed($question['q_name'], $fields[$randKey], $values, $valuesOrder))
										$tempArry[$fields[$randKey]] = $values[$randKey];
									/*$tempAttr[] = $fields[$v];
									$tempVal[] = $values[$v];*/
								}
								/*if(in_array($legend[$randKey], $nogo_legend))
								{
									$tempAttr = array();
									$tempVal = array();
									$nogo_leg = true;
								/*	$tempAttr[] = $val[$randKey];
									$tempVal[] = $legend[$randKey];
								}
								else
								{
									if($nogo_leg == true)
									{
										$tempAttr = array();
										$tempVal = array();
										$nogo_leg = false;
									}
									/*$tempAttr[] = $val[$randKey];
									$tempVal[] = $legend[$randKey];
								}
                                $attrArray[$val[$randKey]] = $legend[$randKey];*/
							}
							/*//merging arrays
							foreach($tempAttr as $attribute){
								array_push($attrArray, $attribute);
							}
							foreach($tempVal as $value){
								array_push($valArray, $value);
							}*/

							foreach($tempArry as $key => $val)
							{
								$attrArray[$key] = $val;
							}
						}
					}
				}
			}

			//var_dump($openAnswers);
			//odgovor na open vprašanja
			if($question['answers_filter'] == 0 AND count($openAnswers) > 0){
				foreach($openAnswers as $key => $val){
					$fieldKey = str_replace('opn', '', $val);

					if($attrArray[$fieldKey])
						$attrArray[$val] = "sample multi response text";
				}
			}

			break;
		//open ------------------------------------------------------------------
		case 4:
			/*$open = new Open($db, $question);
			$fields = $open->getStructureFields();
			*/
			//če ni potrebno odgovoriti na vse odgovore (MA unchecked)
			if($question['must_answer'] == 0){
				//samo en open odgovor
				if($question['odg_sql'] == "" AND rand(0, 1) == 1){
					$attrArray[$fields[0]] = "sample open response text";
				}
				//open vpr. z in brez legende
				else {
					$st = rand(0, count($fields));
					if($st > 0){
						$i = 1;
						foreach($fields as $field)
                        {
                            if(rand(0, 1) < 0.5)
                            {

                            	if(isAllowed($question['q_name'], $field, $values, $valuesOrder))
                                	$attrArray[$field] = "sample open response text ".  $i;
                                $i++;
                            }
                        }
					}
				}
			}
			//če je potrebno odgovoriti na vse odgovore (MA checked)
			else {
				//samo en open odgovor
				if($question['odg_sql'] == ""){
					$attrArray[$fields[0]] = "sample open response text";
				}
				//open vpr. z in brez legende
				else {
					$i = 1;
					foreach($fields as $val)
					{
						if(isAllowed($question['q_name'], $val, $values, $valuesOrder))
							$attrArray[$val] = "sample open response text ".$i;

						$i++;
					}
				}
			}

			break;
		//timestamp -------------------------------------------------------------
		case 6:
			/*$time = new Timestamp($db, $question);
			$fields = $time->getStructureFields();*/

			$field_name = explode(" ", $fields[0]);

			/*$attrArray[] = $field_name[0];
			$valArray[] = "'".date("Y-m-d H:i:s")."'";*/
			$attrArray[$field_name[0]] = date("Y-m-d H:i:s");
			break;
		default:
			break;
	}

	//upoštevanje 'filter out' filtra
	if($question['con_sql'] != ""){
        //if filter out condition is not fulfilled in max filter tries we skip this question and we add error to ErrorReport class
		if(filterOut($e, $question['con_sql'], $attrArray, $fields, $question['q_name']) == false && $repetCnt < MAX_FILTER_TRIES){
			$repetCnt++;
            //print $question['q_name'] . " " . $repetCnt . "</br>";
			goto reselect;//ponovno izpolni to vprašanje
		}
        else if($repetCnt == MAX_FILTER_TRIES)
        {
            $errorReport->addError($question['q_name'],"Filter out condition is not fulfilled",array(
                'number_of_tries' => $repetCnt
            ));

        }
	}

    //var_dump($attrArray);
   /* var_dump($values);
*/}

/**
 * Upoštevanje attached vprašanj. Funkcija odstrani določene odgovore pri attached vprašanju
 *
 * @param $values vrednosti odgovorov
 * @param $fields imena polj odgovora
 * @param $legend vrednosti legende
 * @param $question array podatkov posameznega vprašanja
 * @param $type tip vprašanja
 * @param $allQuestionFields vrednosti odgovorov vseh vprašanj
 * @param $attrArray polje atributov
 */
function removeAttachedAnswers(&$values, &$fields, $legend = null, $question, $type, $allQuestionFields, $attrArray){

	$qId = $question['attachAnswers'];

	if(array_key_exists($qId, $allQuestionFields)){
		$attachedQfields = $allQuestionFields[$qId];
		//pridobi $fields vprašanja z podanim id-jem
		$tempArray = array();
		foreach($attachedQfields as $val){
			/*if(in_array($val, $attrArray)){
				$tempKey = array_search($val, $attrArray);
				if(is_numeric($tempKey)){
					$tempArray[$val] = $valArray[$tempKey];
				}
			}*/

			$tempArray[$val] = $attrArray[$val];
		}

		switch($type){
			case "single":
				//hide if false: unchecked
				if($question["attachFalse"] == 0){
					foreach($tempArray as $val){
						if(in_array($val, $values)){
							$tmpKey = array_search($val, $values);
							unset($values[$tmpKey]);
						}
					}
				}
				//hide if false: checked
				else {
					$tmpValues = array();
					foreach($tempArray as $val){
						if(in_array($val, $values)){
							$tmpKey = array_search($val, $values);
							$tmpValues[] = $values[$tmpKey];
						}
					}
					$values = $tmpValues;
				}

				break;

			case "scale_multi":
				//$tempArray = array_unique($tempArray);
				//hide if false: unchecked
				if($question["attachFalse"] == 0){
					if($question['leg_sql'] == ""){//brez legende
						foreach($tempArray as $val){
							if(in_array($val, $values)){
								$tmpKey = array_search($val, $values);
								unset($fields[$tmpKey]);
							}
						}
					}
					else {//z legendo
						$tmpFields = array_chunk($fields, count($legend));

						foreach($tempArray as $val){
							if(in_array($val, $values)){
								$tmpKey = array_search($val, $values);
								unset($tmpFields[$tmpKey]);
								unset($values[$tmpKey]);
							}
						}
						$tempFields2 = array();
						foreach($tmpFields as $val){
							foreach($val as $subVal){
								$tempFields2[] = $subVal;
							}
						}
						$fields = $tempFields2;
					}
				}
				//hide if false: checked
				else {
					if($question['leg_sql'] == ""){//brez legende
						$tempFields = array();
						foreach($tempArray as $val){
							if(in_array($val, $values)){
								$tmpKey = array_search($val, $values);
								$tempFields[] = $fields[$tmpKey];
							}
						}
						$fields = $tempFields;
					}
					else {//z legendo
						$tmpFields = array_chunk($fields, count($legend));

						$tFields = array();
						$tValues = array();
						foreach($tempArray as $val){
							if(in_array($val, $values)){
								$tmpKey = array_search($val, $values);
								$tFields[] = $tmpFields[$tmpKey];
								$tValues[] = $values[$tmpKey];
								unset($values[$tmpKey]);
							}
						}
						$tmpFields = $tFields;
						$values = $tValues;

						$tempFields2 = array();
						foreach($tmpFields as $val){
							foreach($val as $subVal){
								$tempFields2[] = $subVal;
							}
						}
						$fields = $tempFields2;
					}
				}

				break;
		}
	}
}

/**
 * Filtriranje odgovorov. Z polja vrednosti odgovora se odstranijo vrednosti, ki izpolnjujejo pogoj 'filter_answer'
 *
 * @param $e objekt razreda Engine
 * @param $filterAnswer niz 'filter_answer' z tabele ProjectName_structure
 * @param $values polje vrednosti odgovora
 * @param $attrArray polje izbranih atributov oz. imen vprašanj
 */
function filterAnswers($e, $filterAnswers, &$values, $attrArray)
{

      $tempVals = array();
	foreach(explode("<!>", $filterAnswers) as $key => $val){
		if($val)
		{
		 //   var_dump($val);
		 //   var_dump($key);

//			$val = explode(" ", $val, 2);
			$explodeVal[0] = substr($val, 0,1);
            $explodeVal[1] = substr($val, 1);

			$condVariables = $e->returnConditionVariables($filterAnswers);
			$tempKey = array();
			foreach($condVariables as $cVal){
				//$tempKey[] = array_search($cVal, $attrArray);
				$returnArr[$cVal] = $attrArray[$cVal];
			}
		//	var_dump($returnArr);
			/*
			$returnArr = array();
			foreach($tempKey as $tVal){
				$returnArr[$attrArray[$tVal]] = $valArray[$tVal];
			*/

			$question = $e->prepareArrayForSandBox($returnArr);

			if(!trim($explodeVal[1])){
				return true;
			}
			if($question){
				foreach ($question as $qVal){
					eval($qVal);
				}
			}

			//če je/ni pogoj uspešen, se z $values odstani vrednost
			if($explodeVal[0] == 0){
				//var_dump($question);
				/*eval("if(!(\$explodeVal[1])){

                      \$tempVals[\$key] = \$values[\$key];
				        //unset(\$values[\$key]);
				} ");*/
				if($e->ConditionSandBox($question, $explodeVal[1]))
                {

                   // $tempVals[$key] = $values[$key];
                   unset($values[$key]);
                }
			} else if($explodeVal[0] == 1){
			    continue;
				/*eval("
					   if(" .$explodeVal[1] . "){

					   	  \$tempVals[\$key] = \$values[\$key];
					   }");*/
			}




          }
	}
           // $values = $tempVals;
	/*if(strpos($filterAnswers, "HH01_1 < ") !== false)
	{
		var_dump($filterAnswers,$values, $attrArray);
	}*/
}

/**
 * Filtriranje legende. Z polja vrednosti legende se odstranijo vrednosti, ki izpolnjujejo pogoj 'filter_legend'
 *
 * @param $e objekt razreda Engine
 * @param $filterLegend niz 'filter_legend' z tabele ProjectName_structure
 * @param $legend polje vrednosti legende
 * @param $attrArray polje izbranih atributov oz. imen vprašanj
 */
function filterLegend($e, $filterLegend, &$legend, $attrArray){
	foreach(explode("<!>", $filterLegend) as $key => $val){
		if($val){
			$val = explode(" ", $val, 2);

			$condVariables = $e->returnConditionVariables($val[1]);

			$tempKey = array();
			foreach($condVariables as $cVal){
				$tempKey[] = array_search($cVal, $attrArray);
			}

			$returnArr = array();
			foreach($tempKey as $tVal){
				$returnArr[$attrArray[$tVal]] = $valArray[$tVal];
			}

			$question = $e->prepareArrayForSandBox($returnArr);

			if(!trim($val[1])){
				return true;
			}

			if($question){
				foreach ($question as $qVal){
					eval($qVal);
				}
			}
			//če je/ni pogoj uspešen, se z $legend odstani vrednost
			if($val[0] == 0){
				eval("if(".$val[1].") unset(\$legend[\$key]);");
			} else if($val[0] == 1){
				eval("\$tempLegend = array();
					   if(".$val[1]."){
					   	  \$tempLegend[] = \$legend[\$key];
					   }
					   \$legend = \$tempLegend;");
			}
		}
	}
}

/**
 * Upoštevanje filtrov za prikazovanje vprašanj
 *
 * @param $e objekt razreda Engine
 * @param $filter_str niz 'sql_fil' z tabele ProjectName_structure
 * @param $attrArr polje izbranih atributov oz. imen vprašanj
 * @return true ali false, če pogoj za prikaz vprašanja izpolnjen ali ne
 */
function filterIn($e, $filter_str, $attrArr, $q_name) {
	$condVariables = $e->returnConditionVariables($filter_str);
	$filter_str = $e->externalConditionSystem($condVariables, $filter_str);
	global $errorReport;

    //Ask Borut : dovolimo pogoje brez condVariables (1 == 2)?

	/*if(!is_array($condVariables) OR count($condVariables) == 0){
		return true;
	}*/
	$returnArr = array();
	foreach($condVariables as $val)
	{
		/*if(in_array($val, $attrArr)){
			$valueKey = array_search($val, $attrArr);
			$returnArr[$val] = $valArr[$valueKey];
		}*/
		$returnArr[$val] = $attrArr[$val];
	}

	$databaseVars = $e->prepareArrayForSandBox($returnArr);

	if(!trim($filter_str)){
		return true;
	}

	if($databaseVars){
		foreach ($databaseVars as $val){
		    try
		    {
    			eval($val);
		    }catch(Exception $exc)
            {

             //   var_dump($exc);
              //  var_dump($e);
            }
		}
	}
  /*  var_dump($databaseVars);
    var_dump($filter_str);
	*/
	$code = "
			if(".$filter_str.")
			\$returnValue = true;
			else
			\$returnValue = false;
		";
	$validitor = new CodeValiditor();

   	$validitor->validateCode("<?php " .$code);
 	if($validitor->isCodeValid() == 1)
	{
		eval($code);
	}
	else
	{
		var_dump($q_name);
		$errorReport->addError($q_name, "Error in filter in.",array(
                'validitor_error' => $validitor->getErrors()
            ));
		//var_dump($validitor->getErrors());
	}


	//$returnValue = shell_exec("php -r 'echo 1;'");

	return $returnValue;
}

/**
 * Upoštevanje filtrov za skrivanje vprašanj
 *
 * @param $e objekt razreda Engine
 * @param $filter_str niz 'con_fil' z tabele ProjectName_structure
 * @param $attrArray polje izbranih atributov oz. imen vprašanj
 * @return true ali false, če pogoj za prikaz vprašanja izpolnjen ali ne
 */
function filterOut($e, $filter_str, &$attrArray, $fields, $q_name) {
	$condVariables = $e->returnConditionVariables($filter_str);
    $returnArr = array();
	global $errorReport;
	foreach($condVariables as $val)
	{
	   /* $t = array_search($val, $attrArray);
        $returnArr[$attrArray[$t]] = $valArray[$t];*/
        $returnArr[$val] = $attrArray[$val];
	}

	$question = $e->prepareArrayForSandBox($returnArr);

	if(!trim($filter_str)){
		return true;
	}

	if($question){
		foreach ($question as $val)
			eval($val);
	}

	//če pogoj ni uspešen, se z $attrArray in $valArray odstanijo vrednosti
   	$code = "if(".$filter_str."){
			\$returnValue = true;
		} else {
		 	foreach(\$fields as \$field){
		 	    unset(\$attrArray[\$field]);
			}
			\$returnValue = false;
	 	}";

   	$validitor = new CodeValiditor();

   	$validitor->validateCode("<?php " .$code);
 	if($validitor->isCodeValid() == 1)
	{
		eval($code);
	}
	else
	{
		$errorReport->addError($q_name, "Error in filter out.",array(
                'validitor_error' => $validitor->getErrors()
            ));
		var_dump($validitor->getErrors());
	}

	return $returnValue;
}

/**
 * Funkcija vrne indeks naslednjega vprašanja v $data polju, v primeru da je 'go to' pogoj izpolnjen
 *
 * @param $e objekt razreda Engine
 * @param $db objekt za delo z podatkovno bazo
 * @param $goto_str niz z 'go to' pogojem
 * @param $attrArr polje izbranih atributov oz. imen vprašanj
 * @param $projName ime projekta
 * @param $questionIds polje id-jev vprašanj
 * @param $data polje vprašanj
 * @return $nextQuestionId indeks naslednjega vprašanja v $data polju
 */
function goToQuestion($e, $db, $goto_str, $attrArr, $projName, $questionIds, $data) {
	$condVariables = $e->returnConditionVariables($goto_str);

	$returnArr = array();
	foreach($condVariables as $key => $val){
	/*	if(in_array($val, $attrArr)){
			$valueKey = array_search($val, $attrArr);
			$returnArr[$val] = $valArr[$valueKey];
		}*/
		$returnArr[$val] = $attrArr[$val];
	}

	$condArr = $e->prepareArrayForSandBox($returnArr);

	foreach(explode(",", $goto_str) as $gotoCondition){
		$condTmp = explode("#", $gotoCondition);

		if($e->ConditionSandBox($condArr, $condTmp[0])){
			//če je lokacija numerična
			if(is_numeric($condTmp[1])){
				if($condTmp[1] < 0){
					$sql = "SELECT `id` FROM ".DB_WARPIT_WEBCATI.".".$projName." WHERE `q_pos` = '".$condTmp[1]."'";
				}
				else {
					$nextQuestionId = $questionIds[$condTmp[1] - 1];
				}
			}
			//če je lokacija ime vprašanja
			else {
				$sql = "SELECT `id` FROM ".DB_WARPIT_WEBCATI.".".$projName." WHERE `q_name` = '".$condTmp[1]."'";
			}

			if(!$nextQuestionId){
				if(!$res = $db->SQLexecute($sql)) echo "create goto error: ".$this->db->GetError();
				$row = $db->fetchAssoc($res);
				$nextQuestionId = $row['id'];
			}
			//iskanje indeksa vprašanja v $data
			foreach($data as $key => $val){
				if($val['id'] == $nextQuestionId){
					$nextQuestionId = $key;
					break;
				}
			}

			return $nextQuestionId;
		}
	}
}

/**
 * Funkcija vrne indeks prvega vprašanja v $data polju
 *
 * @param $data polje vprašanj
 * @return $key indeks prvega vprašanja v $data polju
 */
function getFirstQuestionIndex($data) {
	$first = $_SESSION['rotFirstQuestion'];
	foreach($data as $key => $val){
		if($val['q_pos'] == $first){
			return $key;
			break;
		}
	}
}

/**
 * Funkcija preveri če vprašanje vsebuje skripto in v primeru da jo, jo izvede
 *
 * @param $db objekt za delo z bazo
 * @param $projName ime projekta
 * @param $question array podatkov posameznega vprašanja
 */
function useQuestionScript($db, $projName, $question, $errorReport) {

	$sql = "SELECT `script`
			FROM ".DB_WARPIT_WEBCATI.".".$projName."_script
			WHERE `id_question` = ".$question['id']."
			AND `id_event` IN (1, 2)";
	$res = $db->SQLexecute($sql);
	$row = $db->fetchAssoc($res);


	if(isset($row['script'])){
		try {
			//izvedba skripte
			eval($row['script']);
		}
		catch (Exception $e) {
            $errorReport->addError($question['q_name'],"Error in script",array(
                'script_error' => $e->getMessage()
            ));
			echo "\nNapaka pri izvedbi skripte vprašanja.\nRazlaga: ".$e->getMessage();

		}
	}
	else {
		return null;
	}
}

function customEval($script)
{
    return eval($script);
}
//MAIN
$idProj = $_POST['id_proj'];

//prodobitev: project_name
$db->ChangeDatabase(DB_WARPIT_WEBCATI_BASE);
$sql = "SELECT `proj_name` FROM " . DB_WARPIT_WEBCATI_BASE . "._Projects WHERE `id` = ".$idProj;
$res = $db->SQLexecute($sql);
$row = $db->fetchAssoc($res);
$projName = $row['proj_name'];
$errorReport = new ErrorReport($db, $projName);
if($_POST['id_attempt'] == 0)
{
    echo $errorReport->addAttempt();
 //   session_write_close();
 //   session_start();
    $_SESSION = $tmpSession;
  //  session_write_close();
    exit;
}
else if($_POST['action'] == 'completeGeneration')
{
    echo $errorReport->completeAttempt($_POST['id_attempt']);
    //session_write_close();
    //session_start();
    $_SESSION = $tmpSession;
    //session_write_close();
    exit;
}

$errorReport->setIdAttempt(intval($_POST['id_attempt']));


//nov objetk SurveySession in Engine za FilterIn funkcijo
$db->ChangeDatabase(DB_WARPIT_WEBCATI_BASE);
$sql = "SELECT `loginSID` FROM `_www_ids` WHERE `id_project` = ".$idProj . " AND user_type = 3 AND id_user = 0";
$res = $db->SQLexecute($sql);
$row = $db->fetchAssoc($res);
$loginSID = $row['loginSID'];

$webSession = new SurveySession($db, $loginSID);

$_SESSION['detectedDevice'] = 1;
//$_SESSION['testSurvey'] = 1;
$e = new Engine($db, $webSession);
$e->CreateRotationString();


//pridobitev podatkov z tabele: ProjectName
$data = array();//polje podatov vprašanj
$qIdArray = array();//polje id-jev vprašanj po vrstnem redu

$db->ChangeDatabase(DB_WARPIT_WEBCATI);
$sql = "SELECT * FROM `".$projName."` WHERE `q_pos` > 0 ORDER BY `q_pos` ASC";
$res = $db->SQLexecute($sql);
while ($dat = $db->fetchAssoc($res)) {
	$data[] = $dat;
	$qIdArray[] = $dat['id'];
}

//prodobitev podatkov z tabele: ProjectName_language
$langData = array();

$sql = "SELECT l.*
		FROM `".$projName."_language` AS l
		LEFT JOIN `".$projName."` AS p
		ON p.`id` = l.`id_question`
		WHERE l.`id_question` IN (".implode(", ", $qIdArray).")
		AND l.`id_text_type` IN (3, 4, 5)
		AND l.`id_language` = ".$_SESSION['id_defaultQuestionLng']."
		ORDER BY p.`q_pos` ASC";
$res = $db->SQLexecute($sql);
while ($dat = $db->fetchAssoc($res)) {
	$langData[] = $dat;
}

$odg = array();//polje z stringi odgovorov
$leg = array();//polje z stringi legend
$attr = array();
$legKey = 0;

foreach ($langData as $key => $val) {
	if ($val['id_text_type'] == 3) {//odgovor
		$odg[$val['id_question']] = $val['lngText'];
		$legKey = $val['id_question'];
	}
	if ($val['id_text_type'] == 4) {//legenda
		$leg[$legKey] = $val['lngText'];
	}
	if ($val['id_text_type'] == 5){
		$attr[$legKey] = $val['lngText'];
	}
}

//nov objekt razreda Question
$q = new Question($db);
//polja hranita imena atributov oz. odgovorov in njihove vrednosti. Uporabita se za shranjevanje vrednosti v bazo
$attrArray = array();

//polje atributov vsakega vprašanja posebej, ločenih po id-ju vprašanja (samo za single, scale in multi)
$allQuestionFields = array();
//polje zaporedja vprašanj
//$questionSequence = array();
$first = getFirstQuestionIndex($data);

$tempArray[] = $data[$first];
$i = $first + 1;

$startTime = time();
if(!isset($_SESSION['id_record']))
{
    $sql = "INSERT INTO " . DB_WARPIT_WEBCATI_BASE . ".".$projName."_structure (`user_id`, `status`, `status_rec`, `flag_bad`, `d_start`, `d_stop`)
            VALUES (-777, 1, 1, 76, '".$startTime."', '".date("Y-m-d H:i:s")."')";
    $db->SQLexecute($sql);
    $_SESSION['id_record'] = $db->GetLastInsertId();
}

//Pripravimo si vse skripte za vsa vprašanja in si jih postavimo v polje
$scriptArray = array();
$scriptSql = "SELECT id_question, script, id_event FROM " . DB_WARPIT_WEBCATI . "." . $projName . "_script";
$scriptRes = $db->SQLexecute($scriptSql);
while($dat = $db->fetchAssoc($scriptRes))
    if(strlen($dat['script']) > 0) $scriptArray[$dat['id_event']][$dat['id_question']] = $dat['script'];

//Lahko se zgodi da imamo v vprašalniku zanko, zato štejemo kolikokrat se je vprašanje ponovilo
$repetCount =array();
while($val = array_pop($tempArray))
{
		$repetCount[$val['q_name']]++;
		if($repetCount[$val['q_name']] > MAX_QUESTION_REPETE)
		{
			$errorReport->addError($val['q_name'],"This question was repeted " . $repetCount[$val['q_name']] .  " times.",array(
                'number_of_repetions' => $repetCount[$val['q_name']]
            ));


			//$errorReport->save();

			saveAndExit($attrArray, $startTime, $errorReport, $projName, 78);
			print "You have got loop in your questionere. Questions repete:\n";
			var_dump($repetCount);


			$_SESSION = $tmpSession;
			exit;
		}
		if(key_exists($val['id'], $scriptArray['1']))
		{
			$myScript = prepareScriptForAutofill($scriptArray['1'][$val['id']]);
            try
            {
            	//var_dump($myScript);
            	customEval($myScript);
            }catch(Exception $exc)
			{
				$errorReport->addError($val['q_name'],"Error in beforeload script");
			}
		}
	//	var_dump($val);
    	//upoštevanje 'filter in' filtrov
    	$filterInQuestion = true;

    	if($val['fil_sql'] != null){
    		$filterInQuestion = filterIn($e, $val['fil_sql'], $attrArray, $val['q_name']);
    	}

    	if($filterInQuestion == true AND $val['disable_question'] == 0 or $val['tip_sql'] == 6){
    		//array_push($questionSequence, $i - 1);

    		//nastavitev public lastnosti razreda Question
    		$obj = $q->createQuestion($val['tip_sql']);
    		$obj->q_name = $val['q_name'];
    		$obj->id_mask = $val['id_mask'];
    		$obj->odg_sql = $odg[$val['id']];
    		$obj->leg_sql = $leg[$val['id']];

    		$val['odg_sql'] = $odg[$val['id']];
    		$val['leg_sql'] = $leg[$val['id']];
    		$val['atr_sql'] = $attr[$val['id']];

			if(key_exists($val['id'], $scriptArray['2']))
			{
				$myScript = prepareScriptForAutofill($scriptArray['2'][$val['id']]);
	            try
	            {
	            	customEval($myScript);
	            }catch(Exception $e)
				{
					$errorReport->addError($val['q_name'],"Error in afterdisplay script");
				}
			}

    		//funkcija getStringValues pridobi vrednosti posameznega odgovora
    		$values = getStringValues($odg[$val['id']]);

            if(key_exists($val['id'], $scriptArray['4']))
            {

                $myScript = prepareScriptForAutofill($scriptArray['4'][$val['id']]);
                try
                {
                	//var_dump($myScript);
                	eval($myScript);
                }catch(Exception $e)
				{
					$errorReport->addError($val['q_name'],"Error in custom fill script");
				}
            }
            else
            {
                //random izbira odgovora
                $randVals = selectRandomAnswer($db, $values, $attrArray, $val, $e, $allQuestionFields, $errorReport);
            }


    		//če ima vprašanje pogoj 'go to'
    		if($val['goto_sql'] != null){
    			$tmp = goToQuestion($e, $db, $val['goto_sql'], $attrArray, $projName, $qIdArray, $data);
    			if(isset($tmp)){//če je pogoj izpolnjen
    				//lovljenje napake nastavitev vprašalnika
    				if($data[$tmp]['disable_question'] == 1){
    		//			echo "Napaka: Go to pogoj vprašanja '".$val['q_name']."' kaže na onemogočeno vprašanje.";
                   //     session_write_close();
                     //   session_start();
                        $_SESSION = $tmpSession;
                       // session_write_close();
    					exit;
    				}
    				array_push($tempArray, $data[$tmp]);
    				$i = $tmp;
    			} else {//v nasprotnem primeru se normalno naloži naslednje vprašanje
    				if(isset($data[$i])){
    					array_push($tempArray, $data[$i]);
    				} else {
    					break;
    				}
    			}
    		}
    		//če vprašanje nima pogoja 'go to'
    		else {
    			if(isset($data[$i])){
    				array_push($tempArray, $data[$i]);
    			} else {
    				break;
    			}
    		}
    	}
    	//če je vprašanje skrito oz. se ne prikaže brez izpolnitve 'filter in' pogoja
    	else
    	{
    		if(isset($data[$i]))
    		{
    			array_push($tempArray, $data[$i]);

    		} else {
    			break;
    		}
    	}
        $i++;

}

/*//temp
echo "Končni podatki:\n";
$tmpSql = array();
$fieldsArray = array();
$valuesArray = array();
foreach($attrArray as $field => $value){
//	echo $val." => ".$valArray[$key]."\n";

     $tmpSql[] = $field . " = '" . $value . "'";
     if(!isset($_SESSION['id_record']))
     {
            $fieldsArray[] = $field;
            $valuesArray[] = $value;
     }

}

/*$tmpSql[] = "user_id = -777";
$tmpSql[] = "status = 1";
$tmpSql[] = "status_rec = 1";
$tmpSql[] = "flag_bad = 76";
$tmpSql[] = "t_start =  " . $startTime;
$tmpSql[] = "t_stop = " . time() ;

//var_dump($tmpSql);

//temp
*/
var_dump($repetCount);

saveAndExit($attrArray, $startTime, $errorReport, $projName);
echo "Error report:\n";
//$errorReport->errorDump();
$errorReport->save();
//session_write_close();
//session_start();
$_SESSION = $tmpSession;
//session_write_close();
?>
