<?php
/**
 * Export module - word
 * 
 * Contains all functions to generate Word file
 * 
 * @package linea21\utils\export
 * @author $Author$ - linea21 <info@linea21.com>
 * @version $Id$ 
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 * Define, compose and generate a SDI (Sustainable Development Indicators) Word report
 */

/**
 * cleanHTMLList()
 * remove unique p tag in li
 * @param string $content
 * @return string
 * @see https://simplehtmldom.sourceforge.io/docs/1.9/api/api/
 */

if(!function_exists('cleanHTMLList')) {

    function cleanHTMLList($content) {

        if(empty($content)) return '';

        $html = new simple_html_dom();

        $html->load($content);
        $el = $html->find('ul li, ol li');

        if(is_null($el) || count($el) === 0) return $content;  // necessary to prevent crash
        foreach($el as $e) {
            $ptags = $e->find('p');
            if(is_null($ptags) || count($ptags) === 0) return $content; // necessary to prevent crash
            // if a unique p tag in li we remove it to prevent extra gap on list
            if(count($ptags) === 1) {
                is_null($ptags[0]->innertext) ? $ptags[0]->outertext = '' : $ptags[0]->outertext = $ptags[0]->innertext;
            }
        }
        $clean = $html;
        $html->clear();
        unset($html);

        return $clean;

    }

}

/**
 * fixImageWidth()
 * remove given style (such as float or image width)
 * @param string $content
 * @return string
 */

if(!function_exists('fixImageWidth')) {
    
    function fixImageWidth($content) {
    
        $html = new simple_html_dom();
        
        $html->load($content);
        
        foreach ($html->find('img') as $el) {
            $el->{'style'} = '';
            $el->{'width'} = '600';
            $el->outertext = '<div style="text-align:center;">' . $el->outertext . '<br /><br /></div>'; // wrapping with <p> tag can cause issue "Fatal error: Uncaught BadMethodCallException: Cannot add TextRun in TextRun"
        }
        
        $content = $html;
        
        unset($html);
        
        return $content;
        
    }

}

/********************************************************************************************
 *
* Following functions are used to generate projects reports
*
********************************************************************************************/

if(!function_exists('project_display_projects_completion')) {
    function project_display_projects_completion($status) {
        
        $comp = $GLOBALS['sql_object']->DBSelect(SQL_getTotalProjectCompletion($status));
        
        if(isset($comp) && is_array($comp)) $content = sprintf(_t('project', 'completion-percentage'), round($comp[0]['completion'], 0));
        else $content = '';
        
        return esc($content);
    }
}


if(!function_exists('project_recursive')) {
    
    function project_recursive($levels, $bookmark_level) {
        
        global $ordered_items;
        global $project;
        global $section;
        global $report_settings;
        global $pageBreak;
        
        $debug = false;
    
        // we retrieve all root levels if not given - when first run
        if($levels === null) $levels = $GLOBALS['sql_object']->DBSelect(SQL_getLevelsList(true));
    
        // if($debug) print_r($levels);
        
        // for each root level ...
        foreach($levels as $l) {
            
            // on affiche ici le nom du thèmes
            // et la description si demandée
            if($debug) echo "<h1>". $l['level_name'] . "</h1><p>". $l['level_desc_project'] . "</p><br /><br />";
            
            // if ($report_settings['levels'] ==  true) project_display_level($l, $bookmark_level, $section);
            
            // if there is action related to current level we display them
            // first we prepare them
            $associated_projects = array();
            foreach($project as $p) {
                if($p['project_level_id'] == $l['level_id']) {
                    if($debug) echo "on affiche le projet ". $p['project_id'] ." (p-level-id".$p['project_level_id']. ") associé directement à ". $l['level_id']."<br />\n<br />\n";
                    array_push($associated_projects, $p);
                    array_push($ordered_items, $p);
                }
            }
            
            // we get levels children
            $levelschildren = getLevelChildren($GLOBALS['sql_object']->DBSelect(SQL_getLevelsList()), $l['level_id']);
            if($debug) echo "<h1>----- Here are children -----</h1>";
            if($debug) print_r($levelschildren);
            
            // we display level if they have associated projects or children levels and or we we display empty levels
            if($report_settings['levels'] ==  true && (count($associated_projects) > 0 || count($levelschildren) > 0 || $report_settings['display_empty_levels'] ===  true)) {
                project_display_level($l, $bookmark_level, $section);
            }
            
            // we display project if any
            if(count($associated_projects) > 0) {
    
                $associated_projects = sort_projects($associated_projects);
                
                foreach($associated_projects as $proj) project_display_by_levels($proj,$bookmark_level, $section);
            }
            
    
    
            if(count($levelschildren) > 0 ) project_recursive($levelschildren, $bookmark_level+1, $section);       
    
        }
        
        
    }
}

function sort_projects($projects) {
    
    // we init values each time we iterate
    $project_range = array();
    $project_name = array();
    
    // First we prepare multi-sort
    // @see http://php.net/manual/fr/function.array-multisort.php
    foreach ($projects as $key => $row) {
        $project_range[$key] = $row['project_range'];
        $project_name[$key] = $row['project_name'];
    }
    
    array_multisort($project_range, SORT_ASC, $project_name, SORT_ASC, $projects);
    
    return $projects;
    
}


function display_orphan_projects ($bookmark_level) {
    
    global $ordered_items;
    global $project;
    global $section;
    global $report_settings;
    global $pageBreak;
    
    $associated_projects = array();
    foreach($project as $p) {
        if($p['project_level_id'] == 0) {
            array_push($associated_projects, $p);
            array_push($ordered_items, $p);
        }
    }
    
    if(count($associated_projects) < 1) return false;
    
    if ($report_settings['levels'] ==  true) {
        $section->addTitle(esc(do_strip(_t('report', 'no-first-level'))), $bookmark_level);
        $section->addTextBreak(2);
    }
    
    $associated_projects = sort_projects($associated_projects);    
    foreach($associated_projects as $proj) project_display_by_levels($proj,$bookmark_level, $section);
    
    return true;
    
}

/**
 * project_display_info()
 * Affiche les infos générales d'un projet
 *
 * @param int $pointer
 * @return bool true
 */

if(!function_exists('project_display_by_levels')) {
    function project_display_by_levels($project, $bookmark_level, $section)
    {
        
        global $report_settings;
        global $pageBreak;
        
        $current_record = $project;
        
        if(defined('EXPORT_LOG') && EXPORT_LOG == 1) file_put_contents('../tmp/export-logs/word-projects.txt', $current_record['project_id']."\n", FILE_APPEND);
        
        // we override dynamic $bookmark_level
        if($report_settings['levels'] ==  false) $bookmark_level = 0;
        
        // we retrieve root level
        $levels = $GLOBALS['sql_object']->DBSelect(SQL_getLevelsList());
        $root_level = getLevelParent($levels, $current_record['level_id'], 0);


        // affichage du niveau d'avancement si existant
        if($current_record['project_achievement'] != '') {

            $colors = ['to_start' => array('bck-color' => '#d5d2d2', 'color' => '#333333'),
                'in_progress' => array('bck-color' => '#89c588', 'color' => '#333333'),
                'over' => array('bck-color' => '#4da148', 'color' => '#ffffff'),
                'postponed' => array('bck-color' => '#f19749', 'color' => '#ffffff'),
                'stopped' => array('bck-color' => '#da2648', 'color' => '#e8e8e8')
            ];
            $out_stage = '<span style="background-color:'.$colors[$current_record['project_achievement']]['bck-color'].'; color: '.$colors[$current_record['project_achievement']]['color'].';font-size:11px;padding:0 5px">&nbsp;'.mb_ucfirst($GLOBALS['lang']['project']['achievementItems'][$current_record['project_achievement']]) .'&nbsp;</span>';
            \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText($out_stage));
        }
        // titre du projet
        $out_title = formatText(mb_ucfirst($current_record['project_name']));
        
        // si non publié
        if ($current_record['project_statut'] == 'D') {
            $out_title .= ' / ' . strtolower(_t('statut', 'draftpdf'));
        }
        
        $section->addTitle(esc(do_strip($out_title)), $bookmark_level+1);
        
        
        // parent project
        if($current_record['project_parent_id'] != 0) {
            project_display_parent($current_record['parent_project_name']);
        }
        
        // Root levels
        // root parent has been retrieved before
        if ($report_settings['levels'] !==  true) {
            if(is_array($root_level) && $root_level['id'] != 0) {
                if(!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0) {
                    $out_level = formatText('» ' . mb_ucfirst($current_record['level_label']). ' : ' . $current_record['level_name']) ;
                    $out_level .=  ' / '. formatText( mb_ucfirst($root_level['label']) . ' : ' . $root_level['name']). PHP_EOL;
                } else {
                    $out_level = formatText('» ' . $current_record['level_name']) ;
                    $out_level .=  ' / '. formatText($root_level['name']). PHP_EOL;
                }
                $section->addText(esc(do_strip($out_level)), 'attachedTheme');
                $section->addTextBreak(1);
            } elseif(!empty($current_record['level_name'])) {
                if(!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0) {
                    $out_level = formatText('» ' . mb_ucfirst($current_record['level_label']). ' : ' . $current_record['level_name']) ;
                } else {
                    $out_level = formatText('» ' . $current_record['level_name']) ;
                }
                $section->addText(esc(do_strip($out_level)), 'attachedTheme');
                $section->addTextBreak(1);
            }
        }
        
        // cibles de l'action
        $targets = getAssociatedActors($current_record['project_id'], 'target');
        if(!empty($targets)) $section->addText(esc(do_strip(mb_ucfirst(strip_tags(_t('project', 'target'))). ' : '. $targets)));
        $section->addTextBreak(1);
        
        // finalities project
        if(defined('PROJECT_FINALITIES') && PROJECT_FINALITIES == 1) {
            $section->addTextBreak(1);
            $out_finalities_item = formatText(mb_ucfirst(strip_tags(_t('project', 'finalities'))));
            $section->addTitle(esc(do_strip($out_finalities_item)), ($bookmark_level+2));
            
            $sdfinalities = getFinalities($current_record['project_id'], 'array');
            
            foreach ($sdfinalities as $finality) {
                $section->addText(esc('       ' . $finality['state_utf8'] . ' ' . do_strip($finality['name'])), 'defaultF', 'defaultP');
            }
            $section->addTextBreak(2);
            
        }
        
        // operationnal goal
        if(!empty($current_record['project_opgoal'])) {
            $out_opgoal = formatText(empty_nc(do_strip($current_record['project_opgoal']))) . PHP_EOL;
            $out_opgoal_item = formatText(mb_ucfirst(strip_tags(_t('project', 'opgoal'))));
            $section->addTitle(esc(do_strip($out_opgoal_item)), ($bookmark_level+2));
            
            if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_opgoal'] = removeDomElement('img', $current_record['project_opgoal']);
            if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_opgoal'])))));
            else $section->addText(esc(do_strip($out_opgoal)), 'defaultF', 'defaultP');
            
            $section->addTextBreak(1);
        }
        
        // goal
        if(!empty($current_record['project_goal'])) {
            $out_goal = formatText(empty_nc(do_strip($current_record['project_goal']))) . PHP_EOL;
            $out_goal_item = formatText(mb_ucfirst(strip_tags(_t('project', 'goal'))));
            $section->addTitle(esc(do_strip($out_goal_item)), ($bookmark_level+2));
            
            if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_goal'] = removeDomElement('img', $current_record['project_goal']);
            if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_goal'])))));
            else $section->addText(esc(do_strip($out_goal)), 'defaultF', 'defaultP');
            
            $section->addTextBreak(1);
        }
        
        // description
        //   $out_desc = formatText(empty_nc(strip_tags($current_record['project_description']))) . PHP_EOL;
        if(!empty($current_record['project_description'])) {
            $out_desc = formatText(empty_nc(do_strip($current_record['project_description']))) . PHP_EOL;
            $out_desc_item = formatText(mb_ucfirst(strip_tags(_t('project', 'description'))));
            $section->addTitle(esc(do_strip($out_desc_item)), ($bookmark_level+2));
            
            if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_description'] = removeDomElement('img', $current_record['project_description']);
            if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_description'])))));
            else $section->addText(esc($out_desc), 'defaultF', 'defaultP');
            
            $section->addTextBreak(1);
        }
        
        // body
        if(!empty($current_record['project_body'])) {
            $out_body = formatText(empty_nc(do_strip($current_record['project_body']))) . PHP_EOL;
            $out_body_item = formatText(mb_ucfirst(strip_tags(_t('project', 'body'))));
            $section->addTitle(do_strip($out_body_item), ($bookmark_level+2));
            
            if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_body'] = removeDomElement('img', $current_record['project_body']);
            if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_body'])))));
            else $section->addText(esc($out_body), 'defaultF', 'defaultP');
            
            $section->addTextBreak(1);
        }        
        
        
        // comment only if EXPLICITLY called
        if(defined('EXPORT_COMMENT') && (stripos(EXPORT_COMMENT, 'project') !== false) && !empty($current_record['project_comment'])) {  
            
            $out_comment = formatText(empty_nc(do_strip($current_record['project_comment']))) . PHP_EOL;
            $out_comment_item = formatText(mb_ucfirst(strip_tags(_t('project', 'comment'))));
            $section->addTitle(do_strip($out_comment_item), ($bookmark_level+2));
            
            if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_comment'] = removeDomElement('img', $current_record['project_comment']);
            if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_comment'])))));
            else $section->addText(esc($out_comment), 'defaultF', 'defaultP');
            
            $section->addTextBreak(1);
        }
        
        project_complement($current_record);
        
        project_tasks($current_record, $bookmark_level+2);
        
        project_display_calendar($current_record, $bookmark_level+2);
        project_display_steering_budget($current_record, $bookmark_level+2, 2);
        
        project_display_impacts($current_record, $bookmark_level+2);
        
        // project_associated_indicators($current_record, $bookmark_level+2);
        // if($report_settings['dashboard_values']) project_associated_dashboard($current_record); // old code generated from html2canvas @todo remove ?
        if($report_settings['dashboard_values']) project_associated_indicators_values($current_record, $bookmark_level+2);
        
        // because $section->addPageBreak(); does not work in current version
        // we add page only if this is not a quick export
        if($report_settings['quick_export'] === false) $section->addTextBreak(null, null, $pageBreak);
        
        return true;
    }
}

