';
        $html .= '
'.$title.'
';
        $legendTitle = [
            'DegreeOfCertaintyVeryUnsure',
            'DegreeOfCertaintyUnsure',
            'DegreeOfCertaintyDeclaredIgnorance',
            'DegreeOfCertaintyPrettySure',
            'DegreeOfCertaintyVerySure',
        ];
        $html .= '
';
        foreach ($legendTitle as $i => $item) {
            $html .= '-  '.get_lang($item).'
 ';
        }
        $html .= '
';
        // get the html of items
        $i = 0;
        $testCategory = new Testcategory();
        foreach ($scoreList as $categoryId => $scoreListForCategory) {
            $category = $testCategory->getCategory($categoryId);
            $categoryQuestionName = '';
            if ($category) {
                $categoryQuestionName = $category->name;
            }
            if ($categoryQuestionName === '') {
                $categoryName = get_lang('WithoutCategory');
            } else {
                $categoryName = $categoryQuestionName;
            }
            $html .= '
';
            $html .= self::displayDegreeChartChildren(
                $scoreListForCategory,
                300,
                $categoryName,
                1,
                $maxHeight,
                false,
                false,
                $groupCategoriesByBracket
            );
            $html .= '
';
            if ($i == 2) {
                $html .= '
 
';
                $i = 0;
            } else {
                $i++;
            }
        }
        $html .= '
 ';
        return $html.'';
        $html .= '
'.$titleDisplay.'
';
        $nbResponsesInc = 0;
        if (isset($scoreList[4])) {
            $nbResponsesInc += (int) $scoreList[4];
        }
        if (isset($scoreList[5])) {
            $nbResponsesInc += (int) $scoreList[5];
        }
        $nbResponsesIng = isset($scoreList[3]) ? $scoreList[3] : 0;
        $nbResponsesCor = 0;
        if (isset($scoreList[1])) {
            $nbResponsesCor += (int) $scoreList[1];
        }
        if (isset($scoreList[2])) {
            $nbResponsesCor += (int) $scoreList[2];
        }
        $IncorrectAnswers = sprintf(get_lang('IncorrectAnswersX'), $nbResponsesInc);
        $IgnoranceAnswers = sprintf(get_lang('IgnoranceAnswersX'), $nbResponsesIng);
        $CorrectAnswers = sprintf(get_lang('CorrectAnswersX'), $nbResponsesCor);
        $html .= '
';
        $explainHistoList = null;
        if ($displayExplanationText) {
            // Display of histogram text
            $explainHistoList = [
                'DegreeOfCertaintyVeryUnsure',
                'DegreeOfCertaintyUnsure',
                'DegreeOfCertaintyDeclaredIgnorance',
                'DegreeOfCertaintyPrettySure',
                'DegreeOfCertaintyVerySure',
            ];
        }
        foreach ($colorList as $i => $color) {
            if (array_key_exists($color, $scoreList)) {
                $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom
            } else {
                $scoreOnBottom = 0;
            }
            $sizeBar = ($scoreOnBottom * $sizeRatio * 2).'px;';
            if ($i == 0) {
                $html .= '
';
                $html .= '
';
                $html .= '
'.$IncorrectAnswers.'
';
                $html .= '
';
            } elseif ($i == 3) {
                $html .= '';
                $html .= '
';
                $html .= '
'.$CorrectAnswers.'
';
                $html .= '
';
            } elseif ($i == 2) {
                $html .= '';
                $html .= '
';
                $html .= '
'.$IgnoranceAnswers.'
';
                $html .= '
';
                $html .= '
';
                $html .= '
 ';
            }
        }
        $html .= '
