<?php
/**
 * Project module
*
* Common functions used in back-office to
* displays filter options
*
* @package linea21\modules\project
* @author $Author$ - linea21 <info@linea21.com>
* @version $Id$
* @access public
* @license http://opensource.org/licenses/gpl-3.0.html
*/


function get_timeline_info() {
    
    if(!defined('PROJECT_TIMELINE')) return false;
    
    $elements = explode("|", strtolower(PROJECT_TIMELINE));
    
    $info = [];
    
    foreach ($elements as $el) {
        list($key, $value) = explode(":", $el);
        $info[$key] = $value;
    }
    return $info;    
}

/**
 * get_task_form()
 *
 * @param  int $task_id
 * @return string
 */
if(!function_exists('get_task_form')) {
    
    
    function get_task_form($project_id, $task_id = false, $form_values = array(), $err_msg = false) {
        
        $a = [];
        $a['user_id'] = $GLOBALS['l21auth']->GetSessionElement('id');
        
        $achieved = '';
        $reminder_last_date = '';
        
        // $project_id always exists even when Project does not exist yet in db 
        // a tmp id is given when project does not exist yet. See add.php page
        $a['project_id'] = $project_id;
        
        // we get given task if provided and populate field 
        if(is_numeric($task_id)) {
            $r = $GLOBALS['sql_object']->DBSelect(SQL_get_task($task_id));
            // print_r($r);
            $formname = 'edit-task';
            $title = _t('task','edit');
            
            $a['todo'] = 'edit';
            $a['id'] = $task_id;
            $a['label'] = $r[0]['task_label'];
            $a['status'] = $r[0]['task_status'];
            $a['reminder-f'] = $r[0]['task_reminder_freq'];
            $a['reminder-f-hidden'] = $r[0]['task_reminder_freq'];
            $a['reminder-last-date'] = $r[0]['task_reminder_lastdate'];
            $a['task_date_crea'] = $r[0]['task_date_crea_display'];
            $a['task_date_done'] = $r[0]['task_date_done_display'];

            if($r[0]['task_date_done'] != '0001-01-01 00:00:00') $achieved = '<br style="clear:both" /><span class="task-achieved">'. mb_ucfirst(_t('task', 'achieved_at')). ' '. $r[0]['task_date_done_display']. ' (' ._t('task', 'duration'). ' : ' .$r[0]['duration'] . ' '._t('task', 'months').')'.'<span>';
            
            if($r[0]['task_reminder_lastdate'] != '0001-01-01 00:00:00') $reminder_last_date = '<span class="task-reminder">'. sprintf(mb_ucfirst(_t('task', 'reminder_lastdate')), $r[0]['task_reminder_lastdate_display']).'</span>';
            
            if($a['reminder-f'] != 'NO REMINDER' && $a['status'] != 'done') {
                $res = $GLOBALS['sql_object']->DBSelect(SQL_get_next_reminder_date($a['id'], $a['reminder-f']));
                $reminder_last_date .= '<span class="task-reminder">('. sprintf(mb_ucfirst(_t('task', 'reminder_nextdate')), $res[0]['next_send']).')</span>';
            }

        }
        else { // we add a new record
            $formname = 'add-task';
            $title = _t('task','add');
            $a['todo'] = 'add';
            $a['label']="";
            $a['status'] = 'todo';
            $a['reminder-f'] = 'NO REMINDER';
            $a['reminder-f-hidden'] = $a['reminder-f'];
            
        }
        
        // form as been submited already, we populate it again with entered values
        if(!empty($form_values)) {
            $a['label'] = $form_values['label'];
            $a['status'] = $form_values['status'];
            $a['reminder-f'] = $form_values['reminder_freq'];
            $a['reminder-f-hidden'] = $form_values['reminder_freq_hidden'];
        }
        
        $otask = new projectTask();
        
        $select_reminders = TasksReminderSelectBox($otask->available_frequencies, 'task-reminder-f', $a['reminder-f']);
        $radio_status = TasksReminderStatusRadio($otask->available_status, 'task-status', $a['status']);
        
        // echo $a['project_id'];
        
        $form  = '<h2>'.$title.'</h2>'.PHP_EOL;
       
        if(is_string($err_msg)) $form .= '<div class="error">' . $err_msg . '</div>';

        $form .= '<form id="'.$formname.'" action="' . $_SERVER['SCRIPT_NAME']. '" method="post">';
        
        $form .= '<div class="">'.PHP_EOL;
        $form .= '<div class="grid-6-small-3">'.PHP_EOL;
        $form .= '<div><label for="task-label" class="label">'._t('task', 'label').': *<label></div>'.PHP_EOL;
        $form .= '<div class="col-5-small-2"><textarea name="task-label" id="task-label" maxlength="3500" class="largetextfield" '.AREA_SETTINGS.'>'.$a['label'].'</textarea></div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;
        
        $form .= '<div class="">'.PHP_EOL;
        $form .= '<div class="grid-6-small-3">'.PHP_EOL;
        $form .= '<div><div class="label">'._t('task', 'status').'&nbsp;:&nbsp;*</div></div>'.PHP_EOL;
        $form .= '<div class="col-5-small-2">'.$radio_status . $achieved.'</div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;

        // ability to modify task dates
        if($a['todo'] == 'edit') {
            $form .= '<div class="grid-6-small-3 mbm">'.PHP_EOL;
            $form .= '<div><div class="label">&nbsp;&nbsp;</div></div>'.PHP_EOL;
            $form .= '<div class="col-5-small-2">'.PHP_EOL;
            $form .= '<p><a href="#" class="change-date"><i class="fa fa-calendar-check-o" aria-hidden="true"></i> '._t('task', 'modify_dates').'</a></p>'.PHP_EOL;
            $form .= '<div class="change-date-container">'.PHP_EOL;
            $form .= '<label for="task_date_crea">'._t('task', 'date_start').'</label><input name="task_date_crea" type="text" value="'. $a['task_date_crea']. '" id="task_date_crea" />'.PHP_EOL;
            if($r[0]['task_date_done'] != '0001-01-01 00:00:00') $form .= '<label for="task_date_done">'._t('task', 'date_end').'</label><input  class="date-pick" name="task_date_done" type="text" value="'. $a['task_date_done']. '" id="task_date_done" />'.PHP_EOL;
            $form .= '</div>'.PHP_EOL;
            $form .= '</div>'.PHP_EOL;
            $form .= '</div>'.PHP_EOL;
        }



        
        $form .= '<div class="">'.PHP_EOL;
        $form .= '<div class="grid-6-small-3">'.PHP_EOL;
        $form .= '<div><label for="task-reminder-f" class="label">'._t('task', 'reminder_freq').'&nbsp;:&nbsp;*<label></div>'.PHP_EOL;
        $form .= '<div class="col-4-small-2">'.$select_reminders. $reminder_last_date . '<span class="task-reminder-info"><i class="fa fa-info-circle" aria-hidden="true"></i> '._t('task', 'reminder_freq_info').' </span></div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;
        $form .= '</div>'.PHP_EOL;
        
        $form .= '<input name="todo" type="hidden" value="'. $a['todo']. '" id="todo" />'.PHP_EOL;
        if($a['todo'] == 'edit') $form .= '<input name="id" type="hidden" value="'. $a['id']. '" id="is" />'.PHP_EOL;
        $form .= '<input name="user_id" type="hidden" value="'. $a['user_id']. '" id="user_id" />'.PHP_EOL;
        $form .= '<input name="task-reminder-f-hidden" type="hidden" value="'. $a['reminder-f-hidden']. '" id="task-reminder-f-hidden" />'.PHP_EOL;
        $form .= '<input name="pid" type="hidden" value="'. $a['project_id']. '" id="pid" />'.PHP_EOL;
        $form .= '<input name="annuler" type="button" value="' ._t('btn','annul').'" class="button" id="annuler" onclick="javascript:parent.$.colorbox.close();" />'.PHP_EOL;
        $form .= '<input name="valider" type="submit" value="'. _t('btn','valid'). '" class="button" id="valider" />'.PHP_EOL;
        $form .= '</form>'.PHP_EOL;
        
        $js = '<script>
                $(function() {
   
                    $("#task_date_crea, #task_date_done").fdatepicker({ 
								language: "'.U_L.'",
								format: "' .DATE_FORMAT .'"
					});
                    
                    $("input[type=radio]").change(function() {
                        $("#task-reminder-f-hidden").val($("#task-reminder-f option:selected").val()); // we update hidden field value with current value
                        var current = $("input[type=radio]:checked"). val();
                        // alert(current);
                        if (current == "todo") {
                            $("#task-reminder-f").prop("disabled", false);
                            $("span.task-reminder").css("opacity", 1);
                        }
                        else {
                            $("#task-reminder-f").prop("disabled", true);
                            $("span.task-reminder").css("opacity", 0.2);
                        }
                    });
                    $("input[type=radio]").trigger( "change" );
                    
                    $(".change-date").click(function() {
                        if($(".change-date-container").css("display") == "block") $(".change-date-container").hide();
                        else $(".change-date-container").show();
                        return false;
                    });
                    $(".change-date").trigger( "click" );
                });
            </script>';


        
        $form .= $js . PHP_EOL;
        
        return $form;
                
    }
}