/**
 * project_display_impacts()
 * Affiche les impacts de chacun des projets
 *
 * @param int $current_record
 * @return bool true
 */
if(!function_exists('project_display_impacts')) {
    function project_display_impacts($current_record, $bookmark_level) {
        
        global $section;
        global $phpWord;
        global $cellalign;
        global $cellHeaderStyle;
        global $styleTable;
        global $firstRowStyle;
        
        // if not defined or not enabled we return false
        if (!defined('PROJECT_IMPACTS') || PROJECT_IMPACTS == 0) return false;
        
        $project_impacts = unserialize($current_record['project_impact']);
        
        // no values, we return empty string
        if (!is_array($project_impacts)) return false;
        
        $out_body_item = formatText(mb_ucfirst(strip_tags(_t('project', 'impacts'))));
        $section->addTitle(esc(do_strip($out_body_item)), ($bookmark_level));
        
        
        $fStyle = array('size' => FONT_SIZE_MIN);
        $cStyle = array('align' => 'center');
        
        $phpWord->addTableStyle('units', $styleTable, $firstRowStyle);
        $table = $section->addTable('units');
        
        $cellsCount = count($project_impacts);
        // row 1 - header
        $row1 = $table->addRow();
        // row 2
        $row2 = $table->addRow();
        foreach ($project_impacts as $k => $v) {
            
            $row1->addCell(PAGE_WIDTH / $cellsCount, $cellHeaderStyle)->addText(mb_ucfirst($GLOBALS['lang']['project']['impactsItems'][$k]. ' (' . $v . '/' . PROJECT_IMPACTS . ')'), 'arrayHeader', $cStyle);
            $row2cell = $row2->addCell(PAGE_WIDTH / $cellsCount, $cellalign);
            $row2cellContent ='<p style="text-align:center;margin:10 10;font-weight:bold;">'; // necessary to get span aligned horizontally !!
            for ($i = 0; $i < PROJECT_IMPACTS; $i ++) {
                if ($v >= $i + 1)
                    $row2cellContent .= '<span style="color:#e98e4e;">⬤</span>';
                    else
                        $row2cellContent .= '<span style="color:#c1c1c1;">⬤</span>';
            }
            $row2cellContent .='</p>';

            \PhpOffice\PhpWord\Shared\Html::addHtml($row2cell, $row2cellContent, false, true, $cStyle);
        }
        $section->addTextBreak(2);
        
        return true;

    }
    
    
}


/**
 * project_tasks()
 * Affiche les tâches associées au projet
 *
 * @param int $current_record
 * @return bool true
 */
if(!function_exists('project_tasks')) {
    function project_tasks($current_record, $bookmark_level) {
        
        global $section;
        global $phpWord;
        global $styleTable;
        global $firstRowStyle;
        global $sql_object;


        if(defined('PROJECT_TASK') && PROJECT_TASK == 1) {
            
            $otask = new projectTask();
            $tasks = $otask->get_project_tasks($current_record['project_id'], $sql_object);
            
            if(!is_array($tasks)) return true;
            
            $out_item = formatText(mb_ucfirst(strip_tags(_t('project', 'tasks_title'))));
            $section->addTitle(esc(do_strip($out_item)), $bookmark_level);
            
            $tasksp =  get_task_progress_bar($current_record['project_id'], true);
            $tasks =   get_tasks_for_report($tasks); 
            
            $section->addText($tasksp, 'defaultF', 'align-right');
            $section->addTextBreak(1);
            
            $phpWord->addTableStyle('tasks', array_merge($styleTable, array('borderColor' => 'ffffff')), $firstRowStyle);
            $table = $section->addTable('tasks');
            
            
            $fStyle = array('size' => DOC_DEFAULT_SIZE);
            $fStyle2 = array('size' => FONT_SIZE_MIN, 'italic' => false, 'color' => '444444');
            $cStyle = array('align' => 'center');
            $fStyleS= array('size' => FONT_SIZE_MIN, 'bold' => false, 'color' => '333333');
            
            foreach($tasks as $el) {
                
                if($el['status_raw'] == 'todo') $color = 'dadada';
                if($el['status_raw'] == 'wip') $color = 'fbbf50';
                if($el['status_raw'] == 'done') $color = '61d3a4';
                
    
                $cellStyle =array('borderBottomSize' => 5, 'borderBottomColor' => 'ffffff',  'valign' => 'center', 'bgcolor' => 'ffffff');
                $cellStyleColor =array('borderBottomSize' => 5, 'borderBottomColor' => 'ffffff',  'valign' => 'center', 'bgcolor' => $color);
                
                $task = $el['label'];
                $row = $table->addRow();
                // we split width in 48 units 
                $row->addCell(PAGE_WIDTH / 48 * 11, $cellStyle)->addText(esc(mb_strtoupper($el['status'])), $fStyleS, $cStyle);
                $row->addCell(PAGE_WIDTH / 48 * 1, $cellStyleColor)->addText('', $fStyleS, $cStyle);
                $cell = $row->addCell((PAGE_WIDTH / 48 * 36 ), $cellStyle);
                
                // $cell->addText(do_strip($el['label'], true), $fStyle);
                \PhpOffice\PhpWord\Shared\Html::addHtml($cell, nl2br($el['label']));
                if(isset($el['done'])) $cell->addText(esc($el['done']), $fStyle2);

            }
            $section->addTextBreak(3);
            
            return true;

        }
    }
}

/**
 * project_associated_dashboard()
 * Affiche l'image des dernières valeurs des indicateurs
 *
 * @param int $current_record
 * @return bool true
 */
