/** file: CalAp102.java */

import java.awt.*;
import java.awt.event.*;
import java.lang.Boolean;
import java.lang.Exception;

/** ========================================
      Calcolatrice (APPLET) per JDK v1.0.2
    ======================================== */
public class CalAp102 extends java.applet.Applet {
  protected TextArea AreaMsg;      // area per i messaggi
  protected TextArea AreaValuta;   // area per str.da valutare
  protected TextArea AreaRisulta;  // area per il risultato
  protected TextArea AreaAmbient;  // area per il risultato

  protected myButton BottoneUgu = new myButton("= VAL", "", 'v');
  protected myButton BottoneCAN = new myButton("CANC",  "", 'c');

  protected static   int MAX_BOT      = 26;
  protected myButton ArrBottoni[] = new myButton [MAX_BOT];
          // NB: TUTTI I BOTTONI CHE AGGIUNGONO CARATTERI IN STR.
                                   // Testo del bottone:
  protected String   StrSuBot[]   = {"1", "2", "3", "+",
                                     "4", "5", "6", "-",
                                     "7", "8", "9", "x",
                                     "(", "0", ")", ":",
                                     ".", "sqr", "sqrt", "inv",
                                     "X", "Y", "A", "B",
                                     "= Ass", "Spazio"};
                                   // Da inserire nella stringa:
  protected String   StrPerStr[]  = {"1", "2", "3", "+",
                                     "4", "5", "6", "-",
                                     "7", "8", "9", "*",
                                     "(", "0", ")", "/",
                                     ".", "sqr", "sqrt", "inv",
                                     "X", "Y", "A", "B",
                                     "=", " "};
  
  protected Panel    PannelloBott;    // Pannello per i bottoni

  Checkbox  CBTracAlb,
            CancInput,
            DispAction,
            DispCostr,
            DispValut;
  protected Panel  PannelloCB;      // Pannello per i check-box
  
  protected CheckboxGroup NotazCBG = new CheckboxGroup();
  Checkbox  NotazPre,
            NotazInf,
            NotazPos;
  protected Panel    PannNotazCB;   // Pannello per il CBG "notazione"
     
  protected String   StrDaValutare = new String ("");  // Exp in stringa
  protected Exp      ExpDaValutare;                    // Exp ad albero
  protected double   Risultato;                        // Exp valutata

  protected myFrame FinDisp;

  protected myDispPerAlbero DispAlb;
  protected VisitorRiscriviExp   PreVis,
                                 InVis,
                                 PostVis; //Visitor per STAMPARE
  protected VisitorValutaExp     ValVis;  //Visitor per VALUTARE

  protected java.util.Hashtable AmbGlobale = new java.util.Hashtable();

  public CalAp102 () {
    super ();
  }
  
  protected void StampaAmbiente() {
    AreaAmbient.setText ("Ambiente:\n");
    AreaAmbient.appendText  ("X = "+AmbGlobale.get("X")+"\n");
    AreaAmbient.appendText  ("Y = "+AmbGlobale.get("Y")+"\n");
    AreaAmbient.appendText  ("A = "+AmbGlobale.get("A")+"\n");
    AreaAmbient.appendText  ("B = "+AmbGlobale.get("B"));
  }// StampaAmbiente
        