/**
 * get_task_progress_bar()
 *
 * @param  integer $id
 * @return string
 */
if(!function_exists('get_task_progress_bar')) {
    
    function get_task_progress_bar($project_id, $report = false) {
        
        $r = $GLOBALS['sql_object']->DBSelect(SQL_get_project_tasks_count($project_id)); // we get all tasks
        
        if($r[0]['count'] == 0) return '<div id="progressbar-project-container" data-tasks-percentage="0"></div>';
        
        $d = $GLOBALS['sql_object']->DBSelect(SQL_get_project_tasks_count($project_id, array('done'))); // we get all done tasks
        if(!is_array($d)) $done = 0; else $done = $d[0]['count'];
        
        $value = round($done * 100 / $r[0]['count'], 0);
        
        $progresstext = sprintf('<span class="task-progress-text">'._t('task', 'progression').'</span>', $done, $r[0]['count'], $value);
        
        if($report) return strip_tags($progresstext);
        
        return sprintf('<div id="progressbar-project-container" data-tasks-percentage="%s"><div class="progressbar-finality" id="progressbar-project-%s"><div style="width: %s%%;"></div></div>%s</div>', $value, $project_id, $value, $progresstext);
        
    }
}



function get_task_status($status) {
    return $GLOBALS['lang']['task']['status_'.$status];
}

