/* Tri par selection d'un tableau d'entiers       */

public class TriSelectionGraphique {

  static final int px = 40;
  static final int py = 170;
  
  static void affichage(int [] t,int px,int py) {
    EcranGraphique.drawLine(px-10,py-25,px+t.length*40-10,py-25);
    EcranGraphique.drawLine(px-10,py+10,px+t.length*40-10,py+10);
    for ( int i = 0 ; i <= t.length ; i++ )
      EcranGraphique.drawLine(px-10+i*40,py-25,px-10+i*40,py+10);
    for ( int i = 0 ; i < t.length ; i++ ) {
      EcranGraphique.drawText(px+40*i,py,EcranGraphique.COLABA8x13,"%d",t[i]); }
  }

  static void affichage(int [] t,int px,int py,int indi,int indf,int lim) {
    EcranGraphique.setColor(0,0,0);
    EcranGraphique.drawLine(px-10,py-25,px+t.length*40-10,py-25);
    EcranGraphique.drawLine(px-10,py+10,px+t.length*40-10,py+10);
    for ( int i = 0 ; i <= t.length ; i++ )
      EcranGraphique.drawLine(px-10+i*40,py-25,px-10+i*40,py+10);
    for ( int i = 0 ; i < t.length ; i++ )
      if ( ( i != indi ) && ( i != indf ) ) {
        if ( i > lim )
          EcranGraphique.setColor(0,192,0);
          else
          EcranGraphique.setColor(0,0,0);
        EcranGraphique.drawText(px+40*i,py,EcranGraphique.COLABA8x13,"%d",t[i]); }
  }

  static void animation(int [] t,int indi,int indf,int lim) {
    for ( int i = 0 ; i <= 45 ; i++ ) {
      EcranGraphique.clear();
      EcranGraphique.setColor(0,0,0);
      affichage(t,40,120,indi,indf,lim);
      int px1 = 40+indi*40;
      int py = 120;
      int px2 = 40+indf*40;
      double dist = (px2-px1)/2.0;
      double angle = i/45.0*Math.PI;
      int pxf =(int) ((px1+px2)/2.0+dist*Math.cos(angle));
      int pyf =(int) (py+40.0*Math.sin(angle));
      int pxi =(int) ((px1+px2)/2.0+dist*Math.cos(angle+Math.PI));
      int pyi =(int) (py+40.0*Math.sin(angle+Math.PI));
      EcranGraphique.setColor(192,0,0);
      EcranGraphique.drawText(pxi,pyi,EcranGraphique.COLABA8x13,"%d",t[indi]);
      EcranGraphique.setColor(0,0,192);
      EcranGraphique.drawText(pxf,pyf,EcranGraphique.COLABA8x13,"%d",t[indf]);
      EcranGraphique.wait(10);
      EcranGraphique.flush(); }
  }

  static void affichage(int [] t,int px,int py,int lim) {
    EcranGraphique.setColor(0,0,0);
    EcranGraphique.drawLine(px-10,py-25,px+t.length*40-10,py-25);
    EcranGraphique.drawLine(px-10,py+10,px+t.length*40-10,py+10);
    for ( int i = 0 ; i <= t.length ; i++ )
      EcranGraphique.drawLine(px-10+i*40,py-25,px-10+i*40,py+10);
    for ( int i = 0 ; i < t.length ; i++ ) {
      if ( i > lim )
        EcranGraphique.setColor(0,192,0);
        else
        EcranGraphique.setColor(0,0,0);
      EcranGraphique.drawText(px+40*i,py,EcranGraphique.COLABA8x13,"%d",t[i]); }
  }

  static void affichageRechercheIMax(int [] t,int ind,int i,int iMax,int lim) {
    EcranGraphique.clear();
    affichage(t,40,120,lim);
    { int px = 50+ind*40+i;
      EcranGraphique.setColor(0,0,0);
      EcranGraphique.drawLine(px,140,px,180);
      EcranGraphique.drawLine(px-5,145,px,140);
      EcranGraphique.drawLine(px+5,145,px,140);
      EcranGraphique.setColor(0,0,192); }
    { int px = 50+iMax*40;
      EcranGraphique.setColor(0,0,192);
      EcranGraphique.drawLine(px,140,px,180);
      EcranGraphique.drawLine(px-5,145,px,140);
      EcranGraphique.drawLine(px+5,145,px,140); }
    EcranGraphique.flush();
    EcranGraphique.wait(10);
  }

  static void animationRechercheIMax(int [] t,int ind,int iMax,int lim) {
    for ( int i = 0 ; i <= 40 ; i += 2 ) {
      affichageRechercheIMax(t,ind,i,iMax,lim); }
  }
  
/* Fonction de recherche de l'indice de la valeur */
/* maximale d'un tableau restreint                */
/* a ses n premieres valeurs                      */
  
  static int indiceDuMaximum(int n,int [] t) {
    int iMax = 0;
    for ( int i = 0 ; i <= n ; i++ ) {
      if ( t[i] > t[iMax] ) {
        iMax = i; }
      if ( i != n )
        animationRechercheIMax(t,i,iMax,n);
        else
        affichageRechercheIMax(t,n,0,iMax,n);}
    EcranGraphique.flush();
    EcranGraphique.wait(1000);
    return iMax;
  }

/* Fonction de tri par selection                  */
/* d'un tableau d'entiers                         */

  static void triSelection(int [] t) {
    int aux;
    int iMax;
    for ( int i = t.length-1 ; i > 0 ; i-- ) {
      iMax = indiceDuMaximum(i,t);
      if ( t[iMax] != t[i] ) {
        animation(t,i,iMax,i);
        aux = t[iMax];
        t[iMax] = t[i];
        t[i] = aux; } }
    EcranGraphique.clear();
    affichage(t,40,120,-1,-1,-1);
    EcranGraphique.flush();
    EcranGraphique.wait(10);
  }

/* Programme principal                            */

  public static void main(String [] args) {
    int [] t = Bibliotheque.initRand(15,99);
    int [] tc = Bibliotheque.clone(t);
    EcranGraphique.init(50,50,700,320,660,240,"Tri par sélection");
    EcranGraphique.setClearColor(255,255,255);
    triSelection(t);
  }
}