if(!function_exists('project_associated_dashboard')) {
    function project_associated_dashboard($current_record)
    {
    	global $section;
    
    	// $section->addTextBreak(1);
    	
    	// Affichage de l'image si elle existe
    	if(file_exists(SITE_PATH. 'tmp/report/project-'.$current_record['project_id'].'-dashboard.png')) {
    		$section->addImage(SITE_PATH. 'tmp/report/project-'.$current_record['project_id'].'-dashboard.png', array('align' => 'center', 'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(12)));
    	}
    
    	$section->addTextBreak(1);
    	
    	return true;
    }
}



/**
 * project_display_calendar()
 * Affiche les tableaux contenant information 'animation / comité de pilotage'
 * et budget
 *
 * @param int $current_record
 * @return bool true
 */
function project_display_calendar($current_record, $bookmark_level)
{
	global $section;
	global $phpWord;
	global $cellalign;
	global $cellHeaderStyle;
	global $styleTable;
	global $firstRowStyle;
	
	$out_item = formatText(mb_ucfirst(strip_tags(_t('project', 'calendar_title')))) ;
	
	$section->addTitle($out_item, $bookmark_level);
	
	$phpWord->addTableStyle('calendar', $styleTable, $firstRowStyle);
	$table = $section->addTable('calendar');
	
	$fStyle = array('size' => FONT_SIZE_MIN);
	$cStyle = array('align' => 'center');
	
	// header
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(_t('project', 'begin_date'))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(_t('project', 'estimated_date'))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(_t('project', 'end_date'))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(_t('project', 'progression'))), 'arrayHeader', $cStyle);
	
	// values
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText(empty_nc(esc($current_record['project_begin_date_display'])), $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText(empty_nc(esc($current_record['project_estimated_date_display'])), $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText(empty_nc(esc($current_record['project_end_date_display'])), $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText(empty_nc(esc($current_record['project_completed'])) . ' %', $fStyle, $cStyle);
	
	if(!empty($current_record['project_cal_comment'])) {
	    $section->addTextBreak(1);
	    
	    if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_cal_comment'] = removeDomElement('img', $current_record['project_cal_comment']);
	    if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_cal_comment'])))));
	    else $section->addText(esc(do_strip($current_record['project_cal_comment'])), 'defaultF', 'defaultP');
	    
	    $section->addTextBreak(1);
	    
	}
	$section->addTextBreak(3);
	
	return true;

}

if(! function_exists('getRawTendency')) {
	function getRawTendency($values, $indicator) {
		
		$tendency = '';

		$percentage = '';
		$evolution = '';
		
		$icoSup = ' 🡽 ';
		$icoInf = ' 🢆 ';
		$icoSta = ' 🡺';

		// we handle multivalues
		// if there is a previous value
		if (! empty($values[1]['sdiv_multivalue'])  && $indicator['sdii_multiple_type'] != 'none') {
			$data = unserialize($values[0]['sdiv_multivalue']);
			$dataPlusOne = unserialize($values[1]['sdiv_multivalue']);

			if ($indicator['sdii_nature'] == 'quantitative') {

                if($indicator['sdii_multiple_type'] == 'sum')  $cfield = '_total';
                if($indicator['sdii_multiple_type'] == 'mean')  $cfield = '_mean';
                $current_value = $data[0][$cfield];

                if($dataPlusOne[0][$cfield] != 0 && !is_null($data[0][$cfield]) && !is_null($dataPlusOne[0][$cfield])) {
                    $percentage = ($data[0][$cfield] - $dataPlusOne[0][$cfield]) / $dataPlusOne[0][$cfield] * 100;
                    $evolution = ' (' . round($percentage, 0) . '%)';
                } else {
                    $evolution = empty_nc('');
                }
			}
            if(!is_null($data[0][$cfield]) && !is_null($dataPlusOne[0][$cfield])) {
                if ($data[0][$cfield] > $dataPlusOne[0][$cfield]) {
                    $tendency .= $icoSup . sprintf(_t('dashboard', 'previous_value'), fnumber_format($dataPlusOne[0][$cfield], 'auto', false)) . $evolution;
                } elseif ($data[0][$cfield] < $dataPlusOne[0][$cfield]) {
                    $tendency .= $icoInf . sprintf(_t('dashboard', 'previous_value'), fnumber_format($dataPlusOne[0][$cfield], 'auto', false)) . $evolution;
                } else {
                    $tendency .= $icoSta . sprintf(_t('dashboard', 'previous_value'), fnumber_format($dataPlusOne[0][$cfield], 'auto', false));
                }
            }

			// we handle simple values
			// if there is a previous value
		} elseif (isset($values[1]['sdiv_value'])) {

            if(is_null($values[1]['sdiv_value'])) $previous_value = _t('dashboard','no_data');
            else $previous_value = fnumber_format($values[1]['sdiv_value'], 'auto', false);


            if ($indicator['sdii_nature'] == 'quantitative') {
                if($values[1]['sdiv_value'] != 0 && !is_null($values[1]['sdiv_value']) && !is_null($values[0]['sdiv_value'])) {
					$percentage = ($values[0]['sdiv_value'] - $values[1]['sdiv_value']) / $values[1]['sdiv_value'] * 100;
					$evolution = ' (' . round($percentage, 0) . '%)';
				}  else {
					$evolution = ' '.empty_nc('');
				}
			} else {

				$a = getBooleanValues($indicator);
				if ($a) {
					$index = array();
					foreach ($a as $key => $value) {
						array_push($index, $key);
					}
					$previous_value = $a[$values[1]['sdiv_value']];
				}
			}

            // finally, if any null value we don't display tendency
            if(is_null($values[0]['sdiv_value']) || is_null($values[1]['sdiv_value'])) {
                if ($values[0]['sdiv_value'] > $values[1]['sdiv_value']) {
                    $tendency .= $icoSup . sprintf(_t('dashboard', 'previous_value'), fnumber_format($previous_value, 'auto', false)) . $evolution;
                } elseif ($values[0]['sdiv_value'] < $values[1]['sdiv_value']) {
                    $tendency .= $icoInf . sprintf(_t('dashboard', 'previous_value'), fnumber_format($previous_value, 'auto', false)) . $evolution;
                } else {
                    $tendency .= $icoSta . sprintf(_t('dashboard', 'previous_value'), fnumber_format($previous_value, 'auto', false));
                }
            }
		}

		return sprintf('<div class="dashboard-indicator-tendency">%s</div>', $tendency);
	}
}

if(! function_exists('getRawIndicatorRecord')) {
	function getRawIndicatorRecord($scale_id, $indicator) {
		
		include_once('../dashboard/common.php');

        $style = ['font-size' => '16pt', 'color' => '#738ace'];
		
		if($indicator['sdii_type'] != 'not-set') $typecontent = ' <span style="color:#bcbcbc;font-size:8pt;font-weight:normal;">['.formatText(mb_ucfirst($GLOBALS['lang']['sdi']['select_type'][$indicator['sdii_type']]), '2HTML').']</span>'; else $typecontent='';
		
		$req_sdiav=SQL_getAllValue("SCA", $scale_id, $indicator['sdii_id']);
		$result_value = $GLOBALS['sql_object']-> DBSelect($req_sdiav);
		
		// if not values yet we return empty string
		if(!is_array($result_value)) return '';
		
		// we handle multivalues
		if ($indicator['sdii_value_type'] == 'multiple') {
			$data = unserialize($result_value[0]['sdiv_multivalue']);

            if($indicator['sdii_multiple_type'] == 'sum')  $cfield = '_total';
            if($indicator['sdii_multiple_type'] == 'mean')  $cfield = '_mean';
            if($indicator['sdii_multiple_type'] == 'none')  $cfield = '_none';

            if(is_null($data[0][$cfield])) {
                $current_value =  _t('dashboard', 'no_data'). ' ';
                $style = ['font-size' => '10pt', 'color' => '#eab86a'];
            } else $current_value = fnumber_format($data[0][$cfield], 'auto', false);

            if($indicator['sdii_multiple_type'] == 'none') {
                $current_value = _t('sdi', 'multiple_type_none'). ' ';
                $style = ['font-size' => '10pt', 'color' => '#b3b3b3'];
            }

			// we handle simple values
		} else {
			$a = getBooleanValues($indicator);
			
			if ($a && ($indicator['sdii_nature'] == 'boolean' || $indicator['sdii_nature'] == 'qualitative')) {
				$current_value = $a[$result_value[0]['sdiv_value']];
			} else {
                if(is_null($result_value[0]['sdiv_value'])) {
                    $current_value = _t('dashboard', 'no_data'). ' ';
                    $style = ['font-size' => '10pt', 'color' => '#eab86a'];
                }
                else $current_value = fnumber_format($result_value[0]['sdiv_value'], 'auto', false);
			}
		}

		$aval = '<p style="text-align:center;"><span style="color:'.$style['color'].';font-size:'.$style['font-size'].';font-weight:bold;">'.$current_value.'</span> <span style="font-weight:bold;color:#738ace;font-size:10pt;">'.formatText($indicator['sdii_unit']).'</span></p>';
		$aval .= '<p style="text-align:center;color:#bcbcbc;font-size:8pt;">'. getRawTendency($result_value, $indicator) .'</p>';

		if(isset($result_value[0])) {
			$arr = array_reverse($result_value);
			$lastval = end($arr);
			$lastyear = get_year($lastval['date_p']);
			$ayear = '<div style="font-size: 9pt;font-weight:bold;color:#bcbcbc;text-align:center" class="indicator-last-date">' . $lastyear . '</div>';
		}

		$aname = '<p style="color:#738ace;font-size:10pt;font-weight:bold;">' .formatText($indicator['sdii_name'], '2HTML') . '</p>';

		return array($aval, $ayear, $aname);
		
	}
}

if(! function_exists('project_associated_indicators_values')) {
	function project_associated_indicators_values($record, $bookmark_level) {
		global $section;
		global $phpWord;
		global $cellalign;
		global $cellHeaderStyle;
		global $styleTable;
		global $firstRowStyle;
		
		$result_sdi = $GLOBALS['sql_object']->DBSelect(SQL_getProjectSdiValues($record['project_id']));
		$scale_id = 1; // scale id value
		
		// we exit if no associated indicators
		if(!is_array($result_sdi)) return false;
		
		
		$ordered_indics = array();
		// we prepare ordered data if given
		// 1 - first data stored in $orderedIndicators, then all data
		$tmp = unserialize($record['project_indic_order']);
		if(is_array($tmp)) {
		    foreach($tmp as $k => $v) {
		        if(is_integer($k)) array_push($ordered_indics, $k); // to be sure it is not empty
		    }
		}
		// 2 - then, we iterate on all indicators that are not already in $ordered_indics
		foreach($result_sdi as $sdi) {
		    if($sdi['sdii_statut'] == 'P' && !in_array($sdi['sdii_id'], $ordered_indics)) array_push($ordered_indics, $sdi['sdii_id']); // to be sure it is not empty
		}
		
		// 3 - we first iterate on $ordered_indics to retrieve values
		$indics_with_values = [];
		foreach($ordered_indics as $k => $v) {
		    
		    // we search for the key of searched element : $j
		    // then we display the full record
		    $j = array_search($v, array_column($result_sdi, 'sdii_id'));
		    
		    // we get information from getRawIndicatorRecord which return an array to fill cells later
		    $indic = getRawIndicatorRecord($scale_id, $result_sdi[$j]);
		    
		    // we populate array, only if a value is returned by $indic
		    if(is_array($indic) && !in_array($indic, $indics_with_values)) array_push($indics_with_values, $indic);
		}
		
		// if no values, we do nothing
		if( count($indics_with_values) <=0 ) return false;
		
		
		$out_item = formatText(mb_ucfirst(strip_tags(_t('project', 'sdi')))) ;
		$section->addTitle(esc($out_item), $bookmark_level);
		
		$phpWord->addTableStyle('indicatorValues', $styleTable, $firstRowStyle);
		$table = $section->addTable('indicatorValues');
		
		$cStyle = array('align' => 'center', 'background-color' => 'CCCCCC');
		
		// header
		$row = $table->addRow();
		// 48 units
		$row->addCell(PAGE_WIDTH / 48 * 14, $cellHeaderStyle)->addText(mb_ucfirst(_t('dashboard', 'numeric_value')), 'arrayHeader', $cStyle);
		$row->addCell(PAGE_WIDTH / 48 * 5, $cellHeaderStyle)->addText(mb_ucfirst(_t('dashboard', 'year')), 'arrayHeader', $cStyle);
		$row->addCell(PAGE_WIDTH / 48 * 29, $cellHeaderStyle)->addText(mb_ucfirst(_t('dashboard', 'label_value')), 'arrayHeader', $cStyle);
		
		foreach($indics_with_values as $indic) {
			
			// values
			$row = $table->addRow();        
			$cell1 = $row->addCell(PAGE_WIDTH / 48 * 14, $cellalign);
			$cell2 = $row->addCell(PAGE_WIDTH / 48 * 5, $cellalign);
			$cell3 = $row->addCell(PAGE_WIDTH / 48 * 29, array_merge($cStyle, array('align' => 'left')));
			
			\PhpOffice\PhpWord\Shared\Html::addHtml($cell1, empty_nc($indic[0]), false, false, null);
			\PhpOffice\PhpWord\Shared\Html::addHtml($cell2, empty_nc($indic[1]), false, false, null);
			\PhpOffice\PhpWord\Shared\Html::addHtml($cell3, empty_nc($indic[2]), false, false, null);
	   }
	}
}

/**
 * project_associated_indicators()
 * Affiche la liste des indicateurs associés
 *
 * @param int $current_record
 * @return bool true
 */
function project_associated_indicators($current_record, $bookmark_level)
{
	global $section;

	$query = SQL_getProjectSdi($current_record['project_id']);
	$data = $GLOBALS['sql_object']->DBSelect($query);


	if(isset($data[0]['sdii_id'])) {
	    
	    $out_indicators_item = formatText(esc(mb_ucfirst(_t('project', 'sdi'))));
	    $section->addTitle($out_indicators_item, ($bookmark_level));
	    
// 		foreach ($data as &$value) {
// 			$section->addListItem(do_strip($value['sdii_name']), 0, 'list');
// 		}
		
		$section->addTextBreak(2);
	} // else $section->addText(mb_ucfirst(_t('divers','none')));

	

	return true;
}


/**
 * project_complement()
 * Affiche la priorité et l'échelle de rattachement
 *
 * @param int $current_record
 * @return bool true
 */
function project_complement($current_record)
{
	global $section;

	$textrun = $section->addTextRun('align-right');
	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'statut'))). ' : '), 'softLabelMin');
	$textrun->addText(esc(display_statut($current_record['project_statut'])), 'softMinBold');
	$textrun->addText(esc(' / ' . mb_ucfirst(strip_tags(_t('project', 'priority'))). ' : '), 'softLabelMin');
	$textrun->addText(esc($current_record['priority_name']), 'softMinBold');
	if($current_record['scale_id'] != 0 ) {
	    $textrun->addText(esc(' / ' . mb_ucfirst(strip_tags(_t('project', 'scale'))). ' : '), 'softLabelMin');
	    $textrun->addText(esc(do_strip($current_record['scale_denomination'])), 'softMinBold');
	}
	
	$section->addTextBreak(2);

	return true;
}