/**
 * get_tasks_for_report()
 *
 * @param  array $tasks
 * @return array
 */
if(!function_exists('get_tasks_for_report')) {
    
    function get_tasks_for_report($tasks = false)
    {
        $a = array();
        
        
        if(!is_array($tasks)) return $a;
        
        foreach ($tasks as $task) {
            
            $t = array();
            
            $t['status_raw'] = $task['task_status'];
            $t['status'] = get_task_status($task['task_status']);
            $t['label'] = formatText($task['task_label']);
            if($task['task_status'] == 'done') $t['done'] = mb_ucfirst(_t('task', 'achieved_at')). ' '. $task['task_date_done_display']. ' (' ._t('task', 'duration'). ' : ' .$task['duration'] . ' '._t('task', 'months').')';
            array_push($a, $t);
        }
        return $a;
    }
    
}

/**
 * format_tasks()
 *
 * @param  array $tasks
 * @return array
 */
if(!function_exists('format_tasks')) {
    
    function format_tasks($tasks = false, $edition = false)
    {
        $str ='';
        
        footerAddJS('../lib/js/jquery.nestable.js');
        
        $js = '$("body").on("scroll", "div.dd", function(e) { // necessary to bind dynamically nestable
				$("div.dd").nestable({listNodeName: "ul"}).on("change", function() {
                      var json_text = $("div.dd").nestable("serialize");
                      //console.log(json_text);
                      $.get("../admin/_ajax_sort.php", {
                        rub: "task",
                        "sort-table": json_text
                      }, function(data){
                      // console.log(data);
                        // replacing data.class by data["class"] for IE8 bug fix
					if(data["class"] == "succeed") {
						alertify.success(data.msg);
					} else {
						alertify.error(data.msg);
					}
                      }, "json");
                    });
                });
                $("div.dd").trigger("scroll");  // necessary to bind dynamically nestable';
        footerAddInlineJS($js);
        
        // we need to include JQuery even if empty because some elements can be added later
        if($edition) {
            $js = '
    
                    // to bind dynamic elements
                   $("body").on("click", "li.tasks a.edit-task", function(e) {
                        e.preventDefault();
    	                var cboxOptions = { href:$(this).attr("href"), iframe:true, innerWidth: "50%", innerHeight: "80%", maxWidth: "85%", maxHeight: "85%", onOpen: setColorBoxFlag("project-edit") }
                    	$(this).colorbox(cboxOptions);
                        // a bit complicated to handle alertify.success() message. Handle by colorbox on closed .... Code is in mod.php / add.php pages 
                    });
                
                    $("body").on("click", "ul.project-tasks a.ico_sup", function(e) {
                        $.ajax({
	                       url : $(this).attr("href"),
	                       type: "GET",
                           dataType: "json",
	                       success: function(data) {
                                if(data.status==1) {
                                  $(data.el).fadeOut("slow");
                                  $("#progressbar-project-container").replaceWith(data.htmlContent).hide().fadeOut();
        						  alertify.success(data.msg);
                                    // if on sync we update completion indicator
                                    if($("#project_progression_sync").length > 0) {
                    	                if($("#project_progression_sync").is(":checked")) {
                        	            	var  curval = $("#progressbar-project-container").attr("data-tasks-percentage");
                        	                // var rounded = Math.ceil(curval / '. PROJECT_STEP .') * '.PROJECT_STEP . ';
                        	                // console.log("Tasks SYNC / curval : " + curval + " - rounded : " + rounded);
                        	                $("#project_progression").val(curval);
                        	                displayValue(curval);
                        	            }
                                    }
        						} else {
        						  alertify.error(data.msg);
        						}
	      	               }
				        });
                        return false;
	    });';
            footerAddInlineJS($js);
        }
        
        if(!is_array($tasks)) return sprintf('<div class="dd"><ul class="project-tasks">%s</ul></div>', $str); // we return container for adding further task
        
        foreach ($tasks as $task) {
            $meta = mb_ucfirst(_t('divers', 'created_on')). ' '. $task['task_date_crea_display']. ' - ' .mb_ucfirst(_t('divers', 'last_modify')). ' '. $task['task_last_modify_display']. ' ' . _t('divers', 'by'). ' '. $task['user_login'];
            
            $str .= '<li class="tasks dd-item"  data-id="'.$task['task_id'].'" id="task-'.$task['task_id'].'">'.PHP_EOL;
            $str .= '<div class="dd-handle">&nbsp;</div>'.PHP_EOL;
            $str .= '<div class="dd-content">'.PHP_EOL;
            $str .= '<span class="task-status task-status-'.$task['task_status'].'" title="'.formatText($meta, '2ATT').'">'.get_task_status($task['task_status']).'</span>'.nl2br($task['task_label']);
            if($task['task_status'] == 'done') $str .= '<span class="task-achieved">'. mb_ucfirst(_t('task', 'achieved_at')). ' '. $task['task_date_done_display']. ' (' ._t('task', 'duration'). ' : ' .$task['duration'] . ' '._t('task', 'months').')'.'</span>';
            
            if($edition) {
                $str .= '<div class="iconetab"><a href="../project/_ajax_task.php?todo=delete&amp;id='.$task['task_id'].'&amp;pid='.$task['task_project_id'].'" title="'.formatText(_t('task', 'delete'), '2ATT').'" class="ico_sup"><i class="fa fa-trash"></i><span>'.formatText(_t('task', 'delete')).'</span></a><a href="../project/_ajax_task.php?todo=edit&amp;id='.$task['task_id'].'&amp;pid='.$task['task_project_id'].'" title="'.formatText(_t('task', 'edit'), '2ATT').'" class="ico_mod edit-task"><i class="fa fa-pencil-square-o"></i><span>'.formatText(_t('task', 'edit')).'</span></a></div>';
            }
            $str .= '</div>'.PHP_EOL;
            $str .= '<br style="clear:both" /></li>';
        }
        
        return sprintf('<div class="dd"><ul class="project-tasks">%s</ul></div>', $str);
    }
    
}

