%%%
% Calisson
%%%
\setKVdefault[Calisson]{Taille=3,Solution=false,Rayon=5cm,Couleur=red}%

\def\UpdatetoksCalissong#1\nil{\addtotok\tokcalissonlistetracesg{,"#1"}}%
\def\UpdatetoksCalissongDepart#1\nil{\addtotok\tokcalissonlistetracesg{"#1"}}%
\def\UpdatetoksCalissond#1\nil{\addtotok\tokcalissonlistetracesd{,"#1"}}%
\def\UpdatetoksCalissondDepart#1\nil{\addtotok\tokcalissonlistetracesd{"#1"}}%

\newtoks\tokcalissonlistetracesg
\newtoks\tokcalissonlistetracesd

\NewDocumentCommand\Calisson{o m}{%
  \useKVdefault[Calisson]%
  \setKV[Calisson]{#1}%
  % Essai de cassage du code
  \tokcalissonlistetracesg{}%
  \tokcalissonlistetracesd{}%
  %Partie Gauche -> ok
  \StrLeft{0#2}{2}[\Depart]%
  \StrGobbleLeft{0#2}{2}[\Reste]%
  \expandafter\UpdatetoksCalissongDepart\Depart0\nil%
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-1}}}\do{%
    \StrLeft{0\Reste}{3}[\Depart]%
    \expandafter\UpdatetoksCalissong\Depart\nil%
    \StrGobbleLeft{0\Reste}{3}[\Reste]%
  }%
  \StrLeft{00\Reste}{3}[\Depart]%
  \StrGobbleLeft{00\Reste}{3}[\Reste]%
  \expandafter\UpdatetoksCalissong\Depart\nil%
  % fin premiere ligne
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-1}}}\do{%
    \StrLeft{\Reste}{2}[\Depart]%
    \expandafter\UpdatetoksCalissong\Depart0\nil%
    \StrGobbleLeft{\Reste}{2}[\Reste]%
    \xintFor* ##2 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-1}}}\do{%
      \StrLeft{\Reste}{3}[\Depart]%
      \expandafter\UpdatetoksCalissong\Depart\nil%
      \StrGobbleLeft{\Reste}{3}[\Reste]%
    }%
    \StrLeft{00\Reste}{3}[\Depart]%
    \expandafter\UpdatetoksCalissong\Depart\nil%
    \StrGobbleLeft{00\Reste}{3}[\Reste]%
  }%
  % fin des lignes intermédiaires
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}}}}\do{%
    \StrLeft{\Reste}{2}[\Depart]%
    \expandafter\UpdatetoksCalissong\Depart0\nil%
    \StrGobbleLeft{\Reste}{2}[\Reste]
    \xintifboolexpr{##1>\fpeval{\useKV[Calisson]{Taille}-1}}{}{%
      \xintFor* ##2 in {\xintSeq{\fpeval{\useKV[Calisson]{Taille}-##1}}{1}}\do{%
        \StrLeft{\Reste}{3}[\Depart]%
        \expandafter\UpdatetoksCalissong\Depart\nil%
        \StrGobbleLeft{\Reste}{3}[\Reste]%
      }%
    }%
  }%
  %Liste gauche : \the\tokcalissonlistetracesg%
  % Partie droite
  \StrLeft{0\Reste}{3}[\Depart]%
  \expandafter\UpdatetoksCalissondDepart\Depart\nil%
  \StrGobbleLeft{0\Reste}{3}[\Reste]%
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-2}}}\do{%
    \StrLeft{0\Reste}{3}[\Depart]%
    \expandafter\UpdatetoksCalissond\Depart\nil%
    \StrGobbleLeft{0\Reste}{3}[\Reste]%
  }%
  \StrLeft{00\Reste}{3}[\Depart]%
  \StrGobbleLeft{00\Reste}{3}[\Reste]%
  \expandafter\UpdatetoksCalissond\Depart\nil%