/**
 * project_display_steering_budget()
 * Affiche les tableaux contenant information 'animation / comité de pilotage'
 * et budget
 *
 * @param int $current_record
 * @return bool true
 */
function project_display_steering_budget($current_record, $bookmark_level, $columns = 2)
{
	global $section;
	global $phpWord;
	global $cellalign;
	global $cellHeaderStyle;
	global $styleTable;
	global $firstRowStyle;
	
	$coordinator = getAssociatedActors($current_record['project_id'], 'coordinator');
	$partners = getAssociatedActors($current_record['project_id'], 'partner');
	$manager = getAssociatedManagers($current_record['project_id']);
	
	// do not display anything if fields are empty
	if(empty($current_record['project_elected']) &&  empty($coordinator) && empty($manager) && empty($partners) && empty($current_record['project_team']) && empty($current_record['project_budget']) && empty($current_record['project_budget_comment'])) return true;
	
	$section->addTitle(esc(strip_tags(_t('project','steering_title')) . ' - ' . strip_tags(_t('project','budget_title'))), $bookmark_level);


	$fStyle = array('size' => FONT_SIZE_MIN);
	$cStyle = array('align' => 'center');
	
	$phpWord->addTableStyle('steering_budget', $styleTable, $firstRowStyle);
	
	// only one table but 2 columns
	if($columns == 2) {

    	$table = $section->addTable('steering_budget', array('cellMargin' => 5));
    	
    	// header
    	$row = $table->addRow();
    	$row->addCell(PAGE_WIDTH / 2, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('project', 'steering_title')))), 'arrayHeader', $cStyle);
    	$row->addCell(PAGE_WIDTH / 2, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('project', 'budget_title')))), 'arrayHeader', $cStyle);
    	
    	// content 
    	$row = $table->addRow();
    	$table_steering = $row->addCell(PAGE_WIDTH / 2, $cellalign)->addTable(array('width' =>  'auto', 'align' => 'left'));
    	$table_budget = $row->addCell(PAGE_WIDTH / 2, $cellalign)->addTable(array('width' =>  'auto', 'align' => 'left'));
    	
    	$page_size = PAGE_WIDTH / 2;
    	
    	//  2 distincts tables
	} else {
	    $table = $section->addTable('steering_budget', array('cellMargin' => 5));
	    $section->addTextBreak(1);
	    $table2 = $section->addTable('steering_budget', array('cellMargin' => 5));
	    
	    // header
	    $row = $table->addRow();
	    $row->addCell(PAGE_WIDTH, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('project', 'steering_title')))), 'arrayHeader', $cStyle);
	    $row = $table2->addRow();
	    $row->addCell(PAGE_WIDTH, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('project', 'budget_title')))), 'arrayHeader', $cStyle);
	    
	    // content
	    $row = $table->addRow();
	    $table_steering = $row->addCell(PAGE_WIDTH, $cellalign)->addTable(array('width' =>  'auto', 'align' => 'left'));
	    $row = $table2->addRow();
	    $table_budget = $row->addCell(PAGE_WIDTH, $cellalign)->addTable(array('width' =>  'auto', 'align' => 'left'));
	    
	    $page_size = PAGE_WIDTH;
	}
	
	$r1 = $table_steering->addRow()->addCell($page_size);
	
	if(!empty($current_record['project_elected'])) {
	    
    	$textrun = $r1->addTextRun();
    	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'elected')))). ' : ', 'softLabelMin');
    	$textrun->addText(empty_nc(esc(do_strip($current_record['project_elected']))), 'softMinBold');
	}
	
	if(!empty($coordinator)) {
    	$r2 = $table_steering->addRow()->addCell($page_size);
    	$textrun = $r2->addTextRun();
    	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'coordinator'))). ' : '), 'softLabelMin');
    	$textrun->addText(empty_nc(esc($coordinator)), 'softMinBold');
	}
	
	if(!empty($manager)) {
    	$r3 = $table_steering->addRow()->addCell($page_size);
    	$textrun = $r3->addTextRun();
    	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'manager'))). ' : '), 'softLabelMin');
    	$textrun->addText(empty_nc(esc($manager)), 'softMinBold');
	}
	
	if(!empty($partners)) {
    	$r4 = $table_steering->addRow()->addCell($page_size);
    	$textrun = $r4->addTextRun();
    	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'partners'))). ' : '), 'softLabelMin');
    	$textrun->addText(empty_nc(esc($partners)), 'softMinBold');
	}
	
	if(!empty($current_record['project_team'])) {
    	$r5 = $table_steering->addRow()->addCell($page_size);
    	$r5->addText(esc(mb_ucfirst(strip_tags(_t('project', 'team'))). ' : '), 'softLabelMin');
    	
    	if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_team'] = removeDomElement('img', $current_record['project_team']);
    	if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($r5, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_team'])))), false,false,null,["font" => array("size" => 6)]);
    	else $r5->addText(empty_nc(esc(do_strip($current_record['project_team']))), 'softMinBold');
	}
	
	if(!empty($current_record['project_budget'])) {
    	$r1 = $table_budget->addRow()->addCell($page_size);
    	$textrun = $r1->addTextRun();
    	$textrun->addText(esc(mb_ucfirst(strip_tags(_t('project', 'budget'))). ' : '), 'softLabelMin');
    	$textrun->addText(empty_nc(fnumber_format($current_record['project_budget'], 0, false)), 'softMinBold');
	}
	
	if(!empty($current_record['project_budget_comment'])) {
    	$r2 = $table_budget->addRow()->addCell($page_size);
    	$r2->addText(esc(mb_ucfirst(strip_tags(_t('project', 'budget_comment'))). ' : '), 'softLabelMin');
    	
    	if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['project_team'] = removeDomElement('img', $current_record['project_budget_comment']);
    	if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($r2, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['project_budget_comment'])))), false,false,null,["font" => array("size" => 6)]);
    	else $r2->addText(empty_nc(esc(do_strip($current_record['project_budget_comment']))), 'softMinBold');
	}
	
	
	$section->addTextBreak(3);
	

	return true;
}

function project_display_parent($name)
{
	global $section;

	$out = formatText(esc(empty_nc(do_strip($name)))) . PHP_EOL;
	$out_item = formatText('⬉ '. mb_ucfirst(esc(strip_tags(_t('project', 'parent')))));
	
	$textrun = $section->addTextRun();
	$textrun->addText(do_strip($out_item) . ' : ', 'softLabelMin');
	$textrun->addText(do_strip($out), 'softMinBold');
	$section->addTextBreak(1);

}

/**
 * project_display_level()
 * display root level as chapter
 * @param string $level
 */
function project_display_level($level, $bookmark_level, $section)
{
    
    // global $section;
    global $report_settings;
    global $pageBreak;
    // global $bookmark_level;
    
    if(!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0) $level_label = esc($level['level_label'].' : ');
    else $level_label = '';
    
    // if level 0 we add page break
    if ($level['level_parent'] == 0) {
        $section->addTextBreak(null, null, $pageBreak);
        $section->addTextBreak(4);
    }
    else $section->addTextBreak(4);
    $section->addTitle(esc(mb_ucfirst(do_strip($level_label . $level['level_name']))), $bookmark_level);
    $section->addTextBreak(2);
    
    
    if ($report_settings['firstlevel_description'] === true && $level['level_parent'] == 0) {
        
        if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(cleanHTMLList(fixImageWidth($level['level_desc_project']))));
        else $section->addText(esc(do_strip($level['level_desc_project'])), 'defaultF', 'defaultP');
        
        // because $section->addPageBreak(); does not work in current version
        $section->addTextBreak(null, null, $pageBreak);
    } else {
        $section->addTextBreak(2);
    }
    
}


/********************************************************************************************
 *
* Following functions are used to generate dashboard reports
*
********************************************************************************************/