/**
 * get_finalities()
 *
 * @param  $id (optionnal) : numeric / false
 * @param  $as_string (optionnal) : true / false
 * @param  $separator (optionnal) : default ','
 * @return array
 */
if(!function_exists('get_finalities')) {

	function get_finalities($id = false, $as_string = true, $separator = ',')
	{
		// we get all values
		$init = $GLOBALS['sql_object']->DBSelect(SQL_getFinalities($id));

		if (! isset ( $init [0] ['finality_id'] )) return false;

		$simple_array = array ();
		$array = array ();

		for($i = 0; $i < count ( $init ); $i ++) {
			$array [$i] ['finality_name'] = $init [$i] ['finality_name'];
			$array [$i] ['finality_id'] = $init [$i] ['finality_id'];
			array_push ( $simple_array, $init [$i] ['finality_name'] );
		}

		if ($as_string) {
			return join ( $separator . ' ', $simple_array );
		} else {
			return $array;
		}

	}
}

function get_sql_status($value) {
	
	$a = array('public' => 'P', 'draft' => 'A', 'archives_p' => 'PA', 'archives_a' => 'AA');

	if(!key_exists($value, $a))  return false;
	else return $a[$value];
}

/**
 * getInternalNav()
 * get internal navigation based on current view
 * @return string
 */
