editGraphe/importGraphe.js

import $ from 'jquery'
import { importeNodeGraphe, getBranchementEntreDeuxNodes, getJspConnexionFromBranchementDomId, getConnexionDansGraphe, connexionNodes } from './fonctionsNodes'
import { traitementNoeudFin, getBranchements, actualiseGestionnaireEvenements } from './scene'
import { dispatch, getConfigGraphTmp, getPosition, getTitre } from './store'
import { setConfigGraphTmp, setPositions, setTitres, setObjetGrapheColor } from './actions'

/** @module editGraphe/importGraphe */

/**
 * Teste si on a un tableau vide
 * on a besoin de cette fonction car [] === [] renvoie toujours false, avec == aussi (pas la même instance d’Array)
 * @param tab
 * @returns {boolean}
 */
function isEmptyArray (tab) {
  return Array.isArray(tab) && tab.length === 0
}

export function importerGraphe (ressource, next) {
  let decalage = 20
  if (ressource && ressource.parametres && ressource.parametres.g && Array.isArray(ressource.parametres.g)) {
    // on a un graphe
    const grapheTab = ressource.parametres.g
    // on récupère ou initialise les positions des nodes
    if (!ressource.parametres.editgraphes || !ressource.parametres.editgraphes.positionNodes || !ressource.parametres.editgraphes.positionNodes.length) {
      // on boucle sur g pour avoir le même nb d’éléments que g
      // une version avec un map, qui retourne un nouveau tableau constitué de chaque elt renvoyé par la fct
      const positions = grapheTab.map(function () {
        decalage += 50
        return [decalage, decalage]
      })
      dispatch(setPositions(positions))
    } else {
      const positionNodes = ressource.parametres.editgraphes.positionNodes
      // on crée un nouveau tableau avec, pour chaque index la position récupérée ou un décalage
      const positions = positionNodes.map(function (positionNode) {
        if (positionNode && positionNode.length === 2) return positionNode
        decalage += 50
        return [decalage, decalage]
      })
      // pose pb
      dispatch(setPositions(positions))
    }
    // on récupère les titres spécifiques à editgraphe
    if (!ressource.parametres.editgraphes || !ressource.parametres.editgraphes.titreNodes) {
      const titreNodes = []
      // on boucle sur les éléments du graphe pour initialiser un titre
      grapheTab.forEach(function (elt, i) {
        // elt[0] est le numéro de noeud, elt[1] le nom de la section
        if (elt[1].toUpperCase() === 'FIN') {
          titreNodes[i] = 'Fin (nœud ' + elt[0] + ')'
        } else {
          titreNodes[i] = 'Nœud ' + elt[0]
        }
      })
      dispatch(setTitres(titreNodes))
    } else {
      dispatch(setTitres(ressource.parametres.editgraphes.titreNodes))
    }
    dispatch(setConfigGraphTmp(grapheTab))
    // permet d’ajouter de remplacer une branche nn:'fin' en nn:numero et d’avoir un autre noeud [numero,'fin',[]] pour voir l’embranchement sur la scène
    // n’est pas appelé si le graphe ne comporte qu’un noeud
    if (grapheTab.length > 1) traitementNoeudFin()
    const grapheTabModif = getConfigGraphTmp()
    // const objetGraphe = getObjetGraphe()
    // initialisation de l’auto-incrément de node
    // if (!objetGraphe.maxNumeroNode) setObjetGrapheProp('maxNumeroNode', 0)
    // on importe

    grapheTabModif.forEach(function (elt, index) {
      const position = getPosition(index)
      const x = (position && position[0]) || decalage + index * 50
      const y = (position && position[1]) || decalage + index * 50
      importeNodeGraphe(elt, x, y, getTitre(index))
    })
    actualiseGestionnaireEvenements(false)
  } else {
    console.error('pas de graphe, ça peut être normal si on va en créer un nouveau')
  }
  next()
  // importerGrapheFin(ressource)
}

/**
 * Importe sur la scene le graphe pour showParcours
 * @param {LegacyResultat} result le résultat que j3p avait envoyé
 */