if(!function_exists('indicator_recursive')) {
    function indicator_recursive($levels, $bookmark_level) {
        
        global $ordered_items;
        global $sdi;
        global $section;
        global $report_settings;
        global $pageBreak;
        
        $debug = false;
        
        // we retrieve all root levels if not given - when first run
        if($levels === null) $levels = $GLOBALS['sql_object']->DBSelect(SQL_getLevelsList(true));
        
        // if($debug) print_r($levels);
        
        // for each root level ...
        foreach($levels as $l) {
            
            // on affiche ici le nom du thèmes
            // et la description si demandée
            if($debug) echo "<h1>". $l['level_name'] . "</h1><p>". $l['level_desc_dashboard'] . "</p><br /><br />";
            
            // if ($report_settings['levels'] ==  true) indicator_display_level($l, $bookmark_level, $section);
            
            // if there is action related to current level we display them
            // first we prepare them
            $associated_indicators = array();
            foreach($sdi as $indicator) {
                if($indicator['sdii_level'] == $l['level_id']) {
                    if($debug) echo "on affiche l'indicateur ". $indicator['sdii_id'] ." (indic-level-id".$indicator['sdii_level']. ") associé directement à ". $l['level_id']."<br />\n<br />\n";
                    array_push($associated_indicators, $indicator);
                    array_push($ordered_items, $indicator);
                }
            }
            
            // we get levels children
            $levelschildren = getLevelChildren($GLOBALS['sql_object']->DBSelect(SQL_getLevelsList()), $l['level_id']);
            if($debug) echo "<h1>----- Here are children -----</h1>";
            if($debug) print_r($levelschildren);
            
            // we display level if they have associated indicators or children levels and or we we display empty levels
            if($report_settings['levels'] ==  true && (count($associated_indicators) > 0 || count($levelschildren) > 0 || $report_settings['display_empty_levels'] ===  true)) {
                indicator_display_level($l, $bookmark_level, $section);
            }
            
            // we display indicator if any
            if(count($associated_indicators) > 0) {
                
                $associated_indicators = sort_indicators($associated_indicators);
                
                foreach($associated_indicators as $indicator) indicator_display_by_levels($indicator,$bookmark_level, $section);
            }
            
            
            
            if(count($levelschildren) > 0 ) indicator_recursive($levelschildren, $bookmark_level+1, $section);
            
        }
        
        
    }
}

function sort_indicators($indicators) {
    
    // we init values each time we iterate
    $indicator_range = array();
    $indicator_name = array();
    
    // First we prepare multi-sort
    // @see http://php.net/manual/fr/function.array-multisort.php
    foreach ($indicators as $key => $row) {
        $indicator_range[$key] = $row['sdii_range'];
        $indicator_name[$key] = $row['sdii_name'];
    }
    
    array_multisort($indicator_range, SORT_ASC, $indicator_name, SORT_ASC, $indicators);
    
    return $indicators;
    
}


function display_orphan_indicators ($bookmark_level) {
    
    global $ordered_items;
    global $sdi;
    global $section;
    global $report_settings;
    
    $associated_indicators = array();
    foreach($sdi as $i) {
        if($i['sdii_level'] == 0) {
            array_push($associated_indicators, $i);
            array_push($ordered_items, $i);
        }
    }
    
    if(count($associated_indicators) < 1) return false;
    
    if ($report_settings['levels'] ==  true) {
        $section->addTitle(esc(do_strip(_t('report', 'no-first-level'))), $bookmark_level);
        $section->addTextBreak(2);
    }
    
    $associated_indicators = sort_indicators($associated_indicators);
    foreach($associated_indicators as $ind) indicator_display_by_levels($ind,$bookmark_level, $section);
    
    return true;
    
}

/**
 * indicator_display_by_levels()
 * Affiche les infos générales d'un projet
 *
 * @param int $pointer
 * @return bool true
 */
if(!function_exists('indicator_display_by_levels')) {
    function indicator_display_by_levels($indicator, $bookmark_level, $section)
    {
        
        global $report_settings;
        global $pageBreak;
        
        if(defined('EXPORT_LOG') && EXPORT_LOG == 1) file_put_contents('../tmp/export-logs/word-indicators.txt', $indicator['sdii_id']."\n", FILE_APPEND);
        
        // we override dynamic $bookmark_level
        if($report_settings['levels'] ==  false) $bookmark_level = 0;
        
        indicator_display_main($indicator, $bookmark_level);
        indicator_display_values($indicator['sdii_id'], $bookmark_level);
        if ($report_settings['display_provider'] === true) indicator_display_provider($indicator, $bookmark_level);
        if ($report_settings['display_reglementation'] === true) indicator_display_rules($indicator, $bookmark_level);
        if ($report_settings['display_evaluation'] === true) indicator_display_assessment($indicator, $bookmark_level);
        
        
        // because $section->addPageBreak(); does not work in current version
        // we add page only if this is not a quick export
        if($report_settings['quick_export'] === false) $section->addTextBreak(null, null, $pageBreak);
        
        return true;
    }
}


/**
 * indicator_display_level()
 * display level as chapter
 * @param string $level
 */
function indicator_display_level($level, $bookmark_level, $section)
{
    
    // global $section;
    global $report_settings;
    global $pageBreak;
    // global $bookmark_level;
    
    if(!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0) $level_label = $level['level_label'].' : ';
    else $level_label = '';
    
    // if level 0 we add page break
    if ($level['level_parent'] == 0) {
        $section->addTextBreak(null, null, $pageBreak);
        $section->addTextBreak(4);
    }
    else $section->addTextBreak(4);
    $section->addTitle(mb_ucfirst(esc(do_strip($level_label.$level['level_name']))), $bookmark_level);
    $section->addTextBreak(2);
    
    
    if ($report_settings['firstlevel_description'] === true && $level['level_parent'] == 0) {
        
        if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(cleanHTMLList(fixImageWidth($level['level_desc_dashboard']))));
        else $section->addText(esc(do_strip($level['level_desc_dashboard'])), 'defaultF', 'defaultP');
        
        // because $section->addPageBreak(); does not work in current version
        $section->addTextBreak(null, null, $pageBreak);
    } else {
        $section->addTextBreak(2);
    }
    
}

/**
 * indicator_display_main()
 * Affiche les infos générales d'un IDD
 *
 * @param int $current_record
 * @return bool true
 */
function indicator_display_main($current_record, $bookmark_level)
{
  global $section;
  global $report_settings;

  // titre d'un indicateur
  $out_title = formatText($current_record['sdii_name']);

  // si non publié
  if ($current_record['sdii_statut'] == 'D') {
    $out_title .= ' / ' . strtolower(_t('statut', 'draftpdf'));
  }
  // si non attaché au tableau de bord
  if ($current_record['sdii_to_dashboard'] == 'Y') {
  	$out_title .= ' (' . strtolower(_t('sdi', 'attached_to_dashboard').')');
  }
  
  $section->addTitle(esc($out_title), $bookmark_level+1);
  
  // affichage du type si existant
  if($current_record['sdii_type'] != 'not-set') {
      
      if($current_record['sdii_type'] == 'state') $out_type = ' <span style="background-color:pink; color: rgb(255, 255, 255);font-size:11px;">&nbsp;'.mb_ucfirst($GLOBALS['lang']['sdi']['select_type'][$current_record['sdii_type']]).'&nbsp;</span>';
      if($current_record['sdii_type'] == 'follow-up' || $current_record['sdii_type'] == 'pressure') $out_type = ' <span style="background-color: #87d9ba; color:#4f8872;font-size:11px;">&nbsp;'.mb_ucfirst($GLOBALS['lang']['sdi']['select_type'][$current_record['sdii_type']]).'&nbsp;</span>';
      if($current_record['sdii_type'] == 'achievement' || $current_record['sdii_type'] == 'response') $out_type = ' <span style="background-color:#bfa8d5; color:#595a9f;font-size:11px;">&nbsp;'.mb_ucfirst($GLOBALS['lang']['sdi']['select_type'][$current_record['sdii_type']]).'&nbsp;</span>';

      \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText($out_type));
  }
  
  // thème d'appartenance
  if ($report_settings['levels'] !==  true) {
      if($current_record['sdii_level'] == 0) $level_name = mb_ucfirst(_t('sdi', 'no_associated_level'));
      else $level_name = mb_ucfirst($current_record['level_name']);
      if($current_record['sdii_level'] != 0 && (!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0)) $out_level = formatText('» ' . mb_ucfirst($current_record['level_label']). ' : ' . $level_name);
      else $out_level = $out_level = formatText('» ' . $level_name );

      // we retrieve root level
      $levels = $GLOBALS['sql_object']->DBSelect(SQL_getLevelsList());
      $a = getLevelParent($levels, $current_record['level_id'], 0);
      if(is_array($a) && $a['id'] != $current_record['level_id']) {
          if(!defined('EXPORT_NOLEVELLABEL') || EXPORT_NOLEVELLABEL == 0) $out_level .=  ' / ' .formatText( mb_ucfirst($a['label']) . ' : ' . $a['name']) . PHP_EOL;
          else $out_level .=  ' / ' .formatText($a['name']) . PHP_EOL;
          
      }
      
      $section->addText(esc(do_strip($out_level)), 'attachedTheme');
      $section->addTextBreak(1);
  }
  
  // description
  $out_desc = formatText(do_strip($current_record['sdii_description'])) . PHP_EOL;
  
  if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdii_description'] = removeDomElement('img', $current_record['sdii_description']);
  if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['sdii_description'])))));
  else $section->addText(esc($out_desc), 'defaultF', 'defaultP');
  
  $section->addTextBreak(1);
  
  // objectif
  if(!empty($current_record['sdii_goal'])) {
      $out_goal = formatText(empty_nc(do_strip($current_record['sdii_goal']))) . PHP_EOL;
      $out_goal_item = formatText(esc(mb_ucfirst(strip_tags(_t('sdi', 'goal')))));
      // $section->addTitle($out_goal_item, $bookmark_level+2);
      
      if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdii_goal'] = removeDomElement('img', $current_record['sdii_goal']);
      if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['sdii_goal'])))));
      else $section->addText(esc($out_goal), 'defaultF', 'defaultP');
    
      $section->addTextBreak(1);
  }
  
  // conseil d'amélioration
  if(!empty($current_record['sdii_consulting'])) {
      $out_consulting = formatText(empty_nc(do_strip($current_record['sdii_consulting']))) . PHP_EOL;
      $out_consulting_item = formatText(esc(mb_ucfirst(strip_tags(_t('sdi', 'consulting')))));
      // $section->addTitle($out_consulting_item, $bookmark_level+2);
      
      if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdii_consulting'] = removeDomElement('img', $current_record['sdii_consulting']);
      if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['sdii_consulting'])))));
      else $section->addText(esc($out_consulting), 'defaultF', 'defaultP');
      
      $section->addTextBreak(1);
  }
  
  // comment only if EXPLICITLY called
  if(defined('EXPORT_COMMENT') && (stripos(EXPORT_COMMENT, 'indicator') !== false) && !empty($current_record['sdii_comment'])) {

      // we remove default values entered between {}
      $current_record['sdii_comment'] = preg_replace('/{[\s\S]+?}/', '', $current_record['sdii_comment']);

      $out_comment = formatText(empty_nc(do_strip($current_record['sdii_comment']))) . PHP_EOL;
      $out_comment_item = formatText(mb_ucfirst(strip_tags(_t('sdi', 'comment'))));

      
      if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdii_comment'] = removeDomElement('img', $current_record['sdii_comment']);

      if(strlen($out_comment) > 6) {
          $section->addTitle(do_strip($out_comment_item), ($bookmark_level + 2));
          if (defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($section, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['sdii_comment'])))));
          else $section->addText(esc($out_comment), 'defaultF', 'defaultP');
      }
      
      $section->addTextBreak(1);
  }

  // informations de mesure
  $out_mesures_item = formatText(ucfirst(strip_tags(_t('sdi', 'info_mesure'))));
  $out_mesures_behavior = ($current_record['sdii_threshold_relative'] == 'Y' ? _t('sdi', 'threshold_relative_Y'): _t('sdi', 'threshold_relative_N'));
  $out_mesures_unit = formatText(mb_ucfirst(_t('sdi', 'unit'))) . ' : ' . $current_record['sdii_unit'] . PHP_EOL;
  // $section->addTitle($out_mesures_item, $bookmark_level+2);


  // unitée de mesure
  $section->addText(esc($out_mesures_unit));
  // $section->addTextBreak(1);
 
  // tableau de valeurs
  indicator_display_mesures($current_record);
  // comportement
  $section->addText(esc(mb_ucfirst($out_mesures_behavior)), array('size' => FONT_SIZE_MIN, 'italic' => true, 'color' => '555555'), array('align' => 'right'));
  $section->addTextBreak(2);
}