if(!function_exists('getInternalNav')) {
	function getInternalNav() {
	
		$dv_class = $fv_class = $fiv_class = '';
		if(!isset($_REQUEST['view'])) $dv_class = 'active';
		if(isset($_REQUEST['view']) && $_REQUEST['view'] == 'flat') $fv_class = 'active';
		if(isset($_REQUEST['view']) && $_REQUEST['view'] == 'finality') $fiv_class = 'active';
		
		$finality_view = $modify_link = $timeline_view = '';
	
		$timeline = get_timeline_info();
		if(isset($timeline) && ($timeline['depth'] == -1 || $timeline['show-root-timeline'] == 1))  $timeline_view = '<a href="../project/_ajax_timeline.php?id=0" class="display-timeline" title="'.mb_ucfirst(_t('project','cal')).'"><i class="fa fa-calendar" aria-hidden="true"></i> '.mb_ucfirst(_t('project','cal')).'</a>';
		
		$default_view ='<a href="index.php?rub=project&amp;todo=list" title="'._t('project','level_view').'"  class="'.$dv_class.'">'._t('project','level_view').'</a>';
		$flat_view 	= '<a href="index.php?rub=project&amp;todo=list&amp;view=flat" title="'._t('project','flat_view').'"  class="'.$fv_class.'">'._t('project','flat_view').'</a>';
		if(defined('PROJECT_FINALITIES') && PROJECT_FINALITIES == 1) $finality_view ='<a href="index.php?rub=project&amp;todo=list&amp;view=finality" title="'._t('project','finality_view').'" class="'.$fiv_class.'">'._t('project','finality_view').'</a>';
		if($GLOBALS['l21auth']->isSuperAdmin ()) $modify_link ='<a href="#modify-actors" title="'._t('project','modify_actors').'">'._t('project','modify_actors').'</a>';
		
		$navbar = $timeline_view. $default_view . $flat_view . $finality_view. $modify_link ;
	
		return sprintf('<div class="mod_link">%s</div><br />', $navbar);
	
	}
}