  public void init() {
    super.init();
    setBackground (Color.blue);
    setForeground (Color.white);          // Aree di stampa
    this.setFont (new Font("TimesRoman", Font.PLAIN, 13));
    
    // Area stampa espress.da calcolare
    AreaValuta = new TextArea (StrDaValutare,1,35);
                               //....TextArea.SCROLLBARS_NONE);
    AreaValuta.setBackground (Color.white);
    AreaValuta.setForeground (Color.black);
    AreaValuta.setFont (new Font("Courier", Font.BOLD, 20));
    AreaValuta.setEditable(false);
    add (AreaValuta);
    
    // Area stampa risultato
    AreaRisulta = new TextArea ("",1,7);//...., TextArea.SCROLLBARS_NONE);
    AreaRisulta.setBackground (Color.yellow);
    AreaRisulta.setForeground (Color.black);
    AreaRisulta.setFont (new Font("Helvetica", Font.BOLD, 30)); // Arial
    AreaRisulta.setEditable(false);
    add (AreaRisulta);
    
    PannNotazCB = new Panel();  // pannello per Gruppo CheckBox
    NotazPre    = new Checkbox ();
    NotazPre.setLabel("PREFISSA");
    NotazPre.setCheckboxGroup(NotazCBG);
    NotazPre.setState(false);
    NotazInf    = new Checkbox ();
    NotazInf.setLabel("INFISSA");
    NotazInf.setCheckboxGroup(NotazCBG);
    NotazInf.setState(true);
    NotazPos    = new Checkbox ();
    NotazPos.setLabel("POSTFISSA");
    NotazPos.setCheckboxGroup(NotazCBG);
    NotazPos.setState(false);
    PannNotazCB.setLayout (new GridLayout(4,1, 10,10));
    PannNotazCB.setBackground (Color.cyan);
    PannNotazCB.setForeground (Color.red);
    PannNotazCB.setFont (new Font("TimesRoman", Font.PLAIN, 18));
    PannNotazCB.add (new Label("Notazione:"));
    PannNotazCB.add (NotazPre);
    PannNotazCB.add (NotazInf);
    PannNotazCB.add (NotazPos);
    add (PannNotazCB);
    
    PannelloBott = new Panel();      // pannello per i bottoni
    PannelloBott.setLayout (new GridLayout(7,4, 3,3));
  
    for (int i=0; i<MAX_BOT; i++) {
      ArrBottoni[i] = new myButton (StrSuBot[i], StrPerStr[i], 'f');
      PannelloBott.add (ArrBottoni[i]);     // TUTTI I BOTTONI
    }
    
    PannelloBott.add (BottoneCAN);
    PannelloBott.add (BottoneUgu);
    add (PannelloBott);
            
    PannelloCB = new Panel ();
    PannelloCB.setLayout (new GridLayout(5,1,2,2));
    PannelloCB.setForeground (Color.orange);
    PannelloCB.setFont (new Font("TimesRoman", Font.PLAIN, 14));
    add (PannelloCB);

    CBTracAlb  = new Checkbox ("Disegna Albero");
    CBTracAlb.setState(true);
    CancInput  = new Checkbox ("Cancella Input");
    CancInput.setState(true);
    DispAction = new Checkbox ("Mostra 'action'");
    DispAction.setState(false);
    DispCostr  = new Checkbox ("Costruzione RI");
    DispCostr.setState(true);
    DispValut  = new Checkbox ("Valutazione RI");
    DispValut.setState(true);
  
    PannelloCB.add (CBTracAlb);
    PannelloCB.add (CancInput);
    PannelloCB.add (DispAction);
    PannelloCB.add (DispCostr);
    PannelloCB.add (DispValut);
    
    AreaMsg = new TextArea ("Area dei Messaggi\n", 8,65);
                            //....TextArea.SCROLLBARS_VERTICAL_ONLY);
    AreaMsg.setBackground (Color.black);
    AreaMsg.setForeground (Color.white);
    AreaMsg.setFont (new Font("Courier", Font.PLAIN, 12));
    add (AreaMsg);
    
    AreaAmbient = new TextArea ("", 6,11);
                                //....TextArea.SCROLLBARS_NONE);
    AreaAmbient.setBackground (Color.orange);
    AreaAmbient.setForeground ((Color.blue).brighter());
    AreaAmbient.setFont (new Font("TimesRoman", Font.BOLD, 15));
    AreaAmbient.setEditable(false);
    add (AreaAmbient);
    
    StampaAmbiente ();    
  } //init


  protected Exp CompilaStrInExp (String EsprInStr) {
    Exp ExpAtt = null;  // inizializzo a exp.nulla
    TextArea MyTA;
    if (DispCostr.getState()) MyTA = AreaMsg;
                         else MyTA = new TextArea();  // Non la visualizzero'
    MyTA.appendText ("--------CONVERSIONE DA STRINGA A R.I.--------\n");
    try{
      // Creo il tokenizer
      ExpTokenizer ETokz  = new ExpTokenizer (EsprInStr, MyTA);
      // e lo do in pasto al Parser (che creo ora)
      StrParser    Parser = new StrParser (ETokz, MyTA);
      // Compilo la stringa a seconda della notazione scelta
      if (NotazInf.getState())     // Esamina notazione scelta
        ExpAtt = Parser.RendiExpDaNotazInfissa();
      else
        if (NotazPre.getState())
          ExpAtt = Parser.RendiExpDaNotazPrefissa();
        else
          if (NotazPos.getState())
            ExpAtt = Parser.RendiExpDaNotazPostfissa();
      MyTA.appendText (" Exp: "+ ExpAtt +"\n");
    } catch (Exception e)
            { AreaMsg.appendText ("!!! ERRORE !!!  "+ e +"\n"); }
    return ExpAtt;
  }//CompilaStrInExp

