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))
}