'use strict';
define(function() {
  var HpoAppFactory = function(
    $http,
    FeatureTypeFactory,
    $filter,
    $rootScope,
    $location,
    InitProvider,
    $timeout,
    AlertHpoFactory,
    gaDomUtils,
    EditFactory,
    $q
  ) {
    /**
     * CONSTANTS
     */
    var HPO_EXTENSION,
      HPO_CANA,
      HPO_CANA_DEFAILLANCE,
      HPO_BRANCHEMENT,
      HPO_BRANCHEMENT_DEFAILLANCE,
      HPO_CANA_VALID,
      HPO_CANA_DEFAILLANCE_VALID,
      HPO_BRANCHEMENT_VALID,
      HPO_BRANCHEMENT_DEFAILLANCE_VALID,
      HPO_TRANSFORMATION_COVARIABLES,
      HPO_JEU_DONNEE,
      HPO_MODELE,
      HPO_MODELE_HISTORIQUE,
      HPO_CALAGE,
      HPO_CALAGE_HISTORIQUE,
      HPO_VALIDATION,
      HPO_PREVISION,
      HPO_IMPORT_HISTORIQUE,
      HPO_AMC_FILTER,
      HPO_ANALYSE_HISTORIQUE,
      HPO_VALIDATION_STEP_HISTORIQUE,
      HPO_DASHBOARD,
      HPO_CALAGE_SYNTHESE,
      HPO_AUTOMATISATION_NAME,
      HPO_PARAMETRES_NAME,
      HPO_CRITEREAS_NAME,
      HPO_PONDERATION_NAME,
      HPO_INDICATOR_NAME,
      HPO_COMPARAISON_NAME,
      HPO_CORRESPONDANCE_NAME,
      HPO_CORRESPONDANCE_ITEMS_NAME,
      HPO_CHANTIERS_NAME,
      HPO_FICHE_CHANTIER_NAME,
      HPO_TABLEAU_RECAPITULATIF_CHANTIERS_NAME,
      HPO_RAPPORT_BILAN_NAME,
      HPO_PRIORITY_NAME,
      HPO_CHANTIERS_RELATIONS_NAME,
      HPO_STANDARDISATION,
      HPO_CHANTIER_AUTOMATIQUE;
    var HPO_COMPONENTS = {};
    var HPO_EXCLUSE_ATTRIBUTES = {};
    var HPO_DISABLED_EDIT_ATTRIBUTES = {};
    var HPO_RAPPORT = {};
    var HPO_RAPPORT_RECAPITULATIF = {};
    let HPO_RAPPORT_BILAN = {};

    var prefixes = 'KIS_HPO_';
    var prefixes_carte = 'KIS_CARTE_';
    var initiated = false;

    function initFactory(storeName) {
      HPO_EXTENSION =
        '_' + (storeName || InitProvider.getHpoConfig().datastoreName);
      HPO_CANA = 'KIS_HPO_CANALISATION_IMPORT' + HPO_EXTENSION;
      HPO_CANA_DEFAILLANCE =
        'KIS_HPO_CANALISATION_DEFAILLANCE_IMPORT' + HPO_EXTENSION;
      HPO_BRANCHEMENT = 'KIS_HPO_BRANCHEMENT_IMPORT' + HPO_EXTENSION;
      HPO_BRANCHEMENT_DEFAILLANCE =
        'KIS_HPO_BRANCHEMENT_DEFAILLANCE_IMPORT' + HPO_EXTENSION;
      HPO_CANA_VALID = 'KIS_HPO_CANALISATION' + HPO_EXTENSION;
      HPO_CANA_DEFAILLANCE_VALID =
        'KIS_HPO_CANALISATION_DEFAILLANCE' + HPO_EXTENSION;
      HPO_BRANCHEMENT_VALID = 'KIS_HPO_BRANCHEMENT' + HPO_EXTENSION;
      HPO_BRANCHEMENT_DEFAILLANCE_VALID =
        'KIS_HPO_BRANCHEMENT_DEFAILLANCE' + HPO_EXTENSION;

      HPO_TRANSFORMATION_COVARIABLES =
        'KIS_HPO_TRANSFORMATION_COVARIABLES' + HPO_EXTENSION;
      HPO_JEU_DONNEE = 'KIS_HPO_JEU_DONNEE' + HPO_EXTENSION;
      HPO_MODELE = 'KIS_HPO_MODELE' + HPO_EXTENSION;
      HPO_MODELE_HISTORIQUE = 'KIS_HPO_MODELE_HISTORIQUE' + HPO_EXTENSION;
      HPO_CALAGE = 'KIS_HPO_CALAGE' + HPO_EXTENSION;
      HPO_CALAGE_SYNTHESE = 'KIS_HPO_CALAGE_SYNTHESE' + HPO_EXTENSION;
      HPO_CALAGE_HISTORIQUE = 'KIS_HPO_CALAGE_HISTORIQUE' + HPO_EXTENSION;
      HPO_VALIDATION = 'KIS_HPO_VALIDATION' + HPO_EXTENSION;
      HPO_PREVISION = 'KIS_HPO_PREVISION' + HPO_EXTENSION;
      HPO_IMPORT_HISTORIQUE = 'KIS_HPO_IMPORT_HISTORIQUE' + HPO_EXTENSION;
      HPO_AMC_FILTER = 'KIS_HPO_AMC_FILTER' + HPO_EXTENSION;
      HPO_STANDARDISATION = 'KIS_HPO_STANDARDISATION' + HPO_EXTENSION;
      HPO_CHANTIER_AUTOMATIQUE = 'KIS_HPO_CHANTIER_AUTOMATIQUE' + HPO_EXTENSION;
      HPO_ANALYSE_HISTORIQUE = 'KIS_HPO_ANALYSE_HISTORIQUE' + HPO_EXTENSION;
      HPO_VALIDATION_STEP_HISTORIQUE =
        'KIS_HPO_VALIDATION_STEP_HISTORIQUE' + HPO_EXTENSION;
      HPO_DASHBOARD = 'KIS_HPO_DASHBOARD' + HPO_EXTENSION;
      HPO_AUTOMATISATION_NAME = 'KIS_HPO_AUTOMATISATION' + HPO_EXTENSION;
      HPO_PARAMETRES_NAME = 'KIS_HPO_PARAMETRES' + HPO_EXTENSION;
      HPO_CRITEREAS_NAME = 'KIS_HPO_CRITEREAS' + HPO_EXTENSION;
      HPO_PONDERATION_NAME = 'KIS_HPO_PONDERATION' + HPO_EXTENSION;
      HPO_INDICATOR_NAME = 'KIS_HPO_INDICATEURS' + HPO_EXTENSION;
      HPO_COMPARAISON_NAME = 'KIS_HPO_COMPARAISON' + HPO_EXTENSION;

      HPO_CORRESPONDANCE_NAME = 'KIS_HPO_CORRESPONDANCE' + HPO_EXTENSION;
      HPO_CORRESPONDANCE_ITEMS_NAME =
        'KIS_HPO_CORRESPONDANCE_ITEMS' + HPO_EXTENSION;
      HPO_PRIORITY_NAME = 'KIS_HPO_PRIORITY' + HPO_EXTENSION;

      HPO_CHANTIERS_NAME = 'KIS_HPO_CHANTIERS' + HPO_EXTENSION;
      HPO_CHANTIERS_RELATIONS_NAME =
        'KIS_HPO_CHANTIERS_RELATIONS' + HPO_EXTENSION;

      HPO_FICHE_CHANTIER_NAME = 'hpo_fiche_chantier' + HPO_EXTENSION + '.docx';
      HPO_TABLEAU_RECAPITULATIF_CHANTIERS_NAME =
        'hpo_tableau_recapitulatif_chantiers' + HPO_EXTENSION + '.docx';
      HPO_RAPPORT_BILAN_NAME = 
        'hpo_rapport_bilan' + HPO_EXTENSION + '.docx';

      HPO_COMPONENTS = {
        all: [
          HPO_CANA,
          HPO_CANA_DEFAILLANCE,
          HPO_BRANCHEMENT,
          HPO_BRANCHEMENT_DEFAILLANCE,
          HPO_CANA_VALID,
          HPO_CANA_DEFAILLANCE_VALID,
          HPO_BRANCHEMENT_VALID,
          HPO_BRANCHEMENT_DEFAILLANCE_VALID,
        ],
        data: [
          HPO_CANA,
          HPO_CANA_DEFAILLANCE,
          HPO_BRANCHEMENT,
          HPO_BRANCHEMENT_DEFAILLANCE,
        ],
        data_no_defail: [HPO_CANA, HPO_BRANCHEMENT],
        data_defail: [HPO_CANA_DEFAILLANCE, HPO_BRANCHEMENT_DEFAILLANCE],
        valid: [
          HPO_CANA_VALID,
          HPO_CANA_DEFAILLANCE_VALID,
          HPO_BRANCHEMENT_VALID,
          HPO_BRANCHEMENT_DEFAILLANCE_VALID,
        ],
        valid_no_defail: [HPO_CANA_VALID, HPO_BRANCHEMENT_VALID],
        valid_defail: [
          HPO_CANA_DEFAILLANCE_VALID,
          HPO_BRANCHEMENT_DEFAILLANCE_VALID,
        ],
        valid_hist: [HPO_VALIDATION_STEP_HISTORIQUE],
        stat_hist: [HPO_DASHBOARD],
        transform: [HPO_TRANSFORMATION_COVARIABLES],
        modele: [
          HPO_JEU_DONNEE,
          HPO_MODELE,
          HPO_MODELE_HISTORIQUE,
          HPO_CALAGE,
          HPO_CALAGE_HISTORIQUE,
          HPO_VALIDATION,
          HPO_PREVISION,
        ],
        modal_historic: [HPO_MODELE],
        jeu_de_donnee: [HPO_JEU_DONNEE],
        calage: [HPO_CALAGE],
        calage_synthese: [HPO_CALAGE_SYNTHESE],
        validation: [HPO_VALIDATION],
        prevision: [HPO_PREVISION],
        logic: [HPO_IMPORT_HISTORIQUE],
        home: {
          canalisation: HPO_CANA_VALID,
          defailcanalisation: HPO_CANA_DEFAILLANCE_VALID,
          branchement: HPO_BRANCHEMENT_VALID,
          defailbranchement: HPO_BRANCHEMENT_DEFAILLANCE_VALID,
        },
        amc_filter: [HPO_AMC_FILTER],
        hpo_standardisation:[HPO_STANDARDISATION],
        hpo_chantier_automatique:[HPO_CHANTIER_AUTOMATIQUE],
        prep: [HPO_ANALYSE_HISTORIQUE],
        auto: [HPO_AUTOMATISATION_NAME],
        parameters: [HPO_PARAMETRES_NAME],
        critereas: [HPO_CRITEREAS_NAME],
        ponderation: [HPO_PONDERATION_NAME],
        indicateur: [HPO_INDICATOR_NAME],
        compare: [HPO_COMPARAISON_NAME],
        chantiers: [HPO_CHANTIERS_NAME],
        chantiers_relations: [HPO_CHANTIERS_RELATIONS_NAME],
        correspondance: [HPO_CORRESPONDANCE_NAME],
        correspondance_items: [HPO_CORRESPONDANCE_ITEMS_NAME],
        priority: [HPO_PRIORITY_NAME],
        srid: 'EPSG:3857',
      };
      HPO_RAPPORT = {
        docx: [HPO_FICHE_CHANTIER_NAME],
      };
      HPO_RAPPORT_RECAPITULATIF = {
        docx: [HPO_TABLEAU_RECAPITULATIF_CHANTIERS_NAME],
      };
      HPO_RAPPORT_BILAN = {
        docx: [HPO_RAPPORT_BILAN_NAME],
      };
      HPO_EXCLUSE_ATTRIBUTES[HPO_IMPORT_HISTORIQUE] = [
        'UID_FICHIER',
        'USERID',
        'PROCESSID',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_ANALYSE_HISTORIQUE] = [
        'TRANSACTION_UID',
        'FEAT_UID',
        'FEAT_NAME',
        'USERID',
        'SELECTED_ATTRIBUTES',
        'REMOVED_FEATURES',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_DASHBOARD] = [
        'FEAT_UID',
        'FEAT_NAME',
        'USERID',
        'FILE',
      ];
      HPO_DISABLED_EDIT_ATTRIBUTES[HPO_VALIDATION_STEP_HISTORIQUE] = [
        'TYPE',
        'DATE_CORRECTION',
        'FEAT_ALIAS',
        'DATE_UPDATE',
        'DATE_CANCEL',
        'TRANSACTION_UID',
        'EXPRESSION',
        'ELEMENT_NAME',
        'ELEMENT_OLD_VALUE',
        'ELEMENT_NEW_VALUE',
        'USER',
        'USERID',
        'PARTAGER',
        'OTHER_USER',
        'JOINORSEPARATION',
        'SEPARATOR',
        'LAST_STATUS',
      ];
      HPO_DISABLED_EDIT_ATTRIBUTES[HPO_ANALYSE_HISTORIQUE] = [
        'TYPE',
        'DATE_CORRECTION',
        'FEAT_ALIAS',
        'DATE_UPDATE',
        'DATE_CANCEL',
        'TRANSACTION_UID',
        'EXPRESSION',
        'ELEMENT_NAME',
        'ELEMENT_OLD_VALUE',
        'ELEMENT_NEW_VALUE',
        'USER',
        'USERID',
        'PARTAGER',
        'OTHER_USER',
        'JOINORSEPARATION',
        'SEPARATOR',
        'LAST_STATUS',
        'ADDED_ATTRIBUTES',
        'REMOVED_ATTRIBUTES',
        'REMOVED_FEATURES',
        'GLOBAL_FILTER',
      ];
      HPO_TRANSLATE_ATTRIBUTES[HPO_ANALYSE_HISTORIQUE] = {
        TYPE: translateValueFunc,
        LAST_STATUS: translateValueFunc,
        ELEMENT_OLD_VALUE: translateValueDirectSplitFunc,
        ELEMENT_NEW_VALUE: translateValueDirectSplitFunc,
      };
      HPO_TRANSLATE_ATTRIBUTES[HPO_VALIDATION_STEP_HISTORIQUE] = {
        TYPE: translateValueFunc,
        LAST_STATUS: translateValueFunc,
        ELEMENT_OLD_VALUE: translateValueDirectSplitFunc,
        ELEMENT_NEW_VALUE: translateValueDirectSplitFunc,
      };
      HPO_TRANSLATE_ATTRIBUTES[HPO_CALAGE] = {
        STEP: translateValueModelFunc,
        STATUS: translateValueModelFunc,
      };
      HPO_TRANSLATE_ATTRIBUTES[HPO_VALIDATION] =
        HPO_TRANSLATE_ATTRIBUTES[HPO_CALAGE];
      HPO_TRANSLATE_ATTRIBUTES[HPO_PREVISION] =
        HPO_TRANSLATE_ATTRIBUTES[HPO_CALAGE];
      HPO_TRANSLATE_ATTRIBUTES[HPO_CHANTIER_AUTOMATIQUE] =
        HPO_TRANSLATE_ATTRIBUTES[HPO_CALAGE];
      HPO_TRANSLATE_ATTRIBUTES[HPO_STANDARDISATION] =
        HPO_TRANSLATE_ATTRIBUTES[HPO_CALAGE];

      HPO_EXCLUSE_ATTRIBUTES[HPO_VALIDATION_STEP_HISTORIQUE] = [
        'TRANSACTION_UID',
        'FEAT_UID',
        'FEAT_NAME',
        'ELEMENT_NAME',
        'ELEMENT_OLD_VALUE',
        'ELEMENT_NEW_VALUE',
        'USERID',
        'ADDED_IDS',
        'UPDATED_IDS',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_MODELE] = [
        'IDENTIFIANT',
        'ID_JEU_DONNEE',
        'USERID',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_JEU_DONNEE] = [
        'IDENTIFIANT',
        'UID_TABLE_DONNEE',
        'UID_TABLE_FUITE',
        'USERID',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_CALAGE] = [
        'IDENTIFIANT',
        'fid',
        'IDENTIFIANT_MODELE',
        'USERID',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_VALIDATION] = [
        'IDENTIFIANT',
        'IDENTIFIANT_MODELE',
        'USERID',
        'COVARIABLES',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_PREVISION] = [
        'IDENTIFIANT',
        'IDENTIFIANT_MODELE',
        'IDENTIFIANT_CALAGE',
        'USERID',
        'COVARIABLES',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_COMPARAISON_NAME] = [
        'PONDERATION',
        'INDICATEUR',
        'RESULT',
      ];
      HPO_EXCLUSE_ATTRIBUTES['CALAGE'] = ['IDENTIFIANT', 'DATE_DE_POSE'];
      HPO_EXCLUSE_ATTRIBUTES[HPO_CORRESPONDANCE_NAME] = [
        'FEATID',
        'CONFIG',
        'USERID',
      ];
      HPO_EXCLUSE_ATTRIBUTES[HPO_PRIORITY_NAME] = ['FEATID', 'DATA', 'USERID'];
      HPO_EXCLUSE_ATTRIBUTES[HPO_CHANTIERS_NAME] = ['FTIUID'];
      HPO_EXCLUSE_ATTRIBUTES[HPO_AUTOMATISATION_NAME] = [
        'FEAT_UID',
        'FEAT_NAME',
        'PREVISION',
        'DATA',
        'ATTRIBUTES_SELECTED',
        'USERID',
        'CREATED_ELEMENTS',
      ];
      HPO_TRANSLATE_ATTRIBUTES[HPO_AUTOMATISATION_NAME] = {
        USE_PREVISION: translateValueModelFunc,
        USE_NOMBRE: translateValueModelFunc,
        PREVISION_METHOD: translateValueCommonFunc,
      };

      initiated = true;
    }

    var isAppInitiated = function() {
      return initiated;
    };

    var getReportName = function(type) {
      return HPO_RAPPORT[type];
    };
    var getReportRecapitulatifName = function(type) {
      return HPO_RAPPORT_RECAPITULATIF[type];
    };
    var getReportBilanName = function(type) {
      return HPO_RAPPORT_BILAN[type];
    };

    var translateValueFunc = function(v) {
      if (v)
        return $filter('translate')('hpo.data.prepare.correctiontools.' + v);
      else {
        return v;
      }
    };
    var translateValueCommonFunc = function(v) {
      if (v) return $filter('translate')('hpo.common.' + v);
      else {
        return v;
      }
    };

    var translateValueModelFunc = function(v) {
      if (v) return $filter('translate')('hpo.model.traduction.' + v);
      else {
        return v;
      }
    };

    function getFuiteTables(fti) {
      var bool = true;
      if (fti && fti.name && fti.relations && fti.relations.length > 0) {
        for (var i = 0; i < fti.relations.length; i++) {
          var rel = fti.relations[i];
          if (rel.type === 'REL_SIMPLE') {
            bool = false;
            break;
          }
        }
      }
      return bool;
    }

    function getFuiteTableFrom(fti) {
      if (fti && fti.name && fti.relations && fti.relations.length > 0) {
        for (var i = 0; i < fti.relations.length; i++) {
          var rel = fti.relations[i];
          if (rel.type === 'REL_SIMPLE') {
            return rel.idEnd;
          }
        }
      }
    }

    var translateValueSplitFunc = function(v) {
      if (v) {
        var elements = v
          .split(',')
          .map(function(x) {
            if (x)
              return $filter('translate')(
                'hpo.data.prepare.correctiontools.' + x
              );
          })
          .filter(function(x) {
            if (x) return x;
          });
        return elements.join(',');
      } else {
        return v;
      }
    };

    var translateDirectValueFunc = function(v) {
      if (v) {
        return $filter('translate')(v);
      } else {
        return v;
      }
    };

    var translateValueDirectSplitFunc = function(v) {
      if (v) {
        var elements = v
          .split(',')
          .map(function(x) {
            if (x) return $filter('translate')(x);
          })
          .filter(function(x) {
            if (x) return x;
          });
        return elements.join(',');
      } else {
        return v;
      }
    };

    var HPO_TRANSLATE_ATTRIBUTES = {};
    var HPO_DIVERS_PARAMS = {
      type: translateDirectValueFunc,
      description: translateDirectValueFunc,
    };

    var APP_NAME = $location.search().app;
    function getAppname() {
      return APP_NAME;
    }

    function parseNameForCheck(name) {
      if (name) {
        var last = '_' + InitProvider.getHpoConfig().datastoreName;
        return name.substring(0, name.length - last.length);
      } else {
        return name;
      }
    }

    function getResourceFromUidCana(uid){
      if (
        InitProvider.getHpoConfig() &&
        InitProvider.getHpoConfig().currentResources &&
        InitProvider.getHpoConfig().currentResources.length > 0
      ) {
        return InitProvider.getHpoConfig().currentResources.find(resource => resource.uid === uid);
      }
      return null;
    }

    function getAdminConfig(fti) {
      var response = false;
      if (
        InitProvider.getHpoConfig() &&
        InitProvider.getHpoConfig().currentResources &&
        InitProvider.getHpoConfig().currentResources.length > 0
      ) {
        for (
          var i = 0;
          i < InitProvider.getHpoConfig().currentResources.length;
          i++
        ) {
          var conf = InitProvider.getHpoConfig().currentResources[i];
          if (
            conf &&
            conf.uid &&
            conf.defail_uid &&
            (conf.uid === fti.uid || conf.defail_uid === fti.uid)
          ) {
            response = true;
            break;
          }
        }
      }
      return response;
    }

    function getAdminConfigAdded(fti) {
      var response = false;
      if (
        InitProvider.getHpoConfig() &&
        InitProvider.getHpoConfig().otherftis &&
        InitProvider.getHpoConfig().otherftis.length > 0
      ) {
        for (var i = 0; i < InitProvider.getHpoConfig().otherftis.length; i++) {
          var conf = InitProvider.getHpoConfig().otherftis[i];
          if (conf && conf.uid && conf.uid === fti.uid) {
            response = true;
            break;
          }
        }
      }
      return response;
    }

    function getComponentName(type) {
      return HPO_COMPONENTS[type];
    }

    /**
     * FONCTIONALITIES
     */
    /**
     * Get features by type of app
     */
    function getFeatureTypes(type) {
      if (typeof type === 'string') {
        if (type === 'home') {
          var elements = {};
          FeatureTypeFactory.resources.featuretypes.map(function(x) {
            for (var key in HPO_COMPONENTS[type]) {
              if (
                key &&
                HPO_COMPONENTS[type].hasOwnProperty(key) &&
                x.name.indexOf(HPO_COMPONENTS[type][key]) !== -1
              ) {
                elements[key] = x.uid;
              }
            }
          });
          return elements;
        } else {
          return FeatureTypeFactory.resources.featuretypes.filter(function(x) {
            switch (type) {
              case 'admin':
                if (
                  x.name.indexOf(prefixes) === -1 &&
                  x.name.indexOf(prefixes_carte) === -1
                ) {
                  return x;
                }
                break;
              case 'all':
                if (
                  (HPO_COMPONENTS[type].indexOf(x.name) !== -1 &&
                    InitProvider.getHpoConfig().datastoreName ===
                      x.storeName) ||
                  getAdminConfig(x) ||
                  getAdminConfigAdded(x)
                ) {
                  return x;
                }
                break;
              default:
                if (
                  HPO_COMPONENTS[type].indexOf(x.name) !== -1 &&
                  InitProvider.getHpoConfig().datastoreName === x.storeName
                ) {
                  return x;
                }
                break;
            }
          });
        }
      } else if (typeof type === 'object' && type instanceof Array)
        return FeatureTypeFactory.resources.featuretypes.filter(function(x) {
          if (
            type.indexOf(x.name) !== -1 &&
            InitProvider.getHpoConfig().datastoreName === x.storeName
          )
            return x;
        });
    }

    function getPrefix() {
      return prefixes;
    }

    function getOtherPrefix() {
      return prefixes_carte;
    }

    function getFeatureTypeDefailName(name) {
      if (name === HPO_CANA) return HPO_CANA_DEFAILLANCE;
      else {
        return HPO_BRANCHEMENT_DEFAILLANCE;
      }
    }

    function getSrid() {
      return HPO_COMPONENTS.srid;
    }

    function getExcludedAttributes(name) {
      if (HPO_EXCLUSE_ATTRIBUTES[name]) return HPO_EXCLUSE_ATTRIBUTES[name];
      else return null;
    }

    function getDisabledEditAttributes(name) {
      if (HPO_DISABLED_EDIT_ATTRIBUTES[name])
        return HPO_DISABLED_EDIT_ATTRIBUTES[name];
      else return null;
    }

    function getTranslateAttributes(name) {
      if (HPO_TRANSLATE_ATTRIBUTES[name]) return HPO_TRANSLATE_ATTRIBUTES[name];
      else return null;
    }

    function formatDate(date) {
      var dateFormat = 'yyyy-MM-ddTHH:mm:ss.sssZ';
      return $filter('date')(date, dateFormat);
    }

    function formatDateShow(date, dateFormat) {
      var dateFormat = dateFormat || 'dd-MM-yyyy';
      return $filter('date')(date, dateFormat);
    }

    function getStringTypes() {
      return [
        'java.lang.String',
        'java.lang.Character',
        'java.lang.CharSequence',
      ];
    }

    function getDateTypes() {
      return [
        'java.util.Date',
        'java.util.TimeZone',
        'java.sql.Timestamp',
        'java.sql.Date',
      ];
    }

    function getNumberTypes() {
      return [
        'java.lang.Integer',
        'java.lang.Short',
        'java.lang.Double',
        'java.lang.Float',
        'java.math.BigDecimal',
        'java.lang.Long',
      ];
    }

    function getRealTypes() {
      return ['java.lang.Double', 'java.lang.Float', 'java.math.BigDecimal'];
    }

    function getAnalysisToolsAttributes() {
      return [
        {
          label: $filter('translate')('hpo.data.prepare.allanalysis'),
          value: 'allanalysis',
          type: 'attributes',
        },
        {
          label: $filter('translate')('hpo.data.prepare.dataanalysis'),
          value: 'dataanalysis',
          type: 'attributes',
        },
        {
          label: $filter('translate')('hpo.data.prepare.numberanalysis'),
          value: 'numberanalysis',
          type: 'attributes',
        },
        {
          label: $filter('translate')('hpo.data.prepare.stringanalysis'),
          value: 'stringanalysis',
          type: 'attributes',
        },
      ];
    }

    function getAnalysisToolsLines() {
      return [
        {
          label: $filter('translate')('hpo.data.prepare.uniqueanalysis'),
          value: 'uniqueanalysis',
          type: 'lines',
        },
        {
          label: $filter('translate')('hpo.data.prepare.distributionanalysis'),
          value: 'distributionanalysis',
          type: 'lines',
        },
        {
          label: $filter('translate')('hpo.data.prepare.doublonanalysis'),
          value: 'doublonanalysis',
          type: 'lines',
        },
        {
          label: $filter('translate')('hpo.data.prepare.emptyanalysis'),
          value: 'emptyanalysis',
          type: 'lines',
        },
      ];
    }

    function getAnalysisToolsTables() {
      return [
        /*{
                              "label" : $filter('translate')('hpo.data.prepare.compareanalysis'),
                              "value" : "compareanalysis",
                              "type" : "multiple"
                          },*/ {
          label: $filter('translate')('hpo.data.prepare.calculatoranalysis'),
          value: 'calculatoranalysis',
          type: 'multiple',
        },
      ];
    }

    function getAnalysisToolsFuites() {
      return [
        {
          label: $filter('translate')('hpo.data.prepare.fuiteanalysis'),
          value: 'fuiteanalysis',
          type: 'special',
        },
      ];
    }

    function getAnalysisToolsCompatility() {
      return [
        {
          label: $filter('translate')('hpo.data.prepare.compatibility'),
          value: 'compatibility',
          type: 'attributes',
        },
      ];
    }

    function getSuppAnalysisTools() {
      return {
        dataanalysis: [],
        numberanalysis: [],
        stringanalysis: [
          {
            name: $filter('translate')('hpo.data.prepare.fuiteanalysis'),
            label: $filter('translate')('hpo.data.prepare.fuiteanalysis'),
          },
        ],
        distributionanalysis: [],
        uniqueanalysis: [],
        emptyanalysis: [],
        compareanalysis: [],
        calculatoranalysis: [],
        fuiteanalysis: [],
      };
    }

    function getFuitePrefix() {
      return 'DEFAILLANCE';
    }

    function getFuiteAnalysisAttributes() {
      return [
        {
          name: 'id',
          alias: $filter('translate')('hpo.data.prepare.id'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'type',
          alias: $filter('translate')('hpo.data.prepare.type'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'idcana',
          alias: $filter('translate')('hpo.data.prepare.idcana'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'acceptable',
          alias: $filter('translate')('hpo.data.prepare.acceptable'),
          type: 'java.lang.Boolean',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'description',
          alias: $filter('translate')('hpo.data.prepare.description'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'datefuite',
          alias: $filter('translate')('hpo.data.prepare.datefuite'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'datepose',
          alias: $filter('translate')('hpo.data.prepare.datepose'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'dateabandon',
          alias: $filter('translate')('hpo.data.prepare.dateabandon'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'column',
          alias: $filter('translate')('hpo.data.prepare.column'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'value',
          alias: $filter('translate')('hpo.data.prepare.value'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'count',
          alias: $filter('translate')('chart.count'),
          type: 'java.lang.Integer',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
      ];
    }

    function getCreationAutoAttributes() {
      return [
        {
          name: 'id',
          alias: $filter('translate')('hpo.data.prepare.id'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'type',
          alias: $filter('translate')('hpo.data.prepare.type'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'alias',
          alias: $filter('translate')('hpo.data.prepare.alias'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'name',
          alias: $filter('translate')('hpo.data.prepare.name'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'categorie',
          alias: $filter('translate')('hpo.data.prepare.categorie'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'description',
          alias: $filter('translate')('hpo.data.prepare.description'),
          type: 'java.lang.String',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
        {
          name: 'acceptable',
          alias: $filter('translate')('hpo.data.prepare.acceptable'),
          type: 'java.lang.Boolean',
          isNillable: false,
          size: 500,
          restrictions: [],
          popup: false,
          autoCalcul: null,
        },
      ];
    }

    function getAttributesToTranslate() {
      return ['type', 'TYPE', 'description'];
    }

    function getCorrectionToolsAttributes() {
      return [
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.retypage'
          ),
          value: 'retypage',
          type: 'attributes',
        },
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.createorremove'
          ),
          value: 'createorremove',
          type: 'attributes',
        },
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.jointrim'
          ),
          value: 'jointrim',
          type: 'attributes',
        },
      ];
    }

    function getCorrectionToolsValues() {
      return [
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.changevalue'
          ),
          value: 'changevalue',
          type: 'values',
        },
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.trimvalues'
          ),
          value: 'trim',
          type: 'values',
        },
        /*{
                              "label" : $filter('translate')('hpo.data.prepare.correctiontools.changeformatdate'),
                              "value" : "changeformatdate",
                              "type" : "values"
                          },*/ {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.changevaluereal'
          ),
          value: 'changevaluereal',
          type: 'values',
        },
      ];
    }

    function getCorrectionToolsDoublon() {
      return [
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.doublons'
          ),
          value: 'doublons',
          type: 'doublon',
        },
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.emptyline'
          ),
          value: 'emptyline',
          type: 'emptyline',
        },
      ];
    }

    function getCorrectionToolsGeneral() {
      return [
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.diversreplace'
          ),
          value: 'diversreplace',
          type: 'divers',
        },
        {
          label: $filter('translate')(
            'hpo.data.prepare.correctiontools.diversremove'
          ),
          value: 'diversremove',
          type: 'divers',
        },
      ];
    }

    function getCorrectionToolsFuites() {
      return [
        {
          label: $filter('translate')('hpo.data.prepare.correctiontools.fuite'),
          value: 'fuite',
          type: 'special',
        },
      ];
    }

    function getCalcAttribute() {
      return {
        name: 'CALC',
        alias: $filter('translate')('hpo.data.prepare.calc'),
        type: 'java.lang.Double',
        isNillable: false,
        size: 500,
        restrictions: [],
        popup: false,
        autoCalcul: null,
      };
    }

    let getAttributesWithFilter = (attributes) => {
      const attributesFiltred = attributes.filter(Attr => Attr.showInDataTable);
      return attributesFiltred.length>0?attributesFiltred:attributes;
    }

    function getScoreAttribute() {
      return {
        name: 'CALC',
        alias: $filter('translate')('hpo.multicritere.retenu.calc'),
        type: 'java.lang.Double',
        isNillable: false,
        size: 500,
        restrictions: [],
        popup: false,
        autoCalcul: null,
      };
    }

    function getCoutAttribute() {
      return {
        name: 'CALC_2',
        alias: $filter('translate')('hpo.multicritere.retenu.enveloppe2'),
        type: 'java.lang.Double',
        isNillable: false,
        size: 500,
        restrictions: [],
        popup: false,
        autoCalcul: null,
      };
    }

    /**
     * SERVICES
     */
    /**
     * Get HpoConfig by portalid
     */
    function getConfig() {
      var promise = $http.get('/services/{portalid}/hpoapp/init/get');

      return promise;
    }

    /**
     * update HpoConfig by portalid
     * @param {object} hpoConfig
     */
    function updateConfig(hpoConfig, reinitialise) {
      if (!reinitialise) reinitialise = false;
      var app = '';
      if ($rootScope.xgos && $rootScope.xgos.sector)
        app = $rootScope.xgos.sector;
      var promise = $http.post(
        '/services/{portalid}/hpoapp/init/{appname}/update?reinitialise=' +
          reinitialise +
          '&app=' +
          app,
        hpoConfig
      );

      return promise;
    }

    /**
     * update HpoConfig by portalid
     * @param {object} hpoConfig
     */
    function addRelationChantiers(uid, uidrel) {
      var promise = $http.get(
        '/services/{portalid}/hpoapp/init/{appname}/addrelation/chantiers?uid=' +
          uid +
          '&uidrel=' +
          uidrel
      );

      return promise;
    }

    /**
     * update HpoConfig by portalid
     * @param {object} hpoConfig
     */
    function addRelationAdmin(uid, uidchantiers, sendata) {
      var promise = $http.post(
        '/services/{portalid}/hpoapp/init/{appname}/addrelation/admin?uid=' +
          uid +
          '&uidchantiers=' +
          uidchantiers,
        sendata
      );

      return promise;
    }

    /**
     * update HpoConfig by portalid
     * @param {object} hpoConfig
     */
    function removeFeaturesAdmin(uid, uidfuite, datastore) {
      var app = '';
      if ($rootScope.xgos && $rootScope.xgos.sector)
        app = $rootScope.xgos.sector;
      var promise = $http.get(
        '/services/{portalid}/hpoapp/init/{appname}/removeFeatures/admin?uid=' +
          uid +
          '&uidfuite=' +
          uidfuite +
          '&datastore=' +
          datastore +
          '&app=' +
          app
      );

      return promise;
    }

    /**
     * add component style
     **/
    function writeRelationAdminStyle(ftiuid, attributeName) {
      return $http.get(
        '/services/{portalid}/hpoapp/init/addrelationstyle?f=json&ftiuid=' +
          ftiuid +
          '&attributeName=' +
          attributeName
      );
    }

    function filterFunc(elements, name) {
      var b = false;
      if (elements && name) {
        if (name.toLowerCase().score(elements.toLowerCase()) > 0.1) b = true;
      } else {
        b = true;
      }
      return b;
    }

    function getHpoFilterModes(bool) {
      if (!bool) {
        return [
          {
            label: $filter('translate')('hpo.data.validation.table'),
            id: 'table',
          } /*,
                  {
                    'label' : $filter('translate')('hpo.data.validation.map'),
                    'id' : 'map'
                  }*/,
        ];
      } else {
        return [
          {
            label: $filter('translate')('hpo.data.validation.table'),
            id: 'table',
          },
        ];
      }
    }

    function getById(ftis, uid) {
      var idx = ftis
        .map(function(x) {
          return x.uid;
        })
        .indexOf(uid);
      if (~idx) return ftis[idx];
      else {
        return null;
      }
    }
    function getByName(ftis, name) {
      var idx = ftis
        .map(function(x) {
          return x.name;
        })
        .indexOf(name);
      if (~idx) return ftis[idx];
      else {
        return null;
      }
    }

    function numberWithSpaces(x) {
      var parts = x.toString().split('.');
      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
      return parts.join('.');
    }

    function getOtherFeatures(x) {
      var ftis = FeatureTypeFactory.resources.featuretypes
        .map(function(x) {
          if (
            x.name.indexOf(prefixes) === -1 &&
            x.name.indexOf(prefixes_carte) === -1 &&
            !getAdminConfig(x)
          )
            return x;
        })
        .filter(function(x) {
          if (x) return x;
        });
      return ftis;
    }

    function getAttributesCalage(fti) {
      var res = {
        required: [],
        available: [],
      };
      if (
        fti.name.indexOf(prefixes) !== -1 &&
        fti.name.indexOf(prefixes_carte) !== -1
      ) {
        fti.attributes.map(function(x) {
          if (!~HPO_EXCLUSE_ATTRIBUTES['CALAGE'].indexOf(x.name)) {
              res.available.push(angular.copy(x));
          }
        });
      } else {
        var config = InitProvider.getHpoConfig();
        if (config.currentResources) {
          var toaddattributes = [];
          var excludeattributes = [];
          for (var i = 0; i < config.currentResources.length; i++) {
            var x = config.currentResources[i];
            if (x.uid === fti.uid) {
              excludeattributes.push(x.identifiant);
              excludeattributes.push('fid');
              toaddattributes.push(x.materiau);
              toaddattributes.push(x.diametre);
              toaddattributes.push(x.date_de_pose);
              break;
            }
          }
          fti.attributes.map(function(x) {
            if (!~excludeattributes.indexOf(x.name)) {
              if (~toaddattributes.indexOf(x.name))
                res.required.push(angular.copy(x));
              else {
                res.available.push(angular.copy(x));
              }
            }
          });
        }
      }
      return res;
    }

    function getJeuTableName(identifiantdata, ftiname) {
      return identifiantdata.substring(0, 7) + '_' + ftiname;
    }

    function getCalageTableName(identifiantdata, identifiantcalage) {
      return (
        identifiantdata.substring(0, 7) +
        '_CALAGE_' +
        identifiantcalage.substring(0, 7)
      );
    }

    function getValidationTableName(identifiantdata, identifiantcalage) {
      return (
        identifiantdata.substring(0, 7) +
        '_VALIDATION_' +
        identifiantcalage.substring(0, 7)
      );
    }

    function getPrevisionTableName(identifiantdata, identifiantcalage) {
      return (
        identifiantdata.substring(0, 7) +
        '_PREVISION_' +
        identifiantcalage.substring(0, 7)
      );
    }

    function differenceDates(date1, date2) {
      var today = new Date(date1);
      var Christmas = new Date(date2);
      var diffMs = Christmas - today;
      var diffDays = Math.floor(diffMs / 86400000); // days
      var diffHrs = Math.floor((diffMs % 86400000) / 3600000); // hours
      var diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000);
      var diffSecs = Math.round((((diffMs % 86400000) % 3600000) / 60000) * 60);
      if (diffDays > 0) {
        return {
          diff: diffDays,
          unit: $filter('translate')('hpo.common.days'),
        };
      } else if (diffHrs > 0) {
        return {
          diff: diffHrs,
          unit: $filter('translate')('hpo.common.hours'),
        };
      } else if (diffMins > 0) {
        return {
          diff: diffMins,
          unit: $filter('translate')('hpo.common.minutes'),
        };
      } else {
        return {
          diff: diffSecs,
          unit: $filter('translate')('hpo.common.seconds'),
        };
      }
    }

    function getRandomInteger() {
      return Math.round(Math.random() * 1000000000) + '';
    }

    function csvJSON(csv, sep) {
      var lines = csv.split('\n');

      var result = [];

      var headerst = lines[0].split(sep);
      var headers = [];
      headerst.map(function(x) {
        if (typeof x === 'string')
          headers.push(x.replace(/"/g, '').replace(/'/g, ''));
        else headers.push(x);
      });

      for (var i = 1; i < lines.length; i++) {
        if(lines[i] !== ""){
          var obj = {};
          var currentline = lines[i].split(sep);

          for (var j = 0; j < headers.length; j++) {
            if(currentline[j] !== "" &&!isNaN(currentline[j])){
              obj[headers[j]] = parseFloat(currentline[j]);
            }else if (typeof currentline[j] === 'string'){
              obj[headers[j]] = currentline[j]
                .replace(/"/g, '')
                .replace(/'/g, '');
            }else {
              obj[headers[j]] = currentline[j];
            }
          }

          result.push(obj);
        }
      }

      //return result; //JavaScript object
      return result; //JSON
    }

    function updateFtiWithAttributs(model, attributsList) {
      attributsList.forEach(attribut => {
        if(!model.fti.attributes.find(a=>a.name==attribut)){
          model.fti.attributes.push({name: attribut, alias:attribut, type: 'java.lang.String'});
        }
      });
      return model;
    }

    function getHpoSpecialAttributes() {
      return [
        'start',
        'end',
        'time',
        'age',
        'timeforrsf',
        'taux_casses_obs',
        'taux_casses_cox',
        'taux_casses_cox_survival',
        'taux_casses_rsf',
        'nb_casses',
        'nb_casses_cox',
        'nb_casses_cox_survival',
        'nb_casses_rsf',
        'nb_casses_cox_cumul',
        'nb_casses_cox_survival_cumul',
        'nb_casses_rsf_cumul',
        'nb_casses_obs_cumul',
        'nb_obs_cumul_fitcox',
        'nb_obs_cumul_fitcox_surv',
        'nb_obs_cumul_rsf',
        'longueur_cumul_fitcox',
        'longueur_cumul_fitcox_surv',
        'longueur_cumul_rsf',
        'aire_fitcox',
        'aire_fitcox_surv',
        'aire_rsf',
        'aire_lng_fitcox',
        'aire_lng_fitcox_surv',
        'aire_lng_rsf',
        'lng_nb_casses_cox_cumul',
        'lng_nb_casses_cox_survival_cumul',
        'lng_nb_casses_rsf_cumul',
        'lng_nb_casses_obs_cumul',
        'lng_nb_obs_cumul_fitcox',
        'lng_nb_obs_cumul_fitcox_surv',
        'lng_nb_obs_cumul_rsf',
      ];
    }

    function getBestScore(attributes, attr) {
      var scores = attributes.map(function(x) {
        return x.toLowerCase().score(attr.toLowerCase());
      });
      var maxScore = Math.max.apply(null, scores);
      if (maxScore > 0.1) {
        return attributes[scores.indexOf(maxScore)];
      } else {
        return undefined;
      }
    }

    function getAttributesForAuto(fti) {
      var anneepose, longueur, materiau, diametre, trafic, sol, chlorure, ilp;
      if (
        fti.name &&
        fti.name.indexOf(prefixes) !== -1 &&
        fti.name.indexOf(prefixes_carte) !== -1
      ) {
        anneepose = 'DATE_DE_POSE';
        longueur = 'LONGUEUR';
        materiau = 'MATERIAU';
        diametre = 'DIAMETER';
        trafic = 'TRAFIC_ROUTIER';
        sol = 'HYDRO_SOL';
        chlorure = 'CVM';
        ilp = 'ILP';
      } else {
        // TODO Correspondance composant
        if (
          InitProvider.getHpoConfig().currentResources &&
          InitProvider.getHpoConfig().currentResources.length > 0
        ) {
          for (
            var i = 0;
            i < InitProvider.getHpoConfig().currentResources.length;
            i++
          ) {
            var current = InitProvider.getHpoConfig().currentResources[i];
            if (current.uid === fti.uid) {
              anneepose = current.date_de_pose;
              longueur = current.longueur;
              materiau = current.materiau;
              diametre = current.diametre;
              var attributes = fti.attributes.map(function(x) {
                return x.name;
              });
              trafic = getBestScore(attributes, 'trafic');
              sol = getBestScore(attributes, 'sol');
              if (angular.isUndefined(sol))
                sol = getBestScore(attributes, 'couvert');
              chlorure = getBestScore(attributes, 'cvm');
              ilp = getBestScore(attributes, 'ilp');
            }
          }
        }
      }
      return [
        {
          name: 'anneepose',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.anneepose'
          ),
          selection: anneepose,
        },
        {
          name: 'longueur',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.longueur'
          ),
          selection: longueur,
        },
        {
          name: 'materiau',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.materiau'
          ),
          selection: materiau,
        },
        {
          name: 'diametre',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.diametre'
          ),
          selection: diametre,
        },
        {
          name: 'trafic',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.trafic'
          ),
          selection: trafic,
        },
        {
          name: 'sol',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.sol'
          ),
          selection: sol,
        },
        {
          name: 'chlorure',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.chlorure'
          ),
          selection: chlorure,
        },
        {
          name: 'ilp',
          alias: $filter('translate')(
            'hpo.multicritere.automatisation.attributes.ilp'
          ),
          selection: ilp,
        },
      ];
    }

    function getMulticritereFtis() {
      var ftis = [];
      var ftis_valid = getFeatureTypes('valid');
      var ftisnodefail_valid = getFeatureTypes('valid_no_defail');
      var ftisdefail_valid = getFeatureTypes('valid_defail');

      var ftist = getFeatureTypes('all');
      for (var i = 0; i < ftist.length; i++) {
        var fti = ftist[i];
        if (!getFuiteTables(fti)) {
          ftis.push(fti);
        }
      }
      return ftis;
    }

    function hasHpoRole() {
      let user = InitProvider.getUser();
      return user.roles.findIndex(role => role.name.includes('HpoRole'))!=-1;
    }

    function getAuthorizedAttributes(fti, readOrWrite) {
      if (fti) {
        var isAdmin =
          $rootScope.xgos.isroot ||
          $rootScope.xgos.isadmin || hasHpoRole();
        if (isAdmin) return fti.attributes.filter(att => att.name !== 'fid');

        var userRights = [];
        $rootScope.xgos.user.roles.forEach(function(role) {
          role.authorizations.forEach(function(authorization) {
            if (authorization.item == fti.uid) {
              authorization.subItems.forEach(function(sub) {
                userRights[sub.item] = {
                  read: sub.read,
                  write: sub.write,
                };
              });
            }
          });
        });
        $rootScope.xgos.user.groups.forEach(function(group) {
          group.roles.forEach(function(inRole) {
            inRole.authorizations.forEach(function(inAuthorization) {
              if (inAuthorization.item == fti.uid) {
                inAuthorization.subItems.forEach(function(inSub) {
                  userRights[inSub.item] = {
                    read:
                      userRights[inSub.item] == undefined ||
                      !userRights[inSub.item].read
                        ? inSub.read
                        : true,
                    write:
                      userRights[inSub.item] == undefined ||
                      !userRights[inSub.item].write
                        ? inSub.write
                        : true,
                  };
                });
              }
            });
          });
        });

        var authorizedAttrs = [];
        if (fti.attributes) {
          for (var i = 0; i < fti.attributes.length; i++) {
            var attr = fti.attributes[i];
            if (readOrWrite === 'w') {
              if (
                userRights[attr.name] != undefined &&
                userRights[attr.name].write == true
              )
                authorizedAttrs.push(attr);
            } else {
              if (
                userRights[attr.name] != undefined &&
                userRights[attr.name].read == true
              )
                authorizedAttrs.push(attr);
            }
          }
        }
        return authorizedAttrs;
      } else {
        return [];
      }
    }

    function isAuthorisedToAddAttribute(fti) {
      if (fti) {
        var isAdmin =
          $rootScope.xgos.isroot ||
          $rootScope.xgos.isadmin || hasHpoRole();
        if (isAdmin) return true;

        var response = false;

        var userRights = {};
        $rootScope.xgos.user.roles.forEach(function(role) {
          role.authorizations.forEach(function(authorization) {
            if (authorization.item == fti.uid && authorization.create) {
              response = true;
            }
          });
        });

        return response;
      } else {
        return true;
      }
    }

    function isAuthorisedToDeleteAttribute(fti) {
      if (fti) {
        var isAdmin =
          $rootScope.xgos.isroot ||
          $rootScope.xgos.isadmin || hasHpoRole();
        if (isAdmin) return true;

        var response = false;

        var userRights = {};
        $rootScope.xgos.user.roles.forEach(function(role) {
          role.authorizations.forEach(function(authorization) {
            if (authorization.item == fti.uid && authorization.remove) {
              response = true;
            }
          });
        });

        return response;
      } else {
        return true;
      }
    }

    function checkDeleteStandardisations(resultat) {
      let identifiants = resultat
            .map(function(x) {
              return x.properties.IDENTIFIANT;
            })
            .join("','");
          $timeout(() => {
            let callback = (confirmed) => {
              if (confirmed) {
                let where = '"SELECTED_JEU" IN (\'' + identifiants + "')";
                gaDomUtils.showGlobalLoader();
                EditFactory.deleteWhere(getFeatureTypes('hpo_standardisation')[0].uid, where).then((res) => {
                  gaDomUtils.hideGlobalLoader();
                  checkDeleteModel(identifiants);
                  AlertHpoFactory.successDelete();
                },()=>{
                  gaDomUtils.hideGlobalLoader();
                  AlertHpoFactory.failDelete();
                });
              }
            }
            AlertHpoFactory.alertConfirmCallback(
              $filter('translate')('hpo.common.info'),
              $filter('translate')('hpo.model.choice.removeStandardisation'),
              'info',
              true,
              undefined,
              '#F50072',
              true,
              undefined,
              undefined,
              true,
              true,
              callback
            );
          }, 2000);
    }

    function checkDeleteModel(identifiants) {
          $timeout(() => {
            let callback = (confirmed) => {
              if (confirmed) {
                let where = '"ID_JEU_DONNEE" IN (\'' + identifiants + "')";
                gaDomUtils.showGlobalLoader();
                EditFactory.deleteWhere(getFeatureTypes('modal_historic')[0].uid, where).then((res) => {
                  gaDomUtils.hideGlobalLoader();
                  AlertHpoFactory.successDelete();
                  if(res && res.data && res.data.featuresHPO && res.data.featuresHPO.features &&
                    res.data.featuresHPO.features.length>0){
                      let identifiantModel = res.data.featuresHPO.features.map(function(x) {
                        return x.properties.IDENTIFIANT;
                      })
                      .join("','");
                      checkDeleteCalageValidation(identifiantModel);
                    }
                },()=>{
                  gaDomUtils.hideGlobalLoader();
                  AlertHpoFactory.failDelete();
                });
              }
            }
            AlertHpoFactory.alertConfirmCallback(
              $filter('translate')('hpo.common.info'),
              $filter('translate')('hpo.model.choice.removeModele'),
              'info',
              true,
              undefined,
              '#F50072',
              true,
              undefined,
              undefined,
              true,
              true,
              callback
            );
          }, 2000);
    }


    function checkDeleteCalageValidation(identifiants) {
      $timeout(() => {
        let callback = (confirmed) => {
          if (confirmed) {
            let where = '"IDENTIFIANT_MODELE" IN (\'' + identifiants + "')";
            gaDomUtils.showGlobalLoader();
            var promise1 = EditFactory.deleteWhere(
              getFeatureTypes('calage')[0].uid,
              where
            );
            var promise2 = EditFactory.deleteWhere(
              getFeatureTypes('validation')[0].uid,
              where
            );
            $q.all([promise1, promise2]).then((res) => {
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.successDelete();
              if(res[0] && res[0].data && res[0].data.featuresHPO && res[0].data.featuresHPO.features &&
                res[0].data.featuresHPO.features.length>0){
                  let identifiantCalage = res[0].data.featuresHPO.features.map(function(x) {
                    return x.properties.IDENTIFIANT;
                  })
                  .join("','");
                  checkDeletePrevision(identifiantCalage);
                }
            },()=>{
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.failDelete();
            });
          }
        }
        AlertHpoFactory.alertConfirmCallback(
          $filter('translate')('hpo.common.info'),
          $filter('translate')('hpo.model.choice.removevalidationcalage'),
          'info',
          true,
          undefined,
          '#F50072',
          true,
          undefined,
          undefined,
          true,
          true,
          callback
        );
      }, 2000);
    }

    function checkDeletePrevision(identifiants) {
      $timeout(() => {
        let callback = (confirmed) => {
          if (confirmed) {
            let where = '"IDENTIFIANT_CALAGE" IN (\'' + identifiants + "')";
            gaDomUtils.showGlobalLoader();
            EditFactory.deleteWhere(getFeatureTypes('prevision')[0].uid, where).then((res) => {
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.successDelete();
              if(res && res.data && res.data.featuresHPO && res.data.featuresHPO.features &&
                res.data.featuresHPO.features.length>0){
                  let identifiantPrevision = res.data.featuresHPO.features.map(function(x) {
                    return x.properties.IDENTIFIANT;
                  })
                  .join("','");
                  checkDeleteChantierAutomatique(identifiantPrevision);
                }
            },()=>{
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.failDelete();
            });
          }
        }
        AlertHpoFactory.alertConfirmCallback(
          $filter('translate')('hpo.common.info'),
          $filter('translate')('hpo.model.choice.removeprevision'),
          'info',
          true,
          undefined,
          '#F50072',
          true,
          undefined,
          undefined,
          true,
          true,
          callback
        );
      }, 2000);
    }

    function checkDeleteChantierAutomatique(identifiants) {
      $timeout(() => {
        let callback = (confirmed) => {
          if (confirmed) {
            let where = '"IDENTIFIANT_PREVISION" in (\'' + identifiants + "')";
            gaDomUtils.showGlobalLoader();
            EditFactory.deleteWhere(getFeatureTypes('hpo_chantier_automatique')[0].uid, where).then((res) => {
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.successDelete();
            },()=>{
              gaDomUtils.hideGlobalLoader();
              AlertHpoFactory.failDelete();
            });
          }
        }
        AlertHpoFactory.alertConfirmCallback(
          $filter('translate')('hpo.common.info'),
          $filter('translate')('hpo.model.choice.removeChantierAuto'),
          'info',
          true,
          undefined,
          '#F50072',
          true,
          undefined,
          undefined,
          true,
          true,
          callback
        );
      }, 2000);
    }


    return {
      HPO_CANA: function() {
        return HPO_CANA;
      },
      HPO_CANA_DEFAILLANCE: function() {
        return HPO_CANA_DEFAILLANCE;
      },
      HPO_BRANCHEMENT: function() {
        return HPO_BRANCHEMENT;
      },
      HPO_BRANCHEMENT_DEFAILLANCE: function() {
        return HPO_BRANCHEMENT_DEFAILLANCE;
      },
      HPO_COMPONENTS: function() {
        return HPO_COMPONENTS;
      },
      HPO_DIVERS_PARAMS: function() {
        return HPO_DIVERS_PARAMS;
      },
      HPO_CANA_VALID: function() {
        return HPO_CANA_VALID;
      },
      HPO_CANA_DEFAILLANCE_VALID: function() {
        return HPO_CANA_DEFAILLANCE_VALID;
      },
      HPO_BRANCHEMENT_VALID: function() {
        return HPO_BRANCHEMENT_VALID;
      },
      HPO_BRANCHEMENT_DEFAILLANCE_VALID: function() {
        return HPO_BRANCHEMENT_DEFAILLANCE_VALID;
      },
      initFactory: initFactory,
      getAppname: getAppname,
      getFeatureTypes: getFeatureTypes,
      getFeatureTypeDefailName: getFeatureTypeDefailName,
      getSrid: getSrid,
      getExcludedAttributes: getExcludedAttributes,
      getDisabledEditAttributes: getDisabledEditAttributes,
      getTranslateAttributes: getTranslateAttributes,
      formatDate: formatDate,
      formatDateShow: formatDateShow,
      getStringTypes: getStringTypes,
      getDateTypes: getDateTypes,
      getNumberTypes: getNumberTypes,
      getRealTypes: getRealTypes,
      getAnalysisToolsAttributes: getAnalysisToolsAttributes,
      getAnalysisToolsLines: getAnalysisToolsLines,
      getAnalysisToolsTables: getAnalysisToolsTables,
      getAnalysisToolsFuites: getAnalysisToolsFuites,
      getSuppAnalysisTools: getSuppAnalysisTools,
      getAnalysisToolsCompatility: getAnalysisToolsCompatility,
      getFuitePrefix: getFuitePrefix,
      getConfig: getConfig,
      updateConfig: updateConfig,
      addRelationChantiers: addRelationChantiers,
      addRelationAdmin: addRelationAdmin,
      removeFeaturesAdmin: removeFeaturesAdmin,
      filterFunc: filterFunc,
      getFuiteAnalysisAttributes: getFuiteAnalysisAttributes,
      getCreationAutoAttributes: getCreationAutoAttributes,
      getAttributesToTranslate: getAttributesToTranslate,
      getCorrectionToolsAttributes: getCorrectionToolsAttributes,
      getCorrectionToolsValues: getCorrectionToolsValues,
      getCorrectionToolsDoublon: getCorrectionToolsDoublon,
      getCorrectionToolsGeneral: getCorrectionToolsGeneral,
      getCorrectionToolsFuites: getCorrectionToolsFuites,
      getHpoFilterModes: getHpoFilterModes,
      parseNameForCheck: parseNameForCheck,
      getResourceFromUidCana:getResourceFromUidCana,
      getPrefix: getPrefix,
      getOtherPrefix: getOtherPrefix,
      getFuiteTables: getFuiteTables,
      getFuiteTableFrom: getFuiteTableFrom,
      getById: getById,
      numberWithSpaces: numberWithSpaces,
      getOtherFeatures: getOtherFeatures,
      getAdminConfig: getAdminConfig,
      getByName: getByName,
      getAttributesCalage: getAttributesCalage,
      getJeuTableName: getJeuTableName,
      getCalageTableName: getCalageTableName,
      getValidationTableName: getValidationTableName,
      getPrevisionTableName: getPrevisionTableName,
      differenceDates: differenceDates,
      getRandomInteger: getRandomInteger,
      csvJSON: csvJSON,
      getReportName: getReportName,
      getReportRecapitulatifName: getReportRecapitulatifName,
      getReportBilanName:getReportBilanName,
      isAppInitiated: isAppInitiated,
      getComponentName: getComponentName,
      getCalcAttribute: getCalcAttribute,
      getAttributesWithFilter:getAttributesWithFilter,
      getScoreAttribute: getScoreAttribute,
      getCoutAttribute: getCoutAttribute,
      getHpoSpecialAttributes: getHpoSpecialAttributes,
      getAttributesForAuto: getAttributesForAuto,
      getMulticritereFtis: getMulticritereFtis,
      getBestScore: getBestScore,
      getAuthorizedAttributes: getAuthorizedAttributes,
      isAuthorisedToAddAttribute: isAuthorisedToAddAttribute,
      isAuthorisedToDeleteAttribute: isAuthorisedToDeleteAttribute,
      writeRelationAdminStyle: writeRelationAdminStyle,
      updateFtiWithAttributs: updateFtiWithAttributs,
      checkDeleteStandardisations:checkDeleteStandardisations,
      checkDeleteModel:checkDeleteModel,
      checkDeleteCalageValidation:checkDeleteCalageValidation,
      checkDeletePrevision:checkDeletePrevision,
      checkDeleteChantierAutomatique:checkDeleteChantierAutomatique,
    };
  };
  HpoAppFactory.$inject = [
    '$http',
    'FeatureTypeFactory',
    '$filter',
    '$rootScope',
    '$location',
    'InitProvider',
    '$timeout',
    'AlertHpoFactory',
    'gaDomUtils',
    'EditFactory',
    '$q'
  ];
  return HpoAppFactory;
});