% fin premiere ligne
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-1}}}\do{%
    \StrLeft{\Reste}{1}[\Depart]%
    \expandafter\UpdatetoksCalissond\Depart00\nil%
    \StrGobbleLeft{\Reste}{1}[\Reste]%
    \xintFor* ##2 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}-1}}}\do{%
      \StrLeft{\Reste}{3}[\Depart]%
      \expandafter\UpdatetoksCalissond\Depart\nil%
      \StrGobbleLeft{\Reste}{3}[\Reste]%
    }%
    \StrLeft{00\Reste}{3}[\Depart]%
    \expandafter\UpdatetoksCalissond\Depart\nil%
    \StrGobbleLeft{00\Reste}{3}[\Reste]%
  }%
  %% fin des lignes intermédiaires
  \xintFor* ##1 in {\xintSeq{1}{\fpeval{\useKV[Calisson]{Taille}}}}\do{%
    \StrLeft{\Reste}{1}[\Depart]%
    \expandafter\UpdatetoksCalissond\Depart00\nil%
    \StrGobbleLeft{\Reste}{1}[\Reste]%
    \xintifboolexpr{##1>\fpeval{\useKV[Calisson]{Taille}-1}}{}{%
      \xintFor* ##2 in {\xintSeq{\fpeval{\useKV[Calisson]{Taille}-##1}}{1}}\do{%
        \StrLeft{\Reste}{3}[\Depart]%
        \expandafter\UpdatetoksCalissond\Depart\nil%
        \StrGobbleLeft{\Reste}{3}[\Reste]%
      }%
    }%
  }%
%  \par Liste droite :\the\tokcalissonlistetracesd
  \BuildCalisson{\the\tokcalissonlistetracesg}{\the\tokcalissonlistetracesd}%
}%