';
        $html .= '
 ';
        if ($returnHeight) {
            return [$html, $verticalLineHeight];
        } else {
            return $html;
        }
    }
    /**
     * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions.
     *
     * @param        $scoreList
     * @param        $widthTable
     * @param string $title
     * @param int    $sizeRatio
     * @param int    $minHeight
     * @param bool   $displayExplanationText
     * @param bool   $returnHeight
     * @param bool   $groupCategoriesByBracket
     * @param int    $numberOfQuestions
     *
     * @return array|string
     */
    public static function displayDegreeChartChildren(
        $scoreList,
        $widthTable,
        $title = '',
        $sizeRatio = 1,
        $minHeight = 0,
        $displayExplanationText = true,
        $returnHeight = false,
        $groupCategoriesByBracket = false,
        $numberOfQuestions = 0
    ) {
        $topAndBottomMargin = 10;
        $colorList = [
            self::LEVEL_DARKRED,
            self::LEVEL_LIGHTRED,
            self::LEVEL_WHITE,
            self::LEVEL_LIGHTGREEN,
            self::LEVEL_DARKGREEN,
        ];
        // get total attempt number
        $highterColorHeight = 0;
        foreach ($scoreList as $color => $number) {
            if ($number > $highterColorHeight) {
                $highterColorHeight = $number;
            }
        }
        $totalAttemptNumber = $numberOfQuestions;
        $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2;
        if ($verticalLineHeight < $minHeight) {
            $minHeightCorrection = $minHeight - $verticalLineHeight;
            $verticalLineHeight += $minHeightCorrection;
        }
        // draw chart
        $html = '';
        if ($groupCategoriesByBracket) {
            $title = api_preg_replace("/[^]]*$/", '', $title);
            $title = ucfirst(api_preg_replace("/[\[\]]/", '', $title));
        }
        $textSize = 80;
        $classGlobalChart = '';
        if ($displayExplanationText) {
            // global chart
            $classGlobalChart = 'globalChart';
        }
        $html .= '';
        $html .= '| '
            .$title
            .' | 
|---|
'
        ;
        $nbResponsesInc = 0;
        if (isset($scoreList[4])) {
            $nbResponsesInc += (int) $scoreList[4];
        }
        if (isset($scoreList[5])) {
            $nbResponsesInc += (int) $scoreList[5];
        }
        $nbResponsesIng = isset($scoreList[3]) ? $scoreList[3] : 0;
        $nbResponsesCor = 0;
        if (isset($scoreList[1])) {
            $nbResponsesCor += (int) $scoreList[1];
        }
        if (isset($scoreList[2])) {
            $nbResponsesCor += (int) $scoreList[2];
        }
        $colWidth = $widthTable / 5;
        $html .= '
                | '.
            sprintf(get_lang('IncorrectAnswersX'), $nbResponsesInc).'
                 | 
                '.
            sprintf(get_lang('IgnoranceAnswersX'), $nbResponsesIng).'
                 | 
                '.
            sprintf(get_lang('CorrectAnswersX'), $nbResponsesCor).'
                 | 
            
';
        $html .= '';
        foreach ($colorList as $i => $color) {
            if (array_key_exists($color, $scoreList)) {
                $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom
            } else {
                $scoreOnBottom = 0;
            }
            $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2;
            if ($i == 1 || $i == 2) {
                $html .= '| '
                ;
            } else {
                $html .= ' | '
                ;
            }
            $html .= ' '
                .$scoreOnBottom
                .'   '
            ;
            $html .= ' | ';
        }
        $html .= '
';
        if ($displayExplanationText) {
            // Display of histogram text
            $explainHistoList = [
                'DegreeOfCertaintyVeryUnsure',
                'DegreeOfCertaintyUnsure',
                'DegreeOfCertaintyDeclaredIgnorance',
                'DegreeOfCertaintyPrettySure',
                'DegreeOfCertaintyVerySure',
            ];
            $html .= '';
            $i = 0;
            foreach ($explainHistoList as $explain) {
                if ($i == 1 || $i == 2) {
                    $class = 'borderRight';
                } else {
                    $class = '';
                }
                $html .= '| '
                ;
                $html .= get_lang($explain);
                $html .= ' | ';
                $i++;
            }
            $html .= '
';
        }
        $html .= '
';
        if ($returnHeight) {
            return [$html, $verticalLineHeight];
        } else {
            return $html;
        }
    }
    /**
     * return previous attempt id for this test for student, 0 if no previous attempt.
     *
     * @param $exeId
     *
     * @return int
     */
    public static function getPreviousAttemptId($exeId)
    {
        $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
        $exeId = (int) $exeId;
        $sql = "SELECT * FROM $tblTrackEExercise
                WHERE exe_id = ".$exeId;
        $res = Database::query($sql);
        if (empty(Database::num_rows($res))) {
            // if we cannot find the exe_id
            return 0;
        }
        $data = Database::fetch_assoc($res);
        $courseCode = $data['c_id'];
        $exerciseId = $data['exe_exo_id'];
        $userId = $data['exe_user_id'];
        $attemptDate = $data['exe_date'];
        if ($attemptDate == '0000-00-00 00:00:00') {
            // incomplete attempt, close it before continue
            return 0;
        }
        // look for previous attempt
        $exerciseId = (int) $exerciseId;
        $userId = (int) $userId;
        $sql = "SELECT *
            FROM $tblTrackEExercise
            WHERE c_id = '$courseCode'
            AND exe_exo_id = $exerciseId
            AND exe_user_id = $userId
            AND status = ''
            AND exe_date > '0000-00-00 00:00:00'
            AND exe_date < '$attemptDate'
            ORDER BY exe_date DESC";
        $res = Database::query($sql);
        if (Database::num_rows($res) == 0) {
            // no previous attempt
            return 0;
        }
        $data = Database::fetch_assoc($res);
        return $data['exe_id'];
    }
    /**
     * return an array of number of answer color for exe attempt
     * for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
     * e.g.
     * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0].
     *
     * @param $exeId
     *
     * @return array
     */
    public static function getColorNumberListForAttempt($exeId)
    {
        $result = [
            self::LEVEL_DARKGREEN => 0,
            self::LEVEL_LIGHTGREEN => 0,
            self::LEVEL_WHITE => 0,
            self::LEVEL_LIGHTRED => 0,
            self::LEVEL_DARKRED => 0,
        ];
        $attemptInfoList = self::getExerciseAttemptInfo($exeId);
        foreach ($attemptInfoList as $attemptInfo) {
            $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty();
            $oQuestion->read($attemptInfo['question_id']);
            if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
                $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']);
                if ($answerColor) {
                    $result[$answerColor]++;
                }
            }
        }
        return $result;
    }
    /**
     * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
     * for each question category.
     *
     * e.g.
     * [
     *      (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12]
     *      (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8]
     *      (categoryId=)0 => [LEVEL_DARKGREEN => 1,
     *          LEVEL_LIGHTGREEN => 2,
     *          LEVEL_WHITE => 6,
     *          LEVEL_LIGHTRED => 1,
     *          LEVEL_DARKTRED => 9]
     * ]
     *
     * @param int $exeId
     *
     * @return array
     */
    public static function getColorNumberListForAttemptByCategory($exeId)
    {
        $result = [];
        $attemptInfoList = self::getExerciseAttemptInfo($exeId);
        foreach ($attemptInfoList as $attemptInfo) {
            $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty();
            $oQuestion->read($attemptInfo['question_id']);
            if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
                $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']);
                if (!array_key_exists($questionCategory, $result)) {
                    $result[$questionCategory] = [];
                }
                $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']);
                if ($answerColor && isset($result[$questionCategory])) {
                    if (!isset($result[$questionCategory][$answerColor])) {
                        $result[$questionCategory][$answerColor] = 0;
                    }
                    $result[$questionCategory][$answerColor]++;
                }
            }
        }
        return $result;
    }
    /**
     * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false.
     *
     * @param $exeId
     * @param $questionId
     * @param $position
     *
     * @return int
     */
    public static function getAnswerColor($exeId, $questionId, $position)
    {
        $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position);
        if (count($attemptInfoList) != 1) {
            // havent got the answer
            return 0;
        }
        $answerCodes = $attemptInfoList[0]['answer'];
        // student answer
        $splitAnswer = preg_split("/:/", $answerCodes);
        // get correct answer option id
        $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]);
        if ($correctAnswerOptionId == 0) {
            // error returning the correct answer option id
            return 0;
        }
        // get student answer option id
        $studentAnswerOptionId = isset($splitAnswer[1]) ? $splitAnswer[1] : null;
        // we got the correct answer option id, let's compare ti with the student answer
        $percentage = null;
        if (isset($splitAnswer[2])) {
            $percentage = self::getPercentagePosition($splitAnswer[2]);
        }
        if ($studentAnswerOptionId == $correctAnswerOptionId) {
            // yeah, student got correct answer
            switch ($percentage) {
                case 3:
                    return self::LEVEL_WHITE;
                case 4:
                case 5:
                    return self::LEVEL_LIGHTGREEN;
                case 6:
                case 7:
                case 8:
                    return self::LEVEL_DARKGREEN;
                default:
                    return 0;
            }
        } else {
            // bummer, wrong answer dude
            switch ($percentage) {
                case 3:
                    return self::LEVEL_WHITE;
                case 4:
                case 5:
                    return self::LEVEL_LIGHTRED;
                case 6:
                case 7:
                case 8:
                    return self::LEVEL_DARKRED;
                default:
                    return 0;
            }
        }
    }
    /**
     * Return the position of certitude %age choose by student.
     *
     * @param $optionId
     *
     * @return int
     */
    public static function getPercentagePosition($optionId)
    {
        $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
        $optionId = (int) $optionId;
        $sql = "SELECT position
                FROM $tblAnswerOption
                WHERE iid = $optionId";
        $res = Database::query($sql);
        if (Database::num_rows($res) == 0) {
            return 0;
        }
        $data = Database::fetch_assoc($res);
        return $data['position'];
    }
    /**
     * return the correct id from c_quiz_question_option for question idAuto.
     *
     * @param $idAuto
     *
     * @return int
     */
    public static function getCorrectAnswerOptionId($idAuto)
    {
        $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
        $idAuto = (int) $idAuto;
        $sql = "SELECT correct FROM $tblAnswer
                WHERE id_auto = $idAuto";
        $res = Database::query($sql);
        $data = Database::fetch_assoc($res);
        if (Database::num_rows($res) > 0) {
            return $data['correct'];
        } else {
            return 0;
        }
    }
    /**
     * return an array of exe info from track_e_attempt.
     *
     * @param int $exeId
     * @param int $questionId
     * @param int $position
     *
     * @return array
     */
    public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1)
    {
        $result = [];
        $and = '';
        $questionId = (int) $questionId;
        $position = (int) $position;
        $exeId = (int) $exeId;
        if ($questionId >= 0) {
            $and .= " AND question_id = $questionId";
        }
        if ($position >= 0) {
            $and .= " AND position = $position";
        }
        $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
        $cId = api_get_course_int_id();
        $sql = "SELECT * FROM $tblExeAttempt
                WHERE c_id = $cId AND exe_id = $exeId $and";
        $res = Database::query($sql);
        while ($data = Database::fetch_assoc($res)) {
            $result[] = $data;
        }
        return $result;
    }
    /**
     * @param int $exeId
     *
     * @return int
     */
    public static function getNumberOfQuestionsForExeId($exeId)
    {
        $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
        $exeId = (int) $exeId;
        $sql = "SELECT exe_exo_id
                FROM $tableTrackEExercise
                WHERE exe_id = ".$exeId;
        $res = Database::query($sql);
        $data = Database::fetch_assoc($res);
        if ($data) {
            $exerciseId = $data['exe_exo_id'];
            $objectExercise = new Exercise();
            $objectExercise->read($exerciseId);
            return $objectExercise->getQuestionCount();
        }
        return 0;
    }
    /**
     * Display student chart results for these question types.
     *
     * @param int      $exeId
     * @param Exercise $objExercice
     *
     * @return string
     */
    public static function displayStudentsChartResults($exeId, $objExercice)
    {
        $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId);
        $globalScoreList = self::getColorNumberListForAttempt($exeId);
        $html = self::displayDegreeChart(
            $globalScoreList,
            600,
            get_lang('YourOverallResultForTheTest'),
            2,
            0,
            true,
            false,
            false,
            $numberOfQuestions
        );
        $html .= '