if(!function_exists('getMenuFilter')) {

	/**
	 * getMenuFilter()
	 *
	 * @param array $tags
	 * @return string
	 */
	function getMenuFilter ($tags = array(), $finalities = array(), $scales = array(), $priorities = array(), $managers = array()) {
	
		footerAddJS('../lib/js/jquery-tag-filtering/jquery.tagfiltering.simo.js');
		addDynamicCSS('../lib/js/jquery-tag-filtering/jquery.tagfiltering.simo.css');
		
		// one call to apply many filters from several lists (ul) with same css class and using distincts data-* attributes
		// to comment if individual filtering are applied
		footerAddInlineJS('$("ul.filter-menu").tagfiltering({target_attr:"data-priorities,data-tags,data-finalities,data-scales", separator:";", callback:compute_values});');
		
		// export Javascript part
		$js =
		'$("#save-export").click( function() {
				var to_export = [];
				var $items = $(".filter-items").children();
		
				// we populate the array to send with ajax
				$items.each(function() {
					if($(this).is(":visible"))  {
						var curval = $(this).attr("data-id");
						// we check if not in array yet - could happen when using "Finality view"
						if($.inArray( curval,to_export) == -1) to_export.push($(this).attr("data-id"));
					}
				});
		
				alertify.success("'. _t('items', 'selected').'".replace("%s", to_export.length));
		
				$.ajax({
					   type: "POST",
					   data: {to_export:to_export},
					   url: "../project/_ajax_actions.php?token='.SECRET_KEY.'",
					   success: function(msg){
					   		window.location = "../admin/index.php?rub=project&todo=report";
					   }
					});
			});';
		footerAddInlineJS($js);
		
		$filter_menu  = '<div class="toggle_title"><a id="projects-filter" href="#">'._t('filter', 'content').'</a></div>';
		$filter_menu .= '<div class="contboxwhite filters" style="display:none">';
		$filter_menu .= getTagsMenuFilter ($tags);
		$filter_menu .= getFinalitiesMenuFilter($finalities);
		$filter_menu .= getScalesMenuFilter($scales);
        $filter_menu .= '<div class="grid-2">';
		$filter_menu .= getPriorityMenuFilter($priorities);
        if ($GLOBALS['l21auth']->isSuperAdmin()) $filter_menu .= getManagerFilter($managers);
        $filter_menu .= '</div>';
        $filter_menu .= '<div class="grid-2">';
        $filter_menu .= getAchievementMenuFilter();
		$filter_menu .= getCompletionMenuFilter();
        $filter_menu .= '</div>';
		if ($GLOBALS['l21auth']->isSuperAdmin()) $filter_menu .= '<div class="end"><a href="#" id="save-export" class="button regular"><i class="fa fa-download" aria-hidden="true"></i></i> '._t('btn', 'save_export').'</a></div><br class="brendstep" />';
		$filter_menu .= '</div>';
		
		return $filter_menu;
	}
}