/**
 * indicator_display_mesures()
 * Dessine le tableau des valeurs IDD
 *
 * @param  $current_record
 * @return bool true
 */
function indicator_display_mesures($current_record)
{

  global $section;
  global $phpWord;
  global $cellalign;
  global $cellHeaderStyle;
  global $styleTable;
  global $firstRowStyle;
  
  $a = getBooleanValues($current_record);
  
  // if indicator is boolean or qualitative and mask is defined
  if(($current_record['sdii_nature'] == 'boolean' || $current_record['sdii_nature'] == 'qualitative') && $a) {
	  if($a) {
	  		$index = array();
	  		foreach ($a as $key => $value) {
	  			array_push($index, $key);
	  		}
	  	
	  		$display_minvalue = $a[min($index)];
	  		$display_maxvalue = $a[max($index)];
	  		($current_record['sdii_threshold_value'] != '') ? $display_threshold = $a[$current_record['sdii_threshold_value']] : $display_threshold = empty_nc('');
	  	} 
  } else {
  	$display_minvalue = empty_nc($current_record['sdii_min_value']);
  	$display_maxvalue = empty_nc($current_record['sdii_max_value']);
  	$display_threshold = empty_none(fnumber_format($current_record['sdii_threshold_value'], 'auto', false));
  	 
  }
  
  $fStyle = array('size' => FONT_SIZE_MIN);
  $cStyle = array('align' => 'center');
  
  $phpWord->addTableStyle('units', $styleTable, $firstRowStyle);
  $table = $section->addTable('units');
  

	// row 1 - header
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('sdi', 'min_value')))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('sdi', 'max_value')))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('sdi', 'initial_threshold_value')))), 'arrayHeader', $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellHeaderStyle)->addText(esc(mb_ucfirst(strip_tags(_t('sdi', 'frequency')))), 'arrayHeader', $cStyle);
	
	// row 2
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText($display_minvalue, $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText($display_maxvalue, $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText($display_threshold, $fStyle, $cStyle);
	$row->addCell(PAGE_WIDTH / 4, $cellalign)->addText($current_record['sdii_frequency'], $fStyle, $cStyle);
	
	$section->addTextBreak(1);
	
  return true;
}

/**
 * indicator_display_provider()
 * Affiche les informations Fournisseurs d'un IDD
 *
 * @param  $current_record
 * @return bool true
 */
function indicator_display_provider($current_record, $bookmark_level)
{
  global $section;
  
  // no information is given, we do not display the section
  if(empty($current_record['sdip_name']) && empty($current_record['sdip_service']) && empty($current_record['sdip_incharge']) && empty($current_record['sdip_email'])) return true;
  
  $lwidth = 0.29;

  $out_name = formatText($current_record['sdip_name']);
  if (!empty($current_record['sdip_service'])) $out_name .= ' - ' . formatText($current_record['sdip_service']);
  if (!empty($current_record['sdip_incharge'])) $out_name .= ' - ' . formatText($current_record['sdip_incharge']) . ' (' . _t('sdi', 'p_incharge') . ')';
  $out_adress = formatText(empty_nc(esc(do_strip($current_record['sdip_address']))));
  $out_phone_fax = mb_ucfirst(strip_tags(_t('sdi', 'p_phone'))) . ' : ' . formatText(esc(empty_nc($current_record['sdip_phone'])));
  $out_phone_fax .= ' - ' . mb_ucfirst(strip_tags(_t('sdi', 'p_fax'))) . ' : ' . formatText(esc(empty_nc($current_record['sdip_fax'])));
  $out_email_item = mb_ucfirst(esc(strip_tags(_t('sdi', 'p_email'))) . ' : ');
  $out_email = formatText(esc($current_record['sdip_email']));
  $out_desc = formatText(empty_nc(esc(do_strip($current_record['sdip_description']))));
  $out_provider_item = formatText(esc(ucfirst(strip_tags(_t('sdi', 'p_title'))))) ;

  // $section->addTitle($out_provider_item, $bookmark_level+2);
  
  $styleTable = array('cellMargin' => 50);
  $table = $section->addTable($styleTable);
  
  $fStyle = array();
  $clStyle = array('align' => 'right');
  $crStyle = array('align' => 'left');
  
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH * $lwidth)->addText('');
  $row->addCell(PAGE_WIDTH * (1 - $lwidth))->addText(esc(do_strip($out_name)), $fStyle, $crStyle);
  
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH * $lwidth)->addText('');
  $s = $row->addCell(PAGE_WIDTH * (1 - $lwidth));
  
  if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdip_address'] = removeDomElement('img', $current_record['sdip_address']);
  if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($s, formatText(empty_nc(cleanHTMLList(fixImageWidth($current_record['sdip_address'])))));
  else $s->addText($out_adress, $fStyle, $crStyle);
  
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH * $lwidth)->addText('');
  $row->addCell(PAGE_WIDTH * (1 - $lwidth))->addText($out_phone_fax, $fStyle, $crStyle);
  
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH * $lwidth)->addText('');
  $cell = $row->addCell(PAGE_WIDTH * (1 - $lwidth));
  $textrun = $cell->addTextRun();
  $textrun->addText($out_email_item, $fStyle);
	if (empty($out_email)) {
		$textrun->addText(empty_nc($out_email), $fStyle);
	} else {
		$textrun->addLink('mailto:' . $out_email, $out_email, $fStyle);
	}

	$section->addTextBreak(1);

  return true;
}

/**
 * indicator_display_rules()
 * Affiche la réglementation d'un IDD
 *
 * @param  $current_record
 * @return bool true
 */
function indicator_display_rules($current_record, $bookmark_level)
{
  global $section;
  
  // no information is given, we do not display the section
  if(empty($current_record['sdir_title']) && empty($current_record['sdir_body']) && empty($current_record['sdir_mask_uri'])) return true;
  
  
  $lwidth = 0.29;

  $out_name = formatText(empty_nc(esc(do_strip($current_record['sdir_title'])))) . PHP_EOL;
  $out_body = formatText(empty_nc(esc(do_strip($current_record['sdir_body'])))) . PHP_EOL;
  $out_uri = formatText(esc(do_strip($current_record['sdir_mask_uri'])));
  $out_uri_href = esc(do_strip($current_record['sdir_referer_uri']));

  $out_name_item = mb_ucfirst(esc(strip_tags(_t('sdi', 'r_title'))) . ' : ');
  $out_body_item = mb_ucfirst(esc(strip_tags(_t('sdi', 'r_body'))) . ' : ');
  $out_uri_item = mb_ucfirst(esc(strip_tags(_t('sdi', 'r_referer_uri'))) . ' : ');
  

  $out_reglementation_item = formatText(esc(ucfirst(strip_tags(_t('sdi', 'add_step4')))));

  // $section->addTitle($out_reglementation_item, $bookmark_level+2);
  
  $styleTable = array('cellMargin' => 50);
  $table = $section->addTable($styleTable);

	$fStyle = array();
	$clStyle = array('align' => 'right');
	$crStyle = array('align' => 'left');

	// nom de l'organisme fournisseur
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH * $lwidth)->addText($out_name_item, 'softLabel', $clStyle);
	$row->addCell(PAGE_WIDTH  * (1 - $lwidth))->addText($out_name, $fStyle, $crStyle);

  // détail reglementation
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH * $lwidth)->addText($out_body_item, 'softLabel', $clStyle);
	$s = $row->addCell(PAGE_WIDTH  * (1 - $lwidth));
	
	if(defined('EXPORT_NOIMAGE') && EXPORT_NOIMAGE == 1)  $current_record['sdir_body'] = removeDomElement('img', $current_record['sdir_body']);
	if(defined('HTML_EXPORT') && HTML_EXPORT == 1) \PhpOffice\PhpWord\Shared\Html::addHtml($s, formatText(cleanHTMLList(empty_nc(fixImageWidth($current_record['sdir_body'])))));
	else $s->addText($out_body, $fStyle, $crStyle);
	
  // lien internet reglementation
	$row = $table->addRow();
	$row->addCell(PAGE_WIDTH * $lwidth)->addText($out_uri_item, 'softLabel', $clStyle);
	if (!empty($out_uri_href)) {
		if (!empty($out_uri)) $row->addCell(PAGE_WIDTH  * (1 - $lwidth))->addLink($out_uri_href, $out_uri, $fStyle);
		else $row->addCell(PAGE_WIDTH  * (1 - $lwidth))->addLink($out_uri_href, $out_uri_href, $fStyle);
	} else {
		$row->addCell(PAGE_WIDTH  * (1 - $lwidth))->addText(empty_nc(''), $fStyle, $crStyle);
	}
	
	$section->addTextBreak(1);
	
  return true;
}

/**
 * indicator_display_assessment()
 * Affiche le tableau de critères d'évaluation
 *
 * @param int $current_record
 * @return bool true
 */
