/*
Si consideri una collezione di 25 blocchi rettangolari di dimensioni (double):
ALTEZZA ( un valore random tra 1 e 10 metri)
LARGHEZZA (un valore random tra 1 e 10 metri)
PROFoNDITA’ (un valore random tra 1 e 10 metri)

E dei seguenti materiali:

PIETRA (kg 20.000 al metro cubo)
PIOMBO (kg 50.000 al metro cubo)
Plastica (kg 300 al metro cubo)

Si scriva un programma JAVA che dica:

a)    quale è tra i 25 il blocco di volume maggiore;
b)    quale è tra i 25 il blocco di volume minore;
c)    quale è tra i 25 il blocco più pesante;
d)    quale è tra i 25 il blocco più leggero;
e)    il peso complessivo di tutti i blocchi.
*/

interface costanti {
  public static final String[] MATERIALI = {"Pietra", "Piombo", "Plastica"};
  public static final double[] PESOMATERIALI = {20000.0, 50000.0,300.0};
}

abstract class blocco implements costanti {
  //membri protetti
  protected double altezza, larghezza, profond;
  protected double pesoMC;         //peso al metro cubo
  protected String tipo;        //tipo di blocco
  //Costruttore
  public blocco() {
    //crea blocco casuale
    altezza   = Math.random() * 10 + 1;
    larghezza = Math.random() * 10 + 1;
    profond   = Math.random() * 10 + 1;
  }
  public double getVolume() {return (double)((long)((altezza * larghezza * profond)*100))/100;}
  public double getPeso() {return getVolume() * pesoMC;}
  public String toString() {return "Blocco di " + tipo + " da " + getVolume() + " mc. Peso= "+getPeso()+" Kg";}
}

//I blocchi
class pietra extends blocco {
  //costruttore
  public pietra() {
    super();
    pesoMC = PESOMATERIALI[0];
    tipo = MATERIALI[0];
  }
  
}

class piombo extends blocco {
  //costruttore
  public piombo() {
    super();
    pesoMC = PESOMATERIALI[1];
    tipo = MATERIALI[1];
  }
}

class plastica extends blocco {
  //costruttore
  public plastica() {
    super();
    pesoMC = PESOMATERIALI[2];
    tipo = MATERIALI[2];
  }
}

//classe "contenitore" di mattoni
class mattoni {
  //membri privati
  private final int NUMBLOCCHI = 25;    //numero blocchi di default
  private int nb;                       //numero blocchi effettivo
  private blocco[] blocchi;
  //variabili contenenti i dati statistici sui blocchi
  private double pesototale=0, maxvol=0, minvol=0, maxpeso=0, minpeso=0;
  private int imaxvol=0, iminvol=0, imaxpeso=0, iminpeso=0;
    
 /* Costruttori: Ne faccio 2; uno che crea il numero blocchi
    di default (25) e uno che permette la creazione di un numero
    stabilito dall'utilizzatore della classe. */  
  //Costruttore #1
  public mattoni() {
    nb = NUMBLOCCHI;
    blocchi = new blocco[nb];
    makeblock();     //crea mattoni
  }  
  //Costruttore #2
  public mattoni(int numblock) {
    nb = numblock;
    blocchi = new blocco[nb];
    makeblock();     //crea mattoni
  }
  //crea i blocchi
  private void makeblock() {
    int cas;
    for (int c=0; c<nb; c++) {
      cas = (int)(Math.random()*3);
      if (cas==0) blocchi[c] = new pietra();
      else if (cas==1) blocchi[c] = new piombo();  
      else blocchi[c] = new plastica();  
      /* mentre crea i blocchi, calcola i dati statistici:
         i vantaggi di questa tecnica sono :
         1. il calcolo di  tutti i dati che servono utilizzando UN UNICO CICLO
         2. Accesso più veloce ai dati (i metodi restituiscono i valori delle relative
            variabili private, invece che calcolare il valore ogni volta che vengono chiamati)
      */
      //PESO TOTALE
      pesototale += blocchi[c].getPeso();
      //inizializza variabili
      if (c==0) {minvol=blocchi[c].getVolume(); minpeso=blocchi[c].getPeso();}
      
      //VOLUME MAGGIORE E MINORE
      if (blocchi[c].getVolume() > maxvol) {maxvol = blocchi[c].getVolume(); imaxvol = c;}
      if (blocchi[c].getVolume() < minvol) {minvol = blocchi[c].getVolume(); iminvol = c;}
      //PESO MAGGIORE E MINORE
      if (blocchi[c].getPeso() > maxpeso) {maxpeso = blocchi[c].getPeso(); imaxpeso = c;}
      if (blocchi[c].getPeso() < minpeso) {minpeso = blocchi[c].getPeso(); iminpeso = c;}
    }
  }
  
  //metodi pubblici
  public int getNumblocchi() {return nb;}
  public void stampa() {
    for (int c=0; c<nb; c++)
      System.out.println(c + ") " + blocchi[c]);
  }
  //metodi per la restituzione dei dati statistici (utili per effettuare eventuali calcoli)
  public double getPesototale(){return pesototale;}
  public double getMaxvolume(){return maxvol;}
  public double getMinvolume(){return minvol;}
  public double getMaxpeso(){return maxpeso;}
  public double getMinpeso(){return minpeso;}
  
  //metodo di stampa dei dati statistici (comodità)
  public void statistiche() {
    System.out.println("\nStatistiche:\n" +
        "Blocco piu' pesante: n°" + imaxpeso + " " + blocchi[imaxpeso] +
        "\nBlocco piu' leggero: n°" + iminpeso + " " + blocchi[iminpeso] +
        "\nBlocco Volume MAX: n°" + imaxvol + " " + blocchi[imaxvol] +
        "\nBlocco Volume Min: n°" + iminvol + " " + blocchi[iminvol]);
    
  }
}


//Classe principale
public class Blocchi {
    
  public static void main(String[] args) {
    mattoni pietre = new mattoni();
    pietre.stampa();
    pietre.statistiche();
    System.out.println("Il peso totale dei blocchi e': " + pietre.getPesototale());
  }
}