if(!function_exists('getCompletionMenuFilter')) {

    /**
     * getCompletionMenuFilter()
     *
     * get completion menu filter
     * @param array $tags
     * @return string
     */
    function getCompletionMenuFilter ($steps = PROJECT_STEP, $initialValue = 0) {
        
        // one call to apply many filters from several lists (ul) with same css class and using distincts data-* attributes
        // to comment if individual filtering are applied
        footerAddInlineJS('
            $("#completion-operator").on("change", function() {$( "#completion-filter" ).trigger( "input" );});

            $(document).on("input", "#completion-filter", function() {
                var current = $(this).val();
                var operator = $("#completion-operator").find(":selected").val();
                // console.log(current);
                // console.log(operator);
                if(operator == "all") {
                    current = 0;
                    operator = ">=";
                    $("#completion-filter").val(current);
                }
                $("#completion-filter-value").text(current + " %").hide().fadeIn();
                $("tbody.filter-items tr").show();
                $("tbody.filter-items tr").filter(function() { 
                    if(operator == ">=") return parseInt($(this).attr("data-completion")) < parseInt(current-1);
                    else if(operator == "<=") return parseInt($(this).attr("data-completion")) > parseInt(current);
                    else return parseInt($(this).attr("data-completion")) != parseInt(current); // operator == "="
                    })
                    .hide(); // !!!! with fadeOut(), compute_values() does not update 
                    compute_values();
        });');
        
        $filter = '';
        $options  = '<select id="completion-operator">
                      <option value="all" checked>'.mb_ucfirst(_t('divers', 'select_all')).'</option>
                      <option value=">="> >=</option>
                      <option value="<="> <=</option>
                      <option value="="> =</option>
                    </select>';
        $options .= '<input name="completion-filter" id="completion-filter" type="range" min="0" max="100" step="'. $steps . '" value="0" /><span id="completion-filter-value">'.$initialValue.' %</span>';
        
        $filter .= sprintf('<div class="completion-filter item-filter"><h3>%s</h3><div class="completion-filter-menu">%s</div></div>', _t('filter', 'by_completion'), $options);
        return $filter;
        
    }
}


if(!function_exists('getManagerFilter')) {

    /**
     * getManagerFilter()
     *
     * get completion menu filter
     * @param array $tags
     * @return string
     */
    function getManagerFilter ($managers) {

        // one call to apply many filters from several lists (ul) with same css class and using distincts data-* attributes
        // to comment if individual filtering are applied
        footerAddInlineJS('
            $("#manager-filter").on("change", function() {
                var manager = $(this).find(":selected").val();

                $("tbody.filter-items tr").show();
                $("tbody.filter-items tr").filter(function() {
                    var recManager = $(this).attr("data-manager");
                    if(manager == "all") return false; // we select nothing to make all items visible
                    else {
                        if(recManager.includes(manager)) console.log(recManager + " a été trouvé !!! ");
                        if(!recManager.includes(manager)) return true; // we select unwanted records to hide them
                    }
                })
                .hide(); // !!!! with fadeOut(), compute_values() does not update
                compute_values();
            });');

        $filter = '';
        $select  = '<select id="manager-filter">
                      <option value="all" checked>'.mb_ucfirst(_t('divers', 'select_all')).'</option>
                      %s
                    </select>';

        $options = '';
        if(is_array($managers)) {
            foreach ($managers as $i => $user)
            {
                $fullname = '';
                if(!empty($user['profile_firstname']) || $user['profile_lastname']) {
                    $fullname = ' - '. $user['profile_firstname'].' '.$user['profile_lastname'];
                }
                $str_id = $user['user_login'];
                $html_str = $user['user_login'] . $fullname . ' ('.$user['profile_email'].')';
                $html_str = cutText($html_str, 55);
                $options .= '<option value="'.$str_id.'">'. $html_str .'</option>';
            }
        }

        $select = sprintf($select, $options);
        $filter .= sprintf('<div class="manager-filter item-filter"><h3>%s</h3><div class="manager-filter-menu">%s</div></div>', _t('filter', 'by_manager'), $select);
        return $filter;

    }
}

if(!function_exists('getAchievementMenuFilter')) {

    /**
     * getAchievementMenuFilter()
     *
     * get tags menu filter
     * @param array $tags
     * @return string
     */
    function getAchievementMenuFilter () {

        // one call to apply many filters from several lists (ul) with same css class and using distincts data-* attributes
        // to comment if individual filtering are applied
        footerAddInlineJS('
            $("#achievement-filter").on("change", function() {
                var achievement = $(this).find(":selected").val();
                 
                $("tbody.filter-items tr").show();
                $("tbody.filter-items tr").filter(function() {
                    var recAchievement = $(this).attr("data-achievement");
                    
                    console.log(achievement +  " - " + recAchievement);
                    if(achievement == "all") return false; // we select nothing to make all items visible
                    else {
                        if(recAchievement.includes(achievement)) console.log(recAchievement + " a été trouvé !!! ");
                        if(!recAchievement.includes(achievement)) return true; // we select unwanted records to hide them
                    }
                })
                .hide(); // !!!! with fadeOut(), compute_values() does not update
                compute_values();
            });');

        $filter = '';
        $select  = '<select id="achievement-filter">
                      <option value="all" checked>'.mb_ucfirst(_t('divers', 'select_all')).'</option>
                      <option value="0">'.empty_nc('').'</option>
                      %s
                    </select>';

        $options = '';

            foreach ($GLOBALS['lang']['project']['achievementItems'] as $key => $value)
            {
                $options .= '<option value="'.$key.'">'. mb_ucfirst($value) .'</option>';
            }


        $select = sprintf($select, $options);
        $filter .= sprintf('<div class="achievement-filter item-filter"><h3>%s</h3><div class="achievement-filter-menu">%s</div></div>', _t('filter', 'by_achievement'), $select);
        return $filter;

    }

}


if(!function_exists('getPriorityMenuFilter')) {
    
    /**
     * getPriorityMenuFilter()
     *
     * get tags menu filter
     * @param array $tags
     * @return string
     */
    function getPriorityMenuFilter ($priorities) {
        
        // to uncomment to apply filter only on scales (without finalities / tags considerations)
        //footerAddInlineJS('$("ul.priorities-filter-menu").tagfiltering({target_attr:"data-priority", exclude_parents:"ul.filter-menu", separator:";", callback:compute_values});');
        
        
        $filter = '';
        
        // we display filter if at least 2 values exists
        if(count($priorities) > 1) {
            $options = '';
            $a = array();
            foreach($priorities as $item) {
                if(!in_array($item['priority_id'], $a)) {
                    $options .= '<li data-tag="'.$item['priority_name'].'" id="priority-'.$item['priority_id'].'"><a class="facet" href="#">'.$item['priority_name'].'</a></li>';
                    array_push($a, $item['priority_id']);
                }
            }
            
            $filter .= sprintf('<div class="priority-filter item-filter"><h3>%s</h3><ul class="filter-menu priorities-filter-menu">%s</ul></div>', _t('filter', 'by_priority'), $options);
            
        }
        return $filter;
    }
    
}


if(!function_exists('getScalesMenuFilter')) {

	/**
	 * getScalesMenuFilter()
	 *
	 * get tags menu filter
	 * @param array $tags
	 * @return string
	 */
	function getScalesMenuFilter ($scales) {

		// to uncomment to apply filter only on scales (without finalities / tags considerations)
		//footerAddInlineJS('$("ul.scales-filter-menu").tagfiltering({target_attr:"data-scales", exclude_parents:"ul.filter-menu", separator:";", callback:compute_values});');


		$filter = '';
		
		// we display filter if at least 2 values exists
		if(count($scales) > 1) {
			$options = '';
			$a = array();
			foreach($scales as $item) {
				if(!in_array($item['scale_id'], $a)) {
					$options .= '<li data-tag="'.$item['scale_name'].'" id="scale-'.$item['scale_id'].'"><a class="facet" href="#">'.$item['scale_name'].'</a></li>';
					array_push($a, $item['scale_id']);
				}
			}

			$filter .= sprintf('<div class="scale-filter item-filter"><h3>%s</h3><ul class="filter-menu scales-filter-menu">%s</ul></div>', _t('filter', 'by_scale'), $options);

		}
		return $filter;
	}

}


if(!function_exists('getFinalitiesMenuFilter')) {

	/**
	 * getTagsMenuFilter()
	 *
	 * get tags menu filter
	 * @param array $tags
	 * @return string
	 */
	function getFinalitiesMenuFilter ($finalities) {

		// to uncomment to apply filter only on finalities (without scales / tags considerations)
		//footerAddInlineJS('$("ul.finalities-filter-menu").tagfiltering({target_attr:"data-finalities", exclude_parents:"ul.filter-menu", separator:";", callback:compute_values});');


		$filter = '';
		
		if(defined('PROJECT_FINALITIES') && PROJECT_FINALITIES == 1) {
		
    		// we display filter if at least 2 values exists
    		if(count($finalities) > 1) {
    			$options = '';
    			$a = array();
    			foreach($finalities as $item) {
    				if(!in_array($item['finality_id'], $a)) {
    					$options .= '<li data-tag="'.$item['finality_name'].'" id="finality-'.$item['finality_id'].'"><a class="facet" href="#">'.$item['finality_name'].'</a></li>';
    					array_push($a, $item['finality_id']);
    				}
    			}
    				
    			$filter .= sprintf('<div class="finality-filter item-filter"><h3>%s</h3><ul class="filter-menu finalities-filter-menu">%s</ul></div>', _t('filter', 'by_finality'), $options);
    				
    		}
		}
		return $filter;
	}

}

if(!function_exists('getTagsMenuFilter')) {

	/**
	 * getTagsMenuFilter()
	 * 
	 * get tags menu filter
	 * @param array $tags
	 * @return string
	 */
	function getTagsMenuFilter ($tags) {
		
		// to uncomment to apply filter only on tags (without scales / finalities considerations)
		//footerAddInlineJS('$("ul.tags-filter-menu").tagfiltering({target_attr:"data-tags", exclude_parents:"ul.filter-menu", separator:";", callback:compute_values});');

		
		$filter = '';
		
		// we display filter if at least 1 values exists
		if(count($tags) >= 1) {
			$options = '';
			$a = array();
			foreach($tags as $item) {
				if(!in_array($item['tag_id'], $a)) {
					$options .= '<li data-tag="'.$item['tag_name'].'" id="tag-'.$item['tag_id'].'"><a class="facet" href="#">'.$item['tag_name'].'</a></li>';
					array_push($a, $item['tag_id']);
				}
			}
			
			$filter .= sprintf('<div class="tag-filter item-filter"><h3>%s</h3><ul class="filter-menu tags-filter-menu">%s</ul></div>', _t('filter', 'by_tag'), $options);
			
		}
		return $filter;
	}

}
