/**
  * Simulation de propagation de la chaleur en 2 dimensions.
  */

import java.awt.image.*;
import javax.imageio.*;

public class PropagationChaleurEn2D {

  static int tx;
  static int ty;
  
/**
* Menu principal de l'application.
* 
* @return L'entier correspondant a l'option choisie.
*/
  public static int resultatExecutionMenu() {
    int v;
    Ecran.sautDeLigne();
    Ecran.afficherln("1: Lancer la simulation");
    Ecran.afficherln("2: Switcher entre affichages plein et wireframe");
    Ecran.afficherln("0: Quitter");
    Ecran.afficher("Que voulez vous faire ? ");
    v = Clavier.saisirInt();
    Ecran.sautDeLigne();
    return v;
  }

  public static double top(double [][] tb,int l,int c) {
    return(( l-1 >= 0 ) ? tb[l-1][c] : 0.0);
  }

  public static double bottom(double [][] tb,int l,int c) {
    return(( l+1 < ty ) ? tb[l+1][c] : 0.0);
  }

  public static double left(double [][] tb,int l,int c) {
    return(( c-1 >= 0 ) ? tb[l][c-1] : 0.0);
  }

  public static double right(double [][] tb,int l,int c) {
    return(( c+1 < tx ) ? tb[l][c+1] : 0.0);
  }
  
  public static double [][] evolution(double [][] tb,double k) {
    double [][] ntb = new double[tb.length][tb[0].length];
    for ( int l = 0 ; l < tb.length ; l++ ) {
      for ( int c = 0 ; c < tb[l].length ; c++ ) {
        ntb[l][c] = tb[l][c]+k*(top(tb,l,c)+bottom(tb,l,c)+left(tb,l,c)+right(tb,l,c)-4.0*tb[l][c]); } }
    return(ntb);
  }

  public static void afficherCellule(double v,int l,int c,boolean mode) {
    int zoom = 4;
    int px = c*zoom;
    int py = l*zoom;
    int rouge;
    int vert;
    int bleu;
    if ( v < 128.0 ) {
      rouge =(int) v*2;
      vert = 0;
      bleu = 0; }
      else 
      if ( v < 192.0 ) {
        rouge = 255;
        vert =(int) ((v-128.0)*4.0);
        bleu = 0; }
        else
        if ( v < 255.0 ) {
          rouge = 255;
          vert = 255;
          bleu = (int) ((v-192.0)*4.0); }
          else {
          rouge = 255;
          vert = 255;
          bleu = 255; }
    EcranGraphique.setColor(rouge,vert,bleu);
    if ( mode )
      for ( int i = 0 ; i < zoom ; i++ )
        EcranGraphique.drawLine(px,py+i,px+zoom-1,py+i);
      else {
      EcranGraphique.fillRect(px,py,zoom-1,zoom-1); }
  }
  
  public static void afficher(double [][] tb,boolean mode) {
    for ( int l = 0 ; l < tb.length ; l++ ) {
      for ( int c = 0 ; c < tb[l].length ; c++ ) {
        afficherCellule(tb[l][c],l,c,mode); } }
  }
  
/**
* Programme principal.
*
*/
  public static void main(String [] args) {
    int choix;
    double prct;
    boolean mode = true;
    EcranGraphique.init(30,30,720,720,800,800,"Simulation 2D de propagation de chaleur");
    double [][] tb = new double[200][200];
    tx = 200;
    ty = 200;
    double init1 = 30000.0;
    tb[70][70] = init1;
    tb[70][71] = init1;
    tb[70][72] = init1;
    tb[71][70] = init1;
    tb[71][71] = init1;
    tb[71][72] = init1;
    tb[72][70] = init1;
    tb[72][71] = init1;
    tb[72][72] = init1;
    double init2 = 40000.0;
    tb[123][43] = init2;
    tb[123][44] = init2;
    tb[124][43] = init2;
    tb[124][44] = init2;
    tb[33][113] = init2;
    tb[33][114] = init2;
    tb[34][113] = init2;
    tb[34][114] = init2;
    tb[152][152] = init2;
    tb[152][153] = init2;
    tb[152][154] = init2;
    tb[152][155] = init2;
    afficher(tb,mode);
    EcranGraphique.flush();
    choix = resultatExecutionMenu();
    while ( choix != 0 ) {
      switch (choix) {
        case 2 : {
          mode = !mode;
          EcranGraphique.clear();
          afficher(tb,mode);
          EcranGraphique.flush(); }
          break;
        case 1 : {
          int nbIterations;
          Ecran.afficher("Combien d'iterations? : ");
          nbIterations = Clavier.saisirInt();
          for ( int i = 0 ; i < nbIterations ; i++ ) {
            tb = evolution(tb,0.2);
            EcranGraphique.clear();
            afficher(tb,mode);
            EcranGraphique.flush(); } }
          break; }
    choix = resultatExecutionMenu(); }
    EcranGraphique.exit();
  }    
}