export function importerGrapheAColorer (result) {
  const { graphe = [], editgraphes = {} } = result
  let { positionNodes = [], titreNodes = [] } = editgraphes
  // inspiré de importerGraphe de l’ancien code mais on file pas une ressource de la bibli
  // on affecte les positions
  let decalage = 20
  if (isEmptyArray(positionNodes)) {
    dispatch(setPositions(graphe.map(function () {
      decalage += 50
      return [decalage, decalage]
    })))
  } else {
    // on initialise ce qui pourrait manquer
    const positions = []
    for (let i = 0; i < graphe.length; i++) {
      const pos = positionNodes[i]
      if (pos && pos.length === 2) {
        positions.push(pos)
      } else {
        decalage += 50
        positions.push([decalage, decalage])
      }
    }
    dispatch(setPositions(positions))
  }

  // les titres
  if (isEmptyArray(titreNodes)) {
    titreNodes = graphe.map(function (elt) {
      if (elt[1].toUpperCase() === 'FIN') return 'Fin (nœud ' + elt[0] + ')'
      else return 'Nœud ' + elt[0]
    })
    dispatch(setTitres(titreNodes))
  } else {
    dispatch(setTitres(titreNodes))
  }
  setConfigGraphTmp(graphe)

  // permet d’ajouter de remplacer une branche nn:'fin' en nn:numero et d’avoir un autre noeud [numero,'fin',[]] pour voir l’embranchement sur la scène
  // n’est pas appelé si le graphe ne comporte qu’un noeud
  if (graphe.length > 1) {
    traitementNoeudFin()
  }

  // initialisation de l’auto-incrément de node
  // const objetGraphe = getObjetGraphe()
  // if (!objetGraphe.maxNumeroNode) setObjetGrapheProp('maxNumeroNode', 0)
  // et on positionne tout ça sur la scene
  graphe.forEach(function (elt, index) {
    const [x, y] = getPosition(index)
    // @todo voir pourquoi positions[k] n’existe pas toujours
    importeNodeGraphe(elt, x, y, getTitre(index))
  })
}

export function importerGrapheFin (next) {
  const graphe = getConfigGraphTmp()
  importerGrapheFinSP(graphe)
  // rappelé sans le param false pour pouvoir avoir les fenetres de dialogue pour les futurs branchements
  // TODO : dans le cas d’importerGraphe de la bibli avec une ressource, mettre cet actualiseGestionnaireEvenements dans le next (car pas besoin en cas de coloration de parcours)
  // actualiseGestionnaireEvenements()
  next()
}

export function importerGrapheFinSP (graphe) {
  // on parcourt à nouveau les noeuds du graphe
  for (const node of graphe) {
    if (Array.isArray(node)) {
      const [id, , params] = node
      if (params) {
        const infosBranchements = getBranchements(params)
        for (const info of infosBranchements) {
          if (info.nn) {
            connexionNodes('node' + id, 'node' + info.nn, id, info, 0)
            // PB !! à faire en callback normalement...
            // completeBranchement(noeudDepart, info, 0)
          } else {
            console.error(Error('Pas de nn dans ce branchement'), info)
          }
        }
      }
    } else {
      console.error(Error('nœud invalide => ignoré'), node)
    }
  }
}

export function coloreParcours ({ noeuds }) {
  for (const [index, noeud] of noeuds.entries()) {
    if (!(/fin/i).test(noeud)) {
      $('#node' + noeud).css('border', '4px solid #FF0000')
      if (index < noeuds.length - 1) {
        // ce n’est donc pas le dernier noeud du parcours (à condition qu’ils soient dans l’ordre…)
        const nextNoeud = noeuds[index + 1]
        const branchementId = getBranchementEntreDeuxNodes(noeud, nextNoeud)
        if (branchementId) changeCouleurBranchement(branchementId, '#FF0000')
        else console.error(Error(`Pas trouvé de branchement entre le node ${noeud} et ${nextNoeud}`), noeuds)
      }
    }
  }
}

// dialogue pour un branchement : changement de couleur, inutilisé car colorPicker pose pb avec les Modales
function changeCouleurBranchement (branchementDomId, couleur) {
  if (!branchementDomId) return console.error(Error('Il faut fournir un branchement'))
  // modification sur la scene
  let branchement = getJspConnexionFromBranchementDomId(branchementDomId)
  if (!branchement) return console.error(`Pas de branchement ${branchementDomId}, impossible de le colorer`)
  const paintStyle = branchement.getPaintStyle()
  // paintStyle.stroke = couleur;ce code modifier aussi la ppte paintStyleInUse d’autres branchements (pas compris pourquoi d’ailleurs) d’où la solution :
  branchement.setPaintStyle({ stroke: couleur, dashstyle: paintStyle.dashstyle, strokeWidth: paintStyle.strokeWidth })
  // modification dans objetGraphe
  branchement = getConnexionDansGraphe(branchementDomId)
  dispatch(setObjetGrapheColor(branchement.sourceNodeId, branchement.branchementIndex, couleur))
}