  protected void VisualizzaFinestraConAlbero (Exp Esp) {
    FinDisp = new myFrame ("Display per Espressioni");
    FinDisp.resize (500,400);
    AreaMsg.appendText ("--------DISEGNANDO ALBERO----------\n");
    
    TextArea AreaStr = new TextArea("", 4,15);
    AreaStr.setFont (new Font("Courier", Font.BOLD, 14));
    DispAlb = new myDispPerAlbero(Esp, AreaMsg);
    setLayout (new BorderLayout());
    FinDisp.add ("North",  AreaStr);     // Aggiungo componenti
    FinDisp.add ("Center", DispAlb);
    PreVis = new VisitorRiscriviExp(0, AreaMsg);
    InVis  = new VisitorRiscriviExp(1, AreaMsg);
    PostVis= new VisitorRiscriviExp(2, AreaMsg);
    try {
      Esp.accept (PreVis);       // ACCETTA VISITOR per RISTAMPA
      Esp.accept (InVis);
      Esp.accept (PostVis);
    } catch (Exception e)
          { AreaMsg.appendText ("!!! ERRORE !!!   "+ e +"\n"); }
    AreaStr.appendText ("Notazione  Prefissa: "+ PreVis.Val()+"\n");
    AreaStr.appendText ("Notazione   Infissa: "+ InVis.Val()+"\n");
    AreaStr.appendText ("Notazione Postfissa: "+ PostVis.Val()+"\n");
    AreaStr.appendText ("Risultato = "+ ValVis.Val());
    FinDisp.show ();
  }//VisualizzaFinestraConAlbero

  protected double ValutaExp (Exp ExpInExp) {
    TextArea MyTA;
    double Ris = 0;
    if (DispValut.getState()) MyTA = AreaMsg;
                         else MyTA = new TextArea();  // Non la visualizzero'
    MyTA.appendText ("--------VALUTAZIONE DELLA R.I.--------\n");
    try{
      ValVis = new VisitorValutaExp (AmbGlobale, MyTA); //nell'amb.dato
      ExpInExp.accept (ValVis);     // ACCETTA IL VISITOR DI VALUTAZIONE
      Ris = ValVis.Val();
    } catch (Exception e)
            { AreaMsg.appendText ("!!! ERRORE !!!   "+ e +"\n"); }
 
    if (CBTracAlb.getState())
      VisualizzaFinestraConAlbero (ExpInExp);
    return Ris;
  }//ValutaExp

  protected void VALUTAZIONE () {
    AreaMsg.setText ("");  //cancella area messaggi
    // INTERPRETA EXP: STR -> RI
    ExpDaValutare = CompilaStrInExp (StrDaValutare);
    // VALUTA ESPRESSIONE: R.I -> STR
    if (!(ExpDaValutare == null)) {
      Risultato = ValutaExp (ExpDaValutare);
      repaint();
      AreaRisulta.setText (""+Risultato); // Stampa risultato
      StampaAmbiente ();
      if (CancInput.getState()) {  // Cancella input
        AreaValuta.setForeground(Color.blue);
        AreaValuta.setText (StrDaValutare);
        StrDaValutare="";
      }
    }//If
    AreaMsg.appendText ("*** VAL Terminata ***\n");
  }//VALUTAZIONE

  
  public boolean action (Event evt, Object arg) {
    if (DispAction.getState()) AreaMsg.appendText ("ACTION - ");
    if (evt.target instanceof myButton) {
      if (DispAction.getState())
        AreaMsg.appendText ("BOTTONE "+(String)arg+"\n");

      String Nome = (String)arg;
      myButton BottPremuto = (myButton) evt.target;   // uso aliasing
      
      if (DispAction.getState()) { // Messaggi di controllo
        AreaMsg.appendText ("  Bottone: toString --> "+BottPremuto.toString()+"\n");
        AreaMsg.appendText ("           mio Nome --> "+BottPremuto.Nome()+"\n");
      }
      if (BottPremuto.TipoFun() == 'f') {
        StrDaValutare = StrDaValutare.concat (BottPremuto.Oper()); //accodo operaz.
        AreaValuta.setForeground(Color.black);
        AreaValuta.setText (StrDaValutare);
      }
      else
        if (BottPremuto.TipoFun() == 'c') {
          StrDaValutare = "";
          AreaValuta.setForeground(Color.black);
          AreaValuta.setText (StrDaValutare);
        }
        else
          if (BottPremuto.TipoFun() == 'v')
            VALUTAZIONE ();
      return true;  // fine passaggio evento
    }//If Button
    else
      if (DispAction.getState()) AreaMsg.appendText ("ALTRO\n");
    return super.action (evt,arg);
  }//action
  
}//CalAp102

//*FINE FILE*