function indicator_display_assessment($current_record, $bookmark_level)
{
  global $section;
  global $phpWord;
  global $cellalign;
  global $cellHeaderStyle;
  global $styleTable;
  global $firstRowStyle;

  // no information is given, we do not display the section
  if($current_record['sdie_scale_compare'] == 0 && $current_record['sdie_fiability'] == 0 && $current_record['sdie_accessibility'] == 0 && $current_record['sdie_lisibility'] == 0 && $current_record['sdie_relevance'] == 0 && $current_record['sdie_global_performance'] == 0) return true;
  
  
  $out_eval_item = formatText(mb_ucfirst(_t('sdi', 'e_title'))) ;


  // $section->addTitle($out_eval_item, $bookmark_level+2);

  
  $phpWord->addTableStyle('evaluation', $styleTable, $firstRowStyle);
  $table = $section->addTable('evaluation');
  
  $fStyle = array('size' => FONT_SIZE_MIN);
  $cStyle = array('align' => 'center');
  
  // header
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_scale_compare')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_fiability')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_accessibility')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_lisibility')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_relevance')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'e_global_performance')))), 'arrayHeader', $cStyle);
  
  // values
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_scale_compare']), $fStyle, $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_fiability']), $fStyle, $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_accessibility']), $fStyle, $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_lisibility']), $fStyle, $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_relevance']), $fStyle, $cStyle);
  $row->addCell(PAGE_WIDTH / 6, $cellalign)->addText(zero_asNC($current_record['sdie_global_performance']), $fStyle, $cStyle);

  $section->addTextBreak(1);

  return true;
}


/**
 * indicator_display_values()
 * Affiche les valeurs d'un IDD.
 *
 * @param int $sdi_id
 * @return bool true
 **/
 
if(!function_exists('indicator_display_values')) {
	
	function indicator_display_values($sdi_id, $bookmark_level)
	{

	  global $section;
	  global $report_settings;
	  global $scale_array;
	  global $sql_object;
	  global $scale_denomination_array;

	  if(count($scale_array) == 0) return true;
	  
	  if ($report_settings['graphic_values'] === true && $report_settings['table_values'] === true) $mode = 'TWICE';
	  elseif ($report_settings['graphic_values'] === true || $report_settings['table_values'] === true) $mode = 'ONE';
	  else return false;

	  $out_values_item = mb_ucfirst(esc(_t('dashboard', 'all_value')));
	  
	  // $section->addTitle($out_values_item, $bookmark_level+2);

	  $scale_no_values = array(); // recipient no values
	  $scale_insuffisant_values = array(); // recipient insuffisant values graph


	  for($i = 0; $i < count($scale_array); $i++) {

		// we print chart if asked
		if ($report_settings['graphic_values'] === true) {
		  if (indicator_display_graphic_values($sdi_id, $scale_array[$i], indicator_get_status($report_settings['status']), $mode) === false) array_push($scale_insuffisant_values, $scale_array[$i]);
		}

		// we print values if asked
		if ($report_settings['table_values'] === true) {
			if (indicator_table_values($sdi_id, $scale_array[$i], indicator_get_status($report_settings['status']), $mode) === false) array_push($scale_no_values, $scale_array[$i]);
		}

	  }
	  indicator_no_values_for($scale_no_values, _t('report', 'no_values_for'));
	  indicator_no_values_for($scale_insuffisant_values, _t('report', 'insuffisant_values'), $mode, $scale_no_values);

	  return true;
	}
	
}


/**
 * indicator_get_status()
 * Formattage du statut pour requête SQL
 *
 * @param string $current_status
 * @return string $status
 **/
function indicator_get_status($current_status)
{
  switch ($current_status) {
    case 'ALL':
      $status = 'SCA';
      break;
    case 'PUBLIC':
      $status = 'SCP';
      break;
  }
  return $status;
}

/**
 * indicator_no_values_for()
 * Affiche les échelles ne contenant pas de valeurs ou insuffisamment
 *
 * @param array $array_scale
 * @param string $message
 * @param integer $mode
 * @param integer $array
 * @return bool true
 **/
function indicator_no_values_for($array_scale, $message, $mode = -1, $array = -1)
{
  global $section;
  global $scale_denomination_array;
  $content = '';
  $sep = '';
  // si mode TWICE et deuxième tableau fourni. On le soustrait au premier.
  if ($array != -1 && $mode == 'TWICE') $array_scale = array_values(array_diff($array_scale, $array));

  if (count($array_scale) == 0) return true;

  for($i = 0; $i < count($array_scale); $i++) {
    $content .= $sep . $scale_denomination_array[$array_scale[$i]];
    $sep = ', ';
  }
  if (empty($content)) return true;
  
  $textrun = $section->addTextRun();
  $textrun->addText(esc($message), 'noValueFor');
  $textrun->addText(esc($content), array());
  $section->addTextBreak(1);

  return true;
}

/**
 * indicator_display_graphic_values()
 * Gènère et affiche les valeurs sous forme graphique
 *
 * @param int $sdi_id
 * @param int $current_scale
 * @param string $status
 * @param string $mode
 * @return bool true
 **/
