import { j3pClone } from 'src/legacy/core/functions'
import { notify } from 'sesajs/error'
class ScratchProg {
/**
* Constructeur du programme
* @param {Object} Blockly
* @param {Object} args
* @param {Array} args.letabeduprog
* @param {string} args.id
* @param {boolean} args.isTest
* @constructor
*/
constructor (Blockly, { scratch, options = {}, numProgDeTabcodex = 0 }) {
const { params } = scratch
this.vite = Boolean(options.vite)
this.sortie = options.sortie
this.workspace = options.workspace
params.leWork = this.workspace
params.cacheTest = options.cacheTest
this.cacheTest = options.cacheTest
params.scratchProgDonnees.workspace = this.workspace
params.scratchProgDonnees.tabcodeX = options.tabcodeX
params.scratchProgDonnees.valPourGetUs = j3pClone(options.valGetUs)
params.scratchProgDonnees.valAleaVerif = options.valAleaVerif
params.scratchProgDonnees.yaErreurMtg = undefined
params.scratchProgDonnees.nomsAleaChar = ['¶', '©', '®', '™', '♠', '♣', '♥', '♦', '↑', '↓', '↔']
params.scratchProgDonnees.nomsAlea = []
params.scratchProgDonnees.nomsAleaChar.forEach(element => {
params.scratchProgDonnees.nomsAlea.push(element, element + "'", element + '"')
for (let i = 0; i < 10; i++) {
params.scratchProgDonnees.nomsAlea.push(element + i, element + i + "'", element + i + '"')
}
})
params.scratchProgDonnees.nomsAleaBase = j3pClone(params.scratchProgDonnees.nomsAlea)
const objet = this
if (scratch.pasapas) {
objet.ModePasapas = scratch.pasapas.checked
scratch.pasapas.disabled = true
}
params.scratchProgDonnees.blokinput = false
params.scratchProgDonnees.x = ''
params.scratchProgDonnees.y = ''
params.scratchProgDonnees.z = ''
params.scratchProgDonnees.valGetDon = []
this.tab = scratch.copieDe(options.tabcodeX[numProgDeTabcodex])
// console.debug('tabcodeX', params.scratchProgDonnees.tabcodeX)
// console.debug('xmlwork', scratch.Blockly.Xml.workspaceToDom(params.scratchProgDonnees.workspace).innerHTML)
if (!params.modeCompare) scratch.traceSortieBase({ sortie: this.sortie })
scratch.remiseAzero()
params.toSouvSuite = []
scratch.remplaceMake(this.tab)
this.where = 0
this.chrono = null
this.dansquoi = [{ type: 'main', where: 0 }]
this.before = ''
params.scratchProgDonnees.yaEuVerif = false
params.valAlea = j3pClone(options.valAlea)
params.scratchProgDonnees.reponse = 'NaN'
params.scratchProgDonnees.Valeursutilisees = []
params.scratchProgDonnees.resetflag = true
this.k = []
this.memstack = ''
function scratchFoncBoutSuiv () {
if (params.scratchProgDonnees.pause) {
setTimeout(() => {
scratchFoncBoutSuiv()
}, 500)
} else {
params.BoutPasSuiv.push(objet.exeaction)
scratch.bouAaPaPa.classList.add('bouturg')
scratch.lesdivs.PASAPASBOOT.style.display = ''
}
}
this.elembywhere = function (el) {
while (objet.dansquoi.length > objet.comcompte + 1) {
if (objet.dansquoi[objet.comcompte + 1].type === 'boucle') {
el = scratch.copieDe(el[objet.dansquoi[objet.comcompte + 1].where].boucle)
}
if (objet.dansquoi[objet.comcompte + 1].type === 'boucleF') {
el = scratch.copieDe(el[objet.dansquoi[objet.comcompte + 1].where].boucle)
}
if (objet.dansquoi[objet.comcompte + 1].type === 'boucleU') {
el = scratch.copieDe(el[objet.dansquoi[objet.comcompte + 1].where].boucle)
}
if (objet.dansquoi[objet.comcompte + 1].type === 'sioui') {
el = scratch.copieDe(el[objet.dansquoi[objet.comcompte + 1].where].sioui)
}
if (objet.dansquoi[objet.comcompte + 1].type === 'sinon') {
el = scratch.copieDe(el[objet.dansquoi[objet.comcompte + 1].where].sinon)
}
objet.comcompte++
}
return el[objet.where]
}
this.trouveprochainordre = function () {
function execute (unelem) {
try {
if (objet.memstack) {
objet.workspace.glowBlock(objet.memstack, false)
}
if (unelem) {
objet.workspace.glowBlock(unelem.id, true)
objet.memstack = unelem.id
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
}
if (!unelem) return { result: 'fin' }
if (unelem.type === 'Mb') return { result: 'Mb', name: unelem.nom }
if (unelem.type === 'event') return { result: 'event' }
if (unelem.type === 'boucle') return { result: 'boucle' }
if (unelem.type === 'boucleF') return { result: 'boucleF' }
if (unelem.type === 'boucleU') return { result: 'boucleU' }
if (unelem.type === 'control_stop') return { result: 'control_stop' }
if (unelem.type === 'si') return { result: 'si' }
if (unelem.type === 'setValPerso') {
params.scratchProgDonnees.x = unelem.valX
params.scratchProgDonnees.y = unelem.valY
params.scratchProgDonnees.z = unelem.valZ
return { result: 'setValPerso' }
}
return unelem.javascript()
}
const elemencours = objet.elembywhere(scratch.copieDe(objet.tab))
let rep
this.lecompteur++
if (params.scratchProgDonnees.yaErreurMtg) {
rep = { result: 'prob', quoi: params.scratchProgDonnees.yaErreurMtg }
} else {
objet.comcompte = 0
rep = execute(elemencours)
}
if (this.lecompteur === 2000) {
notify('ya + de 2000 Tommy', { prog: objet.tab, result: rep })
objet.destroy()
const fflis = scratch.stopTout.bind(scratch)
fflis()
scratch.scratchVerifRun(objet.mod)
return
}
if (rep.result === 'ordrew') {
objet.where++
params.scratchProgDonnees.pause = true
if (this.cacheTest || params.cacheTest) params.scratchProgDonnees.pause = false
return true
}
if (rep.result === 'event') {
objet.where++
return true
}
if (rep.result === 'ordre') {
objet.where++
return true
}
if (rep.result === 'boucle') {
let numberName
try {
numberName = scratch.vireGuillemets(Blockly.JavaScript.valueToCode(elemencours.repete, 'TIMES', Blockly.JavaScript.ORDER_ATOMIC))
} catch (e) {
numberName = ' '
}
if (numberName === ' ' || numberName === '' || isNaN(numberName) || Number(numberName) < 0) {
rep.result = 'prob'
rep.quoi = 'Je ne parviens pas à<br> comprendre le nombre de répétitions !'
} else {
if (!elemencours.boucle) {
objet.where++
return { tempo: false, cont: true }
}
objet.dansquoi.push({
type: 'boucle',
kmax: Number(numberName),
k: 1,
itk: 1,
where: objet.where,
nom: 'boucle'
})
this.k.push(1)
objet.where = 0
if (Number(numberName) < 1) {
objet.k[objet.k.length - 1]++
if (objet.k[objet.k.length - 1] > objet.dansquoi[objet.dansquoi.length - 1].kmax) {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
objet.dansquoi.pop()
objet.k.pop()
return { tempo: false, cont: true }
} else {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
return { tempo: false, cont: true }
}
}
return { tempo: false, cont: true }
}
}
if (rep.result === 'boucleF') {
if (!elemencours.boucle) {
params.scratchProgDonnees.avertissements.push('Aucune instruction à répéter !')
return 'PROB'
}
objet.dansquoi.push({
type: 'boucleF',
where: objet.where,
nom: 'boucleF'
})
objet.where = 0
return { tempo: false, cont: true }
}
if (rep.result === 'boucleU') {
if (!elemencours.boucle) {
params.scratchProgDonnees.avertissements.push('Aucune instruction à répéter !')
return 'PROB'
}
const cond = scratch.vireGuillemets(Blockly.JavaScript.valueToCode(elemencours.repete, 'CONDITION', Blockly.JavaScript.ORDER_ATOMIC))
if (cond !== 'vrai') {
objet.dansquoi.push({
type: 'boucleU',
where: objet.where,
nom: 'boucleU',
id: elemencours.id,
repete: elemencours.repete,
workspace: this.workspace
})
objet.where = 0
return { tempo: false, cont: true }
} else {
objet.where++
return { tempo: false, cont: true }
}
}
if (rep.result === 'boucleF') {
if (!elemencours.boucle) {
objet.avertissements = ['Aucune instruction à répéter !']
return 'PROB'
}
objet.dansquoi.push({
type: 'boucleF',
where: objet.where,
nom: 'boucleF'
})
objet.where = 0
return { tempo: false, cont: true }
}
if (rep.result === 'si') {
/// faut tester la cond
let cond
if (objet.mod !== 'coco') {
cond = scratch.vireGuillemets(Blockly.JavaScript.valueToCode(this.workspace.getBlockById(elemencours.id), 'CONDITION', Blockly.JavaScript.ORDER_ATOMIC))
} else { cond = scratch.vireGuillemets(Blockly.JavaScript.valueToCode(params.scratchProgDonnees.workspaceco.getBlockById(elemencours.id), 'CONDITION', Blockly.JavaScript.ORDER_ATOMIC)) }
if (cond === 'erreur block vide') {
params.scratchProgDonnees.avertissements.push('Il manque une condition !')
return 'PROB'
}
if (cond === 'vrai') {
if (!elemencours.sioui) {
objet.where++
return { tempo: false, cont: true }
}
objet.dansquoi.push({ type: 'sioui', where: objet.where, nom: 'sioui' })
objet.where = 0
return { tempo: false, cont: true }
} else {
if (!elemencours.sinon) {
objet.where++
return { tempo: false, cont: true }
}
objet.dansquoi.push({ type: 'sinon', where: objet.where, nom: 'sinon' })
objet.where = 0
return { tempo: false, cont: true }
}
}
if (rep.result === 'fin') {
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'boucle') {
objet.k[objet.k.length - 1]++
if (objet.k[objet.k.length - 1] > objet.dansquoi[objet.dansquoi.length - 1].kmax) {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
objet.dansquoi.pop()
objet.k.pop()
return { tempo: false, cont: true }
} else {
objet.where = 0
return { tempo: false, cont: true }
}
}
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'sioui') {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
objet.dansquoi.pop()
return { tempo: false, cont: true }
}
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'sinon') {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
objet.dansquoi.pop()
return { tempo: false, cont: true }
}
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'boucleU') {
const cond = scratch.vireGuillemets(Blockly.JavaScript.valueToCode(objet.dansquoi[objet.dansquoi.length - 1].repete, 'CONDITION', Blockly.JavaScript.ORDER_ATOMIC))
if (cond !== 'vrai') {
objet.where = 0
return { tempo: false, cont: true }
} else {
objet.where = objet.dansquoi[objet.dansquoi.length - 1].where + 1
objet.dansquoi.pop()
return { tempo: false, cont: true }
}
}
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'boucleF') {
objet.where = 0
return { tempo: false, cont: true }
}
if (objet.dansquoi[objet.dansquoi.length - 1].type === 'main') {
return 'FIN'
}
}
if (rep.result === 'setValPerso') {
objet.where++
return { tempo: false, cont: true }
}
if (rep.result === 'control_stop') {
return 'FIN'
}
if (rep.result === 'prob') {
params.scratchProgDonnees.avertissements.push(rep.quoi)
return 'PROB'
}
}
this.exeaction = function () {
if (params.scratchProgDonnees.fostop) {
params.scratchProgDonnees.sortieAvecProb = true
params.scratchProgDonnees.avertissements.push('Tu as interrompu le programme')
scratch.scratchVerifRun()
return
}
if (params.scratchProgDonnees.fostopErreur) {
params.scratchProgDonnees.sortieAvecProb = true
params.scratchProgDonnees.avertissements.push(params.scratchProgDonnees.fostopErreurText)
scratch.scratchVerifRun()
return
}
if (params.scratchProgDonnees.pause) {
objet.chrono = setTimeout(objet.exeaction, 1000)
return
}
if (params.grosStop) return
const quoifaire = objet.trouveprochainordre()
// console.debug('quoifaire', quoifaire)
scratch.testFlag()
if (quoifaire === 'FIN') {
params.scratchProgDonnees.sortieAvecProb = false
scratch.scratchVerifRun()
return
}
if (quoifaire === 'PROB') {
params.scratchProgDonnees.sortieAvecProb = true
params.scratchProgDonnees.avertissements.push('Je ne peux pas exécuter cet ordre !<BR>' + params.scratchProgDonnees.avertissements[params.scratchProgDonnees.avertissements.length - 1])
scratch.scratchVerifRun()
return
}
if (!objet.ModePasapas) {
if (quoifaire === true && (!objet.vite)) {
objet.chrono = setTimeout(objet.exeaction, 1000)
} else {
objet.exeaction()
}
} else {
scratchFoncBoutSuiv()
}
}
this.exeaction()
}
}
export default ScratchProg