import { j3pAjouteDiv, j3pAjouteZoneTexte, j3pComplete, j3pDiv, j3pElement } from 'src/legacy/core/functions'
import { hasProp } from 'sesajs/object'
import { j3pMathsAjouteDans } from 'src/lib/mathquill/functions'
import { j3pCreeRectangle, j3pCreeSegment, j3pCreeSVG, j3pCreeTexte, j3pCreeVirgule } from 'src/legacy/core/functionsSvg'
/**
* Outil tableauconversion pour créer un tableau de conversion
* @name TableauConversion
* @param {HTMLElement|string} container
* @param {Object} [values]
* @constructor
*/
function TableauConversion (container, values) {
if (!this || typeof this !== 'object') throw Error('Constructeur qui doit être appelé avec new')
/*
this.lesclasses = ["milliards","millions","milliers","unites","milliemes","millioniemes"]
values = {`
idDIV : string; // id du div contenant le tableau
classes : [i,j],
// i < j et 0:"milliards" , 1:"millions" , 2:"milliers" , 3:"unites" , 4:"milliemes" , 5:"millioniemes"
format : {
idDIV:"tableau",
classes:[2,4],
format :{
top : 10,
left:10,
labelsclasses:true,
labelscols:true,
hclasse:70,
hcol:50,
hlig:70,
largeurcol:60,
police:"times new roman",
taillepolice : 20,
taillechiffres : 28,
taillevirgule : 20,
epaisseurs :{
separateurclasses : 4,
ligneclasse : 4,
lignecols : 3,
separateurcols : 3,
lignehorizontale : 1,
cadre : 6
},
couleurs:{
labels:"#000000",
cols:"#000000",
chiffres:"#000000",
virgule:"#000000",
separateurclasses:"#00506B",
separateurcols:"#009DD1",
lignehorizontale:"#009DD1",
lignehorizontaleclasse:"#00506B",
lignehorizontalecdu:"#00506B",
cadre:"#002EB8"
}
}
lignes : Array
lignes[k] : contenu de la ligne k
lignes[k] = {
milliards:[a,b,c],
millions:[a,b,c],
milliers:[a,b,c],
unites:[a,b,c],
milliemes:[a,b,c],
millioniemes:[a,b,c]
}
AVEC
a = "." ==> FERME
a = "?_" ==> ZDT vide
a = "?5" ==> ZDT contenant le chiffre 5
a = 4 ==> chiffre 4 dans la case
}
*/
/**
* Le conteneur du tableau
* @memberOf TableauConversion
* @type {HTMLElement}
*/
this.container = (typeof container === 'string') ? j3pElement(container) : container
/**
* Id du conteneur, peut être undefined
* @memberOf TableauConversion
* @deprecated
* @type {string}
*/
this.conteneur = this.container.id
this.idDIV = values.idDIV
this.lesclasses = ['Milliards', 'Millions', 'Milliers', 'Unités', 'Millièmes', 'Millionièmes']
// Définition de toutes les propriétés et initialisation si absence dans values
this.classes = values.classes
// le format, avec ces valeurs par défaut
const defaultFormat = {
relative: false,
top: 0,
left: 0,
labelsclasses: true,
labelscols: true,
labelscolsdecimaleslettres: false,
virgule: [false, false, false, false, false, false, false],
// nblignes est imposé par la taille de values.lignes
hclasse: 40,
hcol: 40,
hlig: 50,
largeurcol: 50,
police: 'verdana',
taillepolice: 20,
taillepoliceclasses: 20,
taillechiffres: 20,
taillevirgule: 20,
epaisseurs: {
separateurclasses: 4,
separateurcols: 3,
lignehorizontale: 1,
cadre: 6,
ligneclasse: 4,
lignecols: 3
},
couleurs: {
labels: '#000000',
cols: '#339966',
chiffres: '#000000',
virgule: '#000000',
separateurclasses: '#00506B',
separateurcols: '#009DD1',
lignehorizontaleclasse: '#00506B',
lignehorizontalecdu: '#00506B',
lignehorizontale: '#009DD1',
cadre: '#002EB8'
}
}
this.format = j3pComplete(defaultFormat, values.format)
// on remet virgule au cas où ce serait autorisé de passer un nb d’élément ≠ de celui par défaut
if (values.format && Array.isArray(values.format.virgule)) this.format.virgule = values.format.virgule
this.lignes = values.lignes
this.format.nblignes = this.lignes.length
this.hauteurSVG = this.format.nblignes * this.format.hlig
if (this.format.labelsclasses) this.hauteurSVG += this.format.hclasse
if (this.format.labelscols) this.hauteurSVG += this.format.hcol
let nbcol = 0
this.premiereclasse = 0
let trouve = false
for (let k = 0; k < this.lignes[0].length; k++) {
if (this.lignes[0][k].length !== 0) {
nbcol++
if (!trouve) {
this.premiereclasse = k
trouve = true
}
}
}
this.largeurSVG = 3 * nbcol * this.format.largeurcol
this.nbcol = 3 * nbcol
this.construit()
}
TableauConversion.prototype.construit = function () {
/**
* Retourne this.idDIV + suffix, ou undefined
* @param {string} suffix
* @return {string|undefined}
*/
function getId (suffix) {
if (idConteneur) return idConteneur + suffix
}
const idConteneur = this.idDIV
const styleTab = {
position: (this.format.relative ? 'relative' : 'absolute')
}
// on ne le précise que si on l’avait fourni (ou que top a été affecté dans le constructeur
if (hasProp(this.format, 'top')) styleTab.top = this.format.top + 'px'
if (hasProp(this.format, 'left')) styleTab.left = this.format.left + 'px'
// si on est positionné en absolu mais que notre parent n’est pas positionné ça déconne
// visiblement y’a eu une modif qq part qui ne fait plus de positionnement systématique
// on sait pas très bien où, donc on l’ajoute ici
if (styleTab.position === 'absolute' && (!this.container.style || !this.container.style.position)) {
if (!this.container.style) this.container.style = {}
this.container.style.position = 'relative'
}
const divSvg = j3pAjouteDiv(this.container, this.idDIV, '', {
style: styleTab
})
const svg = j3pCreeSVG(divSvg, {
id: getId('svg'),
width: this.largeurSVG,
height: this.hauteurSVG
})
j3pCreeRectangle(svg, {
id: getId('cadre'),
x: 0,
y: 0,
width: this.largeurSVG,
height: this.hauteurSVG,
couleur: this.format.couleurs.cadre,
couleurRemplissage: '',
epaisseur: this.format.epaisseurs.cadre
})
let decal = 0
if (this.format.labelsclasses) {
// permier trait horizontal
decal += this.format.hclasse
j3pCreeSegment(svg, {
id: getId('ligneclasses'),
x1: 0,
y1: decal,
x2: this.largeurSVG,
y2: decal,
couleur: this.format.couleurs.lignehorizontaleclasse,
epaisseur: this.format.epaisseurs.ligneclasse
})
}
if (this.format.labelscols) {
decal += this.format.hcol
j3pCreeSegment(svg, {
id: getId('lignecols'),
x1: 0,
y1: decal,
x2: this.largeurSVG,
y2: decal,
couleur: this.format.couleurs.lignehorizontalecdu,
epaisseur: this.format.epaisseurs.lignecols
})
}
let k, u, v, ch, numligne
for (k = 0; k < this.format.nblignes - 1; k++) {
j3pCreeSegment(svg, {
id: getId('lignelig' + k),
x1: 0,
y1: decal + (k + 1) * this.format.hlig,
x2: this.largeurSVG,
y2: decal + (k + 1) * this.format.hlig,
couleur: this.format.couleurs.lignehorizontale,
epaisseur: this.format.epaisseurs.lignehorizontale
})
}
decal = 0
if (this.format.labelsclasses) decal += this.format.hclasse
for (k = 0; k < this.nbcol - 1; k++) {
j3pCreeSegment(svg, {
id: getId('lignecol' + k),
x1: (k + 1) * this.format.largeurcol,
y1: decal,
x2: (k + 1) * this.format.largeurcol,
y2: this.hauteurSVG,
couleur: this.format.couleurs.separateurcols,
epaisseur: this.format.epaisseurs.separateurcols
})
}
for (k = 0; k < (this.nbcol / 3) - 1; k++) {
j3pCreeSegment(svg, {
id: getId('lignecolclasses' + k),
x1: 3 * (k + 1) * this.format.largeurcol,
y1: 0,
x2: 3 * (k + 1) * this.format.largeurcol,
y2: this.hauteurSVG,
couleur: this.format.couleurs.separateurclasses,
epaisseur: this.format.epaisseurs.separateurclasses
})
}
const centragex = (this.format.largeurcol - 12) / 2
if (this.format.labelscols) {
const temp = ['c', 'd', 'u']
for (k = 0; k < this.nbcol; k++) {
u = k % 3
decal = 5
if (this.format.labelsclasses) decal += this.format.hclasse
if (Math.floor(k / 3) + this.premiereclasse <= 3) {
// les classes non décimales
j3pCreeTexte(svg, {
x: centragex + (k) * this.format.largeurcol,
y: 30 + this.format.top + decal,
texte: temp[u],
taille: (this.format.taillepolice) * (3 / 4),
couleur: this.format.couleurs.cols,
fonte: this.format.police,
italique: true
})
} else {
const nbzeros = 1 + u + (Math.floor(k / 3) + this.premiereclasse - 4) * 3
let divNbZeros
if (nbzeros < 4) {
divNbZeros = j3pDiv(divSvg, getId('decimale' + nbzeros), '', [-10 + centragex + (k) * this.format.largeurcol, this.format.top + decal])
} else {
divNbZeros = j3pDiv(divSvg, getId('decimale' + nbzeros), '', [-15 + centragex + (k) * this.format.largeurcol, this.format.top + decal + 5])
}
divNbZeros.style.fontFamily = this.format.police
ch = ''
for (let j = 0; j < nbzeros; j++) ch += '0'
if (this.format.labelscolsdecimaleslettres) {
if (nbzeros < 4) {
let sch = ''
switch (nbzeros) {
case 1:
sch = 'dixième'
break
case 2:
sch = 'centième'
break
case 3:
sch = 'millième'
break
}
divNbZeros.innerHTML = sch
const left = divNbZeros.style.left
const top = divNbZeros.style.top
divNbZeros.style.left = (Number(left.substring(0, left.length - 2)) - 10) + 'px'
divNbZeros.style.top = (Number(top.substring(0, top.length - 2)) + 12) + 'px'
} else {
j3pMathsAjouteDans(divNbZeros, { content: '$\\frac{1}{1' + ch + '}$' })
}
} else {
j3pMathsAjouteDans(divNbZeros, { content: '$\\frac{1}{1' + ch + '}$' })
}
if (nbzeros < 4) {
if (this.format.labelscolsdecimaleslettres) {
divNbZeros.style.fontSize = '9pt'
} else {
divNbZeros.style.fontSize = '12pt'
}
} else {
divNbZeros.style.fontSize = '9pt'
}
}
}
}
if (this.format.labelsclasses) {
for (k = 0; k < (this.nbcol / 3); k++) {
const centragex1 = 35
if (k + this.premiereclasse <= 3) {
// j3pCreeTexte(svg,{id:"texteclassek",x:centragex1+(3*k)*this.format.largeurcol,y:20+this.format.top,texte:"Classe des",taille:this.format.taillepolice-4,couleur:this.format.couleurs.labels,fonte:this.format.police,italique:true})
j3pCreeTexte(svg, {
x: centragex1 + 10 + (3 * k) * this.format.largeurcol,
y: (3 / 4) * this.format.hclasse + this.format.top,
texte: this.lesclasses[k + this.premiereclasse],
taille: (this.format.taillepoliceclasses) * (3 / 4),
couleur: this.format.couleurs.labels,
fonte: this.format.police,
italique: true
})
} else {
j3pCreeTexte(svg, {
x: 10 + (3 * k) * this.format.largeurcol,
y: (3 / 4) * this.format.hclasse + this.format.top,
texte: 'Partie décimale',
taille: (3 / 4) * (this.format.taillepolice - 4),
couleur: this.format.couleurs.labels,
fonte: this.format.police,
italique: true
})
}
}
}
// creation des DIV des différentes cases
let x, y
const colDivs = []
for (numligne = 0; numligne < this.lignes.length; numligne++) {
colDivs[numligne] = []
for (k = 0; k < this.nbcol; k++) {
u = k % 3
decal = 0
if (this.format.labelsclasses) decal += this.format.hclasse
if (this.format.labelscols) decal += this.format.hcol
decal += this.format.hlig * numligne - 1
x = centragex + (k) * this.format.largeurcol
y = this.format.taillechiffres / 2 + this.format.top + decal
colDivs[numligne][k] = j3pDiv(divSvg, {
coord: [x, y],
style: {
fontFamily: this.format.police,
fontSize: this.format.taillechiffres + 'px',
color: this.format.couleurs.chiffres,
width: '30px'
}
})
}
}
let tabindex = 0
for (numligne = 0; numligne < this.lignes.length; numligne++) {
for (k = 0; k < this.nbcol; k++) {
v = k % 3
u = this.premiereclasse + Math.floor(k / 3)
ch = this.lignes[numligne][u][v]
switch (ch) {
case '?_': {
const inputElt = j3pAjouteZoneTexte(colDivs[numligne][k],
{
id: this.idDIV + 'divcoltexte' + numligne + '_' + k,
maxchars: '1',
restrict: /\d/,
texte: '',
police: this.format.police,
width: 30,
tailletexte: this.format.taillechiffres,
fond: '#FFF',
couleur: this.format.couleurs.chiffres,
taille: 1,
top: -this.format.taillechiffres / 2 + 6,
left: -10,
tabindex: tabindex++
}
)
inputElt.style.textAlign = 'center'
break
}
case '.':
break
default:
colDivs[numligne][k].innerHTML = ch
break
}
}
decal = 0
if (this.format.labelsclasses) decal += this.format.hclasse
let decal2 = 0
if (this.format.labelscols) decal2 = decal + this.format.hcol
const emplacement = [3 * (4 - this.premiereclasse) * this.format.largeurcol, decal2 + this.format.hlig * (numligne + 2 / 3)]
if (this.format.virgule[numligne]) {
j3pCreeVirgule(svg, {
id: this.idDIV + 'virgule' + numligne,
top: emplacement[1],
left: emplacement[0],
rayon: 6,
couleur: '#F00',
couleurRemplissage: '#F00',
hauteur: 20,
angle: 45
})
}
}
}
TableauConversion.creeLigne = function (entier, unite, bool, classes) {
// classes = [i,j] i,i entre 0 et 5
// classes affichées
// bool = true : si le nombre<1, et si pas de 1/10 par ex, on met un zéro dans les 1/10
function convertit (nb) {
// 13==>[4,1]
// 5==>[1,2]
const a = Math.floor(nb / 3 + 0.01)
const b = nb % 3
return [a, b]
}
const res = [[], [], [], [], [], []]
/* unite : entier entre 0 et 17
creetableau(3510,13,false) ==> [[],[],[],[.,"3","5"],["1","0",.],[]]
*/
const tab = String(entier).split('')// ["3","5","1","0"]
// 0 ==> dans case 13
// 1 ==> dans case 12
// 5 ==> dans case 11
// 3 ==> dans case 10
let k
for (k = 0; k < tab.length; k++) {
// tab[k] dans case unite-(tab.length-1) + k
const tob = convertit(unite - (tab.length - 1) + k)
res[tob[0]][tob[1]] = tab[k]
}
for (k = 0; k < 6; k++) {
if (res[k].length !== 0) {
let u = 0
while ((typeof (res[k][u]) === 'undefined') && (u < 3)) {
if ((bool) && (k >= 4)) {
res[k][u] = '0'
} else {
res[k][u] = '.'
}
u++
}
}
if ((res[3].length === 0) && (res[4].length !== 0) && bool) {
res[3][2] = '0'
}
}
for (k = classes[0]; k <= classes[1]; k++) {
if (res[k].length === 0) {
res[k] = ['.', '.', '.']
}
}
for (k = 0; k < 6; k++) {
switch (res[k].length) {
case 1:
res[k][1] = '.'
res[k][2] = '.'
break
case 2:
res[k][2] = '.'
break
}
}
// il faut compléter
if ((res[1].length === 0) && (res[0].length !== 0)) {
res[1] = ['0', '0', '0']
res[2] = ['0', '0', '0']
res[3] = ['0', '0', '0']
}
if ((res[1].length !== 0) && (res[2].length === 0)) {
res[2] = ['0', '0', '0']
res[3] = ['0', '0', '0']
}
if ((res[2].length !== 0) && (res[3].length === 0)) {
res[3] = ['0', '0', '0']
}
if ((res[3].length === 0) && (res[4].length !== 0)) {
res[3] = ['.', '.', '0']
}
if ((res[4].length === 0) && (res[5].length !== 0)) {
res[3] = ['.', '.', '0']
res[3] = ['0', '0', '0']
}
return res
}
export default TableauConversion