\NewDocumentCommand\BuildCalisson{m m}{%
  \ifluatex
  \mplibforcehmode
  \begin{mplibcode}
    boolean Solution;
    Solution:=\useKV[Calisson]{Solution};

    color CouleurSolution;
    CouleurSolution:=\useKV[Calisson]{Couleur};
    
    Rayon=\useKV[Calisson]{Rayon};
    Taille=\useKV[Calisson]{Taille};
    
    pair A,B,C,D,E,F,O;
    O=(0,0);
    path cc;
    cc=cercles(O,Rayon);
    D=pointarc(cc,30);
    E=pointarc(cc,90);
    F=pointarc(cc,150);
    A=pointarc(cc,210);
    B=pointarc(cc,270);
    C=pointarc(cc,330);
    trace polygone(A,B,C,D,E,F) withpen pencircle scaled 2;
    path Gauche,Droit,Haut,Bas,TopGauche,BasDroit;
    Gauche=F--A--B;
    Droit=E--D--C;
    Haut=F--E--D;
    Bas=A--B--C;
    TopGauche=E--F--A;
    BasDroit=D--C--B;
    for k=1 upto 2*Taille-1:
    trace (point(k*length Gauche/(2*Taille)) of Gauche)--(point(k*length Droit/(2*Taille)) of Droit) dashed evenly;
    trace (point(k*length Haut/(2*Taille)) of Haut)--(point(k*length Bas/(2*Taille)) of Bas) dashed evenly;
    trace (point(k*length TopGauche/(2*Taille)) of TopGauche)--(point(k*length BasDroit/(2*Taille)) of BasDroit) dashed evenly;
    endfor;
    
    pair Hor,Ver,Horn;
    Hor=(1/Taille)[E,F];
    Ver=rotation(Hor,E,60);
    Horn=rotation(Hor,E,120);

    % On positionne les points
    pair M[];
    n=0;
    %Partie Gauche -> ok
    for k=0 upto Taille-1:
    for l=0 upto Taille:
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Hor-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    for k=Taille upto 2*Taille-1:
    for l=0 upto (2*Taille-1-k):
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Hor-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    % Partie Droite -> ok
    for k=1 upto Taille:
    n:=n+1;
    M[n]=E+k*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    for k=1 upto Taille-1:
    for l=0 upto Taille:
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    for k=Taille upto 2*Taille-1:
    for l=0 upto (2*Taille-1-k):
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    %
    
    string Retiens;
    Retiens="";

    pair Depla;
    Depla:=Hor;
    
    vardef LesTracesg(text t)=
    n:=0;
    for p_=t:
    n:=n+1;
    for d=1 upto 3:
    Retiens:=substring(d-1,d) of p_;
    if d=1:Depla:=Hor
    elseif d=2:Depla:=Ver
    else : Depla:=Horn
    fi;
    if (Retiens="0") or (Retiens="f"):
    elseif Retiens="t":
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2;
    elseif Retiens="s":
    if Solution:
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2 withcolor CouleurSolution;
    fi;
    fi;
    endfor;
    endfor;
    enddef;

    vardef LesTracesd(text t)=
    for p_=t:
    n:=n+1;
    for d=1 upto 3:
    Retiens:=substring(d-1,d) of p_;
    if d=1:Depla:=Horn
    elseif d=2:Depla:=Ver
    else : Depla:=Hor
    fi;
    if (Retiens="0") or (Retiens="f"):
    elseif Retiens="t":
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2;
    elseif Retiens="s":
    if Solution:
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2 withcolor CouleurSolution;
    fi;
    fi;
    endfor;
    endfor;
    enddef;
    
    LesTracesg(#1);
    LesTracesd(#2);
  \end{mplibcode}
  \else
  \begin{mpost}[mpsettings={boolean Solution; Solution:=\useKV[Calisson]{Solution}; Rayon=\useKV[Calisson]{Rayon};Taille=\useKV[Calisson]{Taille};color CouleurSolution; CouleurSolution:=\useKV[Calisson]{Couleur};}]
    pair A,B,C,D,E,F,O;
    O=(0,0);
    path cc;
    cc=cercles(O,Rayon);
    D=pointarc(cc,30);
    E=pointarc(cc,90);
    F=pointarc(cc,150);
    A=pointarc(cc,210);
    B=pointarc(cc,270);
    C=pointarc(cc,330);
    trace polygone(A,B,C,D,E,F) withpen pencircle scaled 2;
    path Gauche,Droit,Haut,Bas,TopGauche,BasDroit;
    Gauche=F--A--B;
    Droit=E--D--C;
    Haut=F--E--D;
    Bas=A--B--C;
    TopGauche=E--F--A;
    BasDroit=D--C--B;
    for k=1 upto 2*Taille-1:
    trace (point(k*length Gauche/(2*Taille)) of Gauche)--(point(k*length Droit/(2*Taille)) of Droit) dashed evenly;
    trace (point(k*length Haut/(2*Taille)) of Haut)--(point(k*length Bas/(2*Taille)) of Bas) dashed evenly;
    trace (point(k*length TopGauche/(2*Taille)) of TopGauche)--(point(k*length BasDroit/(2*Taille)) of BasDroit) dashed evenly;
    endfor;
    
    pair Hor,Ver,Horn;
    Hor=(1/Taille)[E,F];
    Ver=rotation(Hor,E,60);
    Horn=rotation(Hor,E,120);

    % On positionne les points
    pair M[];
    n=0;
    %Partie Gauche -> ok
    for k=0 upto Taille-1:
    for l=0 upto Taille:
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Hor-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    for k=Taille upto 2*Taille-1:
    for l=0 upto (2*Taille-1-k):
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Hor-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    % Partie Droite -> ok
    for k=1 upto Taille:
    n:=n+1;
    M[n]=E+k*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    for k=1 upto Taille-1:
    for l=0 upto Taille:
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    for k=Taille upto 2*Taille-1:
    for l=0 upto (2*Taille-1-k):
    n:=n+1;
    M[n]=E+k*(Ver-E)+l*(Horn-E);
    %dotlabel.top(decimal(n),M[n]);
    endfor;
    endfor;
    %
    
    string Retiens;
    Retiens="";

    pair Depla;
    Depla:=Hor;
    
    vardef LesTracesg(text t)=
    n:=0;
    for p_=t:
    n:=n+1;
    for d=1 upto 3:
    Retiens:=substring(d-1,d) of p_;
    if d=1:Depla:=Hor
    elseif d=2:Depla:=Ver
    else : Depla:=Horn
    fi;
    if (Retiens="0") or (Retiens="f"):
    elseif Retiens="t":
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2;
    elseif Retiens="s":
    if Solution:
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2 withcolor CouleurSolution;
    fi;
    fi;
    endfor;
    endfor;
    enddef;

    vardef LesTracesd(text t)=
    for p_=t:
    n:=n+1;
    for d=1 upto 3:
    Retiens:=substring(d-1,d) of p_;
    if d=1:Depla:=Horn
    elseif d=2:Depla:=Ver
    else : Depla:=Hor
    fi;
    if (Retiens="0") or (Retiens="f"):
    elseif Retiens="t":
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2;
    elseif Retiens="s":
    if Solution:
    trace (chemin(Depla,E) shifted (M[n]-E)) withpen pencircle scaled 2 withcolor CouleurSolution;
    fi;
    fi;
    endfor;
    endfor;
    enddef;
    
    LesTracesg(#1);
    LesTracesd(#2);
  \end{mpost}
  \fi
}%