';
        $previousAttemptId = self::getPreviousAttemptId($exeId);
        if ($previousAttemptId > 0) {
            $previousAttemptScoreList = self::getColorNumberListForAttempt(
                $previousAttemptId
            );
            $html .= self::displayDegreeChart(
                $previousAttemptScoreList,
                600,
                get_lang('ForComparisonYourLastResultToThisTest'),
                2
            );
            $html .= '
';
        }
        $list = self::getColorNumberListForAttemptByCategory($exeId);
        $html .= self::displayDegreeChartByCategory(
            $list,
            get_lang('YourResultsByDiscipline'),
            1,
            $objExercice
        );
        $html .= '
';
        return $html;
    }
    /**
     * send mail to student with degre certainty result test.
     *
     * @param int      $userId
     * @param Exercise $objExercise
     * @param int      $exeId
     */
    public static function sendQuestionCertaintyNotification($userId, $objExercise, $exeId)
    {
        $userInfo = api_get_user_info($userId);
        $recipientName = api_get_person_name($userInfo['firstname'],
            $userInfo['lastname'],
            null,
            PERSON_NAME_EMAIL_ADDRESS
        );
        $subject = "[".get_lang('DoNotReply')."] "
            .html_entity_decode(get_lang('ResultAccomplishedTest')." \"".$objExercise->title."\"");
        // message sended to the student
        $message = get_lang('Dear').' '.$recipientName.",
";
        $exerciseLink = "";
        $exerciseTitle = $objExercise->title;
        $message .= sprintf(
            get_lang('MessageQuestionCertainty'),
            $exerciseTitle,
            api_get_path(WEB_PATH),
            $exerciseLink
        );
        // show histogram
        $message .= self::displayStudentsChartResults($exeId, $objExercise);
        $message .= get_lang('KindRegards');
        $message = api_preg_replace("/\\\n/", '', $message);
        MessageManager::send_message_simple($userId, $subject, $message);
    }
}