
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

abstract public class MagnetGUI extends PhysicsApplet{

  double[][] A;
  double[][] Bx;
  double[][] By;
  int[][] State;
  VectorDisplay D;
  TitleCanvas Legend;
  double Icell = 100.0;    /*  current in a square, in A  */
  double a = 1.0e-3;         /* grid spacing, in m   */  
  int displayB;     /*  = 1 to display B, = -1 to display H  */
  double Bscale = 5.0;
  double mu = 50.0;
     // mouse modes:
  static final int NormalMode = 0;
  static final int UpWireMode = 1;
  static final int DownWireMode = 2;
  static final int IronMode = 3;
  static final int EraseWireMode = 4;
  static final int EraseIronMode = 5;
  static final int MeasureMode = 6;
     // button codes:
  static final int FieldResetCode = 1;
  static final int AllResetCode = 2;
  static final int MeasureBCode = 3;
  static final int StartCode = 4;
  static final int StopCode = 5;
  static final int BScrollBarCode = 6;
  static final int muScrollBarCode = 7;
  static final int BHCode = 8;
  static final int CurrentsCode = 9;
    // array states:
  static final int NormalState = 0;
  static final int UpWireState = 1;
  static final int DownWireState = 2;
  static final int IronState = 3;
    // Scrollbars and labels 
  PhysicsScrollbar PSBmu, PSBB;
  BoldLabel SBmuLabel, SBBLabel;
  

  MagnetGUI(){
    super("Magnet Applet",100,100,4);
    A = new double[Nx+1][Ny+1];
    Bx = new double[Nx+1][Ny+1];
    By = new double[Nx+1][Ny+1];
    displayB = 1;
    State = new int[Nx+1][Ny+1];
    for (int i = 0; i <= Nx; i++){
      for (int j = 0; j <= Ny; j++){
         A[i][j] = 0.0;
         State[i][j] = 0;
       }
    }
  }

  void fillB(){
    if (displayB == 1){
      for (int i =1; i < Nx; i++){
        for (int j = 1; j < Ny; j++){
	  Bx[i][j] = (A[i][j]-A[i][j-1])/a;
	  By[i][j] = - (A[i][j]-A[i-1][j])/a;
        }
      }
    } else {   /* fill Bx, By with Hx, Hy   */
      for (int i =1; i < Nx; i++){
        for (int j = 1; j < Ny; j++){
	  double mui = 1.0;
	  if (State[i][j] == IronState) mui  = mu;
	  Bx[i][j] = (A[i][j]-A[i][j-1])/(mui * a);
	  By[i][j] = - (A[i][j]-A[i-1][j])/(mui * a);
        }
      }
    }
  }

  void resetArrays(){
      for (int mx = 0; mx <= Nx; mx++){
        for (int my = 0; my <= Ny; my++){
         A[mx][my] = 0.0;
        }
      }
      refreshPicture();
    }

    void resetAll(){
      for (int mx = 0; mx <= Nx; mx++){
        for (int my = 0; my <= Ny; my++){
         A[mx][my] = 0.0;
         State[mx][my] = 0;
        }
      }
      refreshPicture();
    }

  void buildPicture(){
    D = new VectorDisplay(Bx,By,State,Bscale,Color.black,Color.magenta);
    Picture.add(D,"Center");
    Legend = new TitleCanvas(" ", 16);
    Picture.add(Legend,"South");
  }

  void refreshPicture(){
    fillB();
    D.refresh();
  }
  
  void buildControls(){
    Controls.setLayout(new GridLayout(0,6,10,10));
    ModeButton B1 = new ModeButton("Wire Up", UpWireMode);
    Controls.add(B1);
    ModeButton B2 = new ModeButton("Wire Down", DownWireMode);
    Controls.add(B2);   
    ModeButton B3 = new ModeButton("Erase Wire", EraseWireMode);
    Controls.add(B3);   
    CommandButton B7 = new CommandButton("Currents", CurrentsCode);
    Controls.add(B7);
    ModeButton B5 = new ModeButton("Iron", IronMode);
    Controls.add(B5);
    ModeButton B6 = new ModeButton("Erase Iron", EraseIronMode);
    Controls.add(B6);
    CommandButton B9 = new CommandButton("Solve", StartCode);
    Controls.add(B9);
    CommandButton B10 = new CommandButton("Stop", StopCode);
    Controls.add(B10);
    ModeButton B11 = new ModeButton("Measure", MeasureMode);
    Controls.add(B11);
    CommandButton B12 = new CommandButton("Toggle B/H", BHCode);
    Controls.add(B12);
    CommandButton B8 = new CommandButton("Reset Fields", FieldResetCode);
    Controls.add(B8);
    CommandButton B4 = new CommandButton("Reset All", AllResetCode);
    Controls.add(B4);
    BoldLabel B13 = new BoldLabel(" Mu ");
    Controls.add(B13);
    PSBmu = new PhysicsScrollbar(mu, 1.0, 100.0, muScrollBarCode);
    Controls.add(PSBmu);
    SBmuLabel = new BoldLabel("   "+mu);
    Controls.add(SBmuLabel);
    BoldLabel B17 = new BoldLabel("  Scale of B/H ");
    Controls.add(B17);
    PSBB = new PhysicsScrollbar(Bscale, 1.0, 50.0, BScrollBarCode);
    Controls.add(PSBB);
    SBBLabel = new BoldLabel("   "+Bscale+" gauss");
    Controls.add(SBBLabel);
  }

  Color findColor(double A, int S){
    if (S == NormalState) return Color.white;
    if (S == IronState)  return Color.yellow;
    if (S == UpWireState)  return Color.green;
    if (S == DownWireState)   return Color.red;
    return Color.black;
  }

  void writeVectorValue(double Vx, double Vy, int mode){
    if (mode == MeasureMode){
      if (displayB == 1){
          Legend.write(" B = ( "+ Vx + " , " + Vy + " )   gauss ");
      }  else {
          Legend.write(" H = ( "+ Vx + " , " + Vy + " )   gauss ");
      }
    }
  }

  void setArrays(int i, int j, int mode){
    switch(mode){
      case UpWireMode : 
	State[i][j] = UpWireState;
        break;
      case DownWireMode : 
	State[i][j] = DownWireState;
        break;
      case IronMode : 
	if (State[i][j] == NormalState) State[i][j] = IronState;
        break;
      case EraseWireMode : 
	if (State[i][j] == UpWireState || State[i][j] == DownWireState)
                  State[i][j] = NormalState;
        break;
      case EraseIronMode : 
	if (State[i][j] == IronState) State[i][j] = NormalState;
        break;
      default : 
        break;
    }
  }

  void doAction(int Code){
    switch(Code){
      case FieldResetCode:
        resetArrays();
        break;;
     case AllResetCode:
        resetAll();
        break;
     case BHCode:
        displayB *= -1;
        refreshPicture();
        break;
     case StartCode:
        startThread();
        break;
     case StopCode:
        stopThread();
        break;
     case muScrollBarCode:
        mu = PSBmu.getReading();
        SBmuLabel.setText(mu+" ");
        break;
     case BScrollBarCode:
        Bscale = PSBB.getReading();
        SBBLabel.setText("   "+Bscale+" gauss");
        D.resetscale(Bscale);
        break;
     case CurrentsCode:
        int upc = 0, downc = 0;
	for (int i = 1; i < Nx ; i++){
	  for (int j =1 ; j < Ny; j++){
	      if (State[i][j] == UpWireState) upc++;
              if (State[i][j] == DownWireState) downc++;
          }
        }
        double upcurrent = Icell * upc;
        double downcurrent = Icell * downc;
        Legend.write(
          " Total current : "+upcurrent+" A up; "+downcurrent+" A down");
        break;  
     default:
        break;
    } 
  }

  void writeFieldValue(double Val, int mode){};
}
      
    