if(!function_exists('indicator_display_graphic_values')) {
	function indicator_display_graphic_values($sdi_id, $current_scale, $status, $mode)
	{
		global $section;
		global $sql_object;
		global $scale_denomination_array;
		
		// getting chart sizes
		list($width, $height) = explode('x', CHART_DEFAULT_SIZE);
		
		// We retrieve indicator type to see if we generate graph or not
		$result_sdii = $sql_object -> DBSelect(SQL_getInfoSdi($sdi_id));
		$indicator_type = $result_sdii[0]['sdii_nature'];
		

		include_once(override('../dashboard/graph.php'));
		
		$values = $sql_object->DBSelect(SQL_getAllValue($status, $current_scale, $sdi_id));
		
	// 	// renversement des valeurs pour affichage chronologique
	// 	if(is_array($values)) $values = @array_reverse ($values, false);

	// 	$result_sdii = $sql_object->DBSelect(SQL_getInfoSdi($sdi_id));

		if(defined('CHART_MIN_VALUES') && is_numeric(CHART_MIN_VALUES)) $minChartValues = CHART_MIN_VALUES; else $minChartValues = 2;
		
		if (!is_array($values) || count($values) < $minChartValues) 	return false;
		
		if($indicator_type == 'quantitative') {

			generateGraphic($sdi_id, $current_scale, $status, 'auto', false, $width, $height, '../tmp/report');
			
			// /////////////////////////////
			// Affichage
			
			// Affichage du titre de l'échelle s'il n'y en a plus d'une seulement
			if(count($scale_denomination_array) > 1) {
    			$out_scale_item = $scale_denomination_array[$current_scale];
    			$scaleStyle = array('bold' => true);
    			$section->addText($out_scale_item, $scaleStyle);
			}
			
			// Affichage de l'image
			$section->addImage('../tmp/report/'.$sdi_id.'_'.$current_scale.'.png', array('align' => 'center', 'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(12)));
		
			$section->addTextBreak(1);
		}
		
		if($indicator_type == 'qualitative') {
			indicator_display_qualitative_array($values,$result_sdii[0]);	
		}

		return true;
		
	}
}

/**
 * indicator_display_qualitative_array()
 * Dessine le tableau des valeurs qualitatives
 *
 * @param  $current_record
 * @return bool true
 */
function indicator_display_qualitative_array($values, $current_record, $dateFormat = 'short') {

	global $section;
	global $phpWord;

	$a = getBooleanValues($current_record);
	// get get color ramp
	$colors = getColorRamp($a);
	

	$styleTableQ = array('borderSize' => 0, 'borderColor' => 'ffffff',  'cellMargin' => 25, 'width' => 100);
	$firstRowStyle = array('bgColor' => ARRAY_HEADER_BG);
	
	$cStyle = array('align' => 'center', 'color' => '777777', 'size' => FONT_SIZE_MIN);
	
	
	$total = count($values);
	// if there is no result we quit the function
	if(!isset($values[0]['sdiv_value'])) return false;
	
	$section->addTextBreak(1);
	$phpWord->addTableStyle('qualitative-viz', $styleTableQ, $firstRowStyle);
	$table = $section->addTable('qualitative-viz');
	
		
	$values = array_reverse($values);
	
	// row 1 - header
	$row = $table->addRow();
	foreach ($values as $entry) {
		if($dateFormat == 'short') $date = substr(formatDate($entry['date_p'], true), 0, 4);
		else $date = $entry['date_p'];
		$row->addCell(PAGE_WIDTH / $total, array())->addText(esc($date), $cStyle, array('align' => 'center'));
		
	}
	// row 2
	$row = $table->addRow();
	foreach ($values as $entry) {
		$fStyle = array('size' => FONT_SIZE_MIN, 'color' => $colors[$entry['sdiv_value']]['color']);
		$c2Style = array('align' => 'center', 'bgColor' => $colors[$entry['sdiv_value']]['background-color']);
		$row->addCell(PAGE_WIDTH / $total, $c2Style)->addText("\n\n".esc($a[$entry['sdiv_value']])."\n\n", $fStyle, array('align'=> 'center'));
	}
	
	$section->addTextBreak(2);
	
	// adding legend
	$table = $section->addTable('qualitative-viz-legend');
	$row = $table->addRow();
	for($i=0; $i<count($a); $i++) {
		$legendColorStyle = array('align' => 'center', 'bgColor' => $colors[$i]['background-color']);
		$row->addCell(PAGE_WIDTH / (count($a)*8), $legendColorStyle);
		$row->addCell(PAGE_WIDTH / (count($a)*1.7), array())->addText(esc($a[$i]), $cStyle, array('align' => 'left'));
	}
	$section->addTextBreak(2);

	return true;
}

/**
 * indicator_table_values()
 * Affiche un tableau de valeurs a une échelle donnée
 *
 * @param int $sdi_id
 * @param int $current_scale
 * @param string $status
 * @param string $mode
 * @return bool true
 **/
function indicator_table_values($sdi_id, $current_scale, $status, $mode)
{
	
	global $section;
	global $phpWord;
	global $sql_object;
	global $scale_denomination_array;
	global $cellalign;
	global $cellHeaderStyle;
	global $styleTable;
	global $firstRowStyle;

	$values = array();

	
	// setting $default_threshold value
	// By default initial value
	$result_sdii = $sql_object -> DBSelect(SQL_getInfoSdi($sdi_id));
	$default_threshold = $result_sdii[0]['sdii_threshold_value'];

    if($result_sdii[0]['sdii_multiple_type'] == 'sum') $cfield = '_total';
    if($result_sdii[0]['sdii_multiple_type'] == 'mean') $cfield = '_mean';

	$sdi_values = $sql_object->DBSelect(SQL_getAllValue($status, $current_scale, $sdi_id));
    $sdi_values = add_cumulative_value($sdi_values, $result_sdii[0]); // we add 'sdiv_cumulative_value' attribute if needed
	

	if (!is_array($sdi_values) || count($sdi_values) < 1) return false;

	// we prepare values for displaying
	for($i = 0; $i < count($sdi_values); $i++) {

		if(!empty($sdi_values[$i]['sdiv_multivalue'])) {

			$data = unserialize($sdi_values[$i]['sdiv_multivalue']);
			$current_value = $data;

            if($result_sdii[0]['sdii_multiple_type'] == 'none') {
                $firstValue = $lastValue = $year_end = $year_start = 0; // will return empty_nc()
            } else {
                if ($i == 0) {
                    $lastValue = $data[0][$cfield]; // we store data to compute TCAM and global rate
                    $year_end = substr(formatDate($sdi_values[$i]['date_p'], true), 0, 4);
                }
                if ($i == count($sdi_values) - 1) {
                    $firstValue = $data[$i][$cfield]; // we store data to compute TCAM and global rate
                    $year_start = substr(formatDate($sdi_values[$i]['date_p'], true), 0, 4);
                }
            }

		} else {
			
			$current_value = '';
			
			// If indicator is boolean or quantitative
			if($result_sdii[0]['sdii_nature'] == 'boolean' || $result_sdii[0]['sdii_nature'] == 'qualitative') {
				$a = getBooleanValues($result_sdii[0]);
				if($a) {
					$current_value .= $a[$sdi_values[$i]['sdiv_value']];
				} else {
					$current_value .= empty_none(fnumber_format($sdi_values[$i]['sdiv_value'], 'auto', false));
				}
				 
			} else {
                if(is_null($sdi_values[$i]['sdiv_value'])) {
                    $current_value .= mb_ucfirst(_t('dashboard', 'no_data'));
                } else {
                    $current_value .= fnumber_format($sdi_values[$i]['sdiv_value'], 'auto', false);
                }
				
				if($i == 0) {
					$lastValue = $sdi_values[$i]['sdiv_value']; // we store data to compute TCAM and global rate
					$year_end = substr(formatDate($sdi_values[$i]['date_p'], true), 0, 4);
				}
				if($i == count($sdi_values)-1) {
					$firstValue = $sdi_values[$i]['sdiv_value']; // we store data to compute TCAM and global rate
					$year_start = substr(formatDate($sdi_values[$i]['date_p'], true), 0, 4);
				}
			}
			
		}
		 
		// if set, we get it from the table
		if(!is_null($sdi_values[$i]['sdiv_threshold'])) {
			// If indicator is boolean or quantitative
			if($result_sdii[0]['sdii_nature'] == 'boolean' || $result_sdii[0]['sdii_nature'] == 'qualitative') {
				$threshold = $a[$sdi_values[$i]['sdiv_threshold']];
			} else {
				$threshold = empty_none(fnumber_format($sdi_values[$i]['sdiv_threshold'], 'auto', false));
			}
			
		} else {
			// If indicator is boolean or quantitative
			if($result_sdii[0]['sdii_nature'] == 'boolean' || $result_sdii[0]['sdii_nature'] == 'qualitative') {
				if(!is_null($default_threshold)) $threshold = $a[$default_threshold];
				else $threshold = empty_none('');
			} else {
			    $threshold = empty_none('');
			}
		}
		 
		if ($sdi_values[$i]['sdiv_statut'] == 'D') $current_value .= ' *';
		if (!empty($sdi_values[$i]['sdiv_comment'])) {
			if($sdi_values[$i]['sdiv_comment_display']=='Y') {
				$comment_status = _t('dashboard', 'public');
			} else {
				$comment_status = _t('dashboard', 'private');
			}
			
			$comments = formatText(do_strip($sdi_values[$i]['sdiv_comment'])) .' ('.$comment_status.')'.PHP_EOL;

		} else {
			$comments = '';
		}
		
		$current_date = formatText($sdi_values[$i]['date_p']);
		
		$values[$i]['current'] = $current_value; // we do not escape $current_value because it can be an array
		$values[$i]['threshold'] = esc($threshold);
		$values[$i]['date'] = esc($current_date);
		$values[$i]['comment'] = esc($comments);
        if(isset($sdi_values[$i]['sdiv_cumulative_value']))$values[$i]['cumulative_value'] =  esc($sdi_values[$i]['sdiv_cumulative_value']);

	}

	// Affichage des données
	
	// Affichage du titre seulement si affichage des valeurs en standalone
	// ou si la génération des graphiques est infaisables car moins de 2 valeurs
	if(defined('CHART_MIN_VALUES') && is_numeric(CHART_MIN_VALUES)) $minChartValues = CHART_MIN_VALUES; else $minChartValues = 2;
	
	if ($mode != 'TWICE' || (count($sdi_values) >= 1 && count($sdi_values) < $minChartValues)) {
	    
	    // Affichage du titre de l'échelle s'il n'y en a plus d'une seulement
	    if(count($scale_denomination_array) > 1) {
	       $out_scale_item = esc($scale_denomination_array[$current_scale]);
	       $scaleStyle = array('bold' => true);
	       $section->addText($out_scale_item, $scaleStyle);
	    }
	
	}
	
	// Affichage de l'astérisque - avertissement
	$section->addText(esc('* ' . strtolower(_t('statut', 'draftpdf')).' '), array('size' => FONT_SIZE_MIN, 'italic' => true, 'color' => '555555'), array('align' => 'right'));
	
	$phpWord->addTableStyle('values', $styleTable, $firstRowStyle);
	$table = $section->addTable('values');
	
	$fStyle = array('size' => FONT_SIZE_MIN);
  $cStyle = array('align' => 'center');
  $clStyle = array('align' => 'left');

  if($result_sdii[0]['sdii_value_type'] == 'unique' && $result_sdii[0]['sdii_unique_mode'] == 'cumulative') $colsWidth = [0.2, 0.2, 0.2, 0.2];
  else $colsWidth = [0.4, 0.2, 0.2, 0.2];

        // header
  $row = $table->addRow();
  $row->addCell(PAGE_WIDTH * $colsWidth[0], $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('dashboard', 'name_pluriel')))), 'arrayHeader', $cStyle);

  // we handle cumulative values
  if($result_sdii[0]['sdii_value_type'] == 'unique' && $result_sdii[0]['sdii_unique_mode'] == 'cumulative') $row->addCell(PAGE_WIDTH * $colsWidth[0], $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('dashboard', 'cumulative_value')))), 'arrayHeader', $cStyle);

  $row->addCell(PAGE_WIDTH * $colsWidth[1], $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('dashboard', 'threshold_value')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH * $colsWidth[2], $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('statut', 'published_on')))), 'arrayHeader', $cStyle);
  $row->addCell(PAGE_WIDTH * $colsWidth[3], $cellHeaderStyle)->addText(mb_ucfirst(esc(strip_tags(_t('sdi', 'comment')))), 'arrayHeader', $cStyle);
	
  // values
	foreach ($values as &$val) {
		$row = $table->addRow();
		
		$cell = $row->addCell(PAGE_WIDTH * $colsWidth[0], $cellalign);
		
		if(is_array($val['current'])) {
			foreach($val['current'] as &$el) {
			
				$textrun = $cell->addTextRun();
				
				if(!empty($el['label'])) $disp = mb_ucfirst($el['label']). ' : ';
                if(!is_null($el['value'])) $disp .= fnumber_format($val['value'], 'auto', false);
                else $disp .= mb_ucfirst(_t('dashboard', 'no_data'));
				
				$textrun->addText(esc($disp), 'arrayValue');
                if(!is_null($el['value'])) $textrun->addText(' ('.fnumber_format($el['_percentage'], 2, false).' %)', 'percentageValue');

			}
			// we display the total if needed
            if($result_sdii[0]['sdii_multiple_type'] == 'sum') {
                if(!is_null($val['current'][0]['_total'])) {
                    $cell->addText(mb_ucfirst(esc(_t('dashboard', 'multivalue_total')) . ' : ' . fnumber_format($val['current'][0]['_total'], 'auto', false)), array('size' => FONT_SIZE_MIN, 'bold' => true));
                } else {
                    $cell->addText(mb_ucfirst(esc(_t('dashboard', 'multivalue_total'))) . ' : ' . mb_ucfirst(_t('dashboard', 'no_data')), array('size' => FONT_SIZE_MIN, 'bold' => true));
                }
            }
            // we display the mean if needed
            if($result_sdii[0]['sdii_multiple_type'] == 'mean') {
                if(!is_null($val['current'][0]['_mean'])) {
                    $cell->addText(mb_ucfirst(esc(_t('dashboard', 'multivalue_mean')) . ' : ' . fnumber_format($val['current'][0]['_mean'], 2, false)), array('size' => FONT_SIZE_MIN, 'bold' => true));
                } else {
                    $cell->addText(mb_ucfirst(esc(_t('dashboard', 'multivalue_mean'))) . ' : ' . mb_ucfirst(_t('dashboard', 'no_data')), array('size' => FONT_SIZE_MIN, 'bold' => true));
                }
            }

		} else {
		    $cell->addText(esc($val['current']), 'arrayValue', $cStyle);
		}

        // we handle cumulative values
        if($result_sdii[0]['sdii_value_type'] == 'unique' && $result_sdii[0]['sdii_unique_mode'] == 'cumulative') $row->addCell(PAGE_WIDTH * $colsWidth[0], $cellalign)->addText(fnumber_format($val['cumulative_value'], 'auto', false), $fStyle, $cStyle);
		
		$row->addCell(PAGE_WIDTH * $colsWidth[1], $cellalign)->addText(esc($val['threshold']), $fStyle, $cStyle);
		$row->addCell(PAGE_WIDTH * $colsWidth[2], $cellalign)->addText(esc($val['date']), $fStyle, $cStyle);
		$row->addCell(PAGE_WIDTH * $colsWidth[3], $cellalign)->addText(esc($val['comment']), $fStyle, $clStyle);
	}
	
	// affichage des taux
	if($result_sdii[0]['sdii_nature'] == 'quantitative') {
		$rates = getRates($firstValue, $lastValue, $year_start, $year_end, 'txt');
		$section->addTextBreak(1);
		$section->addText(esc($rates), array('size' => FONT_SIZE_MIN, 'italic' => false));
	}
	$section->addTextBreak(2);
		
	return true;
}

/**
 * esc()
 * simply escape string
 * to prevent Word generation failure
 * @param string $str
 * @return string
 */
function esc( $str) {
    // to prevent fail when Word escaping is not set - see https://dev.linea21.com/issues/1154
    if(!defined('WORDEXPORT_ESCAPE') || WORDEXPORT_ESCAPE == 0) return htmlspecialchars($str);
    else return $str;
}

/**
 * do_strip()
 * @param string $content
 * @return string
 */
function do_strip($content, $force = false) {

	global $report_settings;
	
	$replace_array = array("\r\n", "\n\r", "\\r\\n", "\\n\\r", "\r", "\\r", "\\n");
	
	
	if($report_settings['export_format'] === 'html' && $force !== true) {
		
		return $content;
		
	} else { 
		
	    $converted = \Soundasleep\Html2Text::convert($content);
	
		// @see https://github.com/PHPOffice/PHPWord/issues/384
		// this will convert all "\n" to new lines when generating Word files
	    // @todo remove ? since we use new convert_html_to_text() function
		$str = str_replace($replace_array,"\n", $converted); // cleaning new line syntax
		$str = htmlspecialchars($str, ENT_NOQUOTES, CHARSET);
		$str = str_replace("\n", "</w:t><w:br/><w:t>", $str); // should be after htmlspecialchars()
		return $str;
	}
}


?>