/*
Programmer:  Konstantin Lukin
E-mail    :  lukink@ug.cs.sunysb.edu
*/

import java.awt.*;
import java.applet.*;
import java.net.*;


public class UserInterface extends Applet  {


public  TextField[] tf = { new TextField("3.0"), 
                           new TextField("3.0"), 
                           new TextField("30.0") };
private  Label[] label  = { new Label("Lambda", Label.CENTER),  
                           new Label("Distance", Label.CENTER), 
                           new Label("Theta", Label.CENTER) };
private Message message;
private  Button[] button;
private int PLACES = 2;
private GraphCanvas graph;
private Bragg bragg;
private Rectangle control, graphic, msg;
private Box[] box = new Box[3];
private float[] value; 
private float[] delta = { 0.1f, 0.1f, 1.0f }; 
private float[] range = { 5.0f, 0.5f, 5.0f, 0.5f, 50.0f, 5.0f };


public void init() {
   button = new Button[6];
   value = new float[3];
   setBackground(Color.lightGray);
   message = new Message(Message.EMPTY);
   graph = new GraphCanvas(this);
   setLayout(null);
   loadLayout();
}

public void paint(Graphics g) {
   drawControlBorder(g);
   drawMsgBorder(g);
   update(g);
}

public void update(Graphics g) {
   DisplayStatus(g);
}


public boolean action(Event evt, Object arg) {
  if((evt.target instanceof TextField)) {
     setGraph();
  }
  else if(evt.target instanceof Button) {
     int i=0;
     while(i<button.length && evt.target != button[i]) { i++;}
     int mod = i%2;
     int div = i/2;
     float d = value[div]; // assign old value
     try {
        d = Float.valueOf(tf[div].getText()).floatValue();
     }
     catch(NumberFormatException e) { setCode(4); return true; }

     if(mod == 0) {
        if(d > range[i]) { setCode(div+1); return true; }
        else tf[div].setText(Float.toString(d+delta[div]));
     }
     else {
        if(d < range[i]) { setCode(div+1); return true; }
        else tf[div].setText(Float.toString(d-delta[div]));
     }
     setGraph();
  }
  else return super.action(evt, arg);
  return true;
}

private void loadLayout() {
   int width = 110;
   int height = 78;  // height from the bottom
   int between = (size().width - 3*width)/4;
  
   Font label_font = new Font("Helvetica", Font.BOLD, 20);
   Font tf_font    = new Font("TimesRoman", Font.BOLD, 20);
   Font button_font = new Font("Courier", Font.BOLD, 12);
   
   graphic = new Rectangle(0, 0, size().width, size().height-height-30);
   control = new Rectangle(0, graphic.y+graphic.height, size().width , height);
   msg     = new Rectangle(control.x, control.y+control.height, control.width, 
                           size().height-control.y-control.height);
   setCode(Message.INIT);

   add(graph);
   graph.reshape(graphic.x, graphic.y, graphic.width, graphic.height);
   
   box[0]  = new Box(control.x+between, control.y+3,          width, height-6);
   box[1]  = new Box(box[0].x+box[0].width+between, box[0].y, width, height-6);
   box[2]  = new Box(box[1].x+box[1].width+between, box[1].y, width, height-6);
 
   for(int i=0; i<box.length; i++) {
      label[i].setFont(label_font);
      tf[i].setFont(tf_font);
      button[2*i] = new Button(">");
      button[2*i].setFont(button_font);
      button[2*i+1] = new Button("<");
      button[2*i+1].setFont(button_font);

      add(label[i]);
      add(tf[i]);
      add(button[2*i]);
      add(button[2*i+1]);

      label[i].reshape(box[i].top.x, box[i].top.y, box[i].top.width, box[i].top.height);

      tf[i].reshape(box[i].left.x, box[i].left.y, box[i].left.width, box[i].left.height);

      button[2*i].reshape(box[i].right_top.x,     box[i].right_top.y,
                          box[i].right_top.width, box[i].right_top.height);

      button[2*i+1].reshape(box[i].right_bottom.x,     box[i].right_bottom.y,
                          box[i].right_bottom.width, box[i].right_bottom.height);
   }
   setGraph();
   setCode(Message.EMPTY);
}
  
private void setGraph() {
  try {
      value[0] = Float.valueOf(tf[0].getText()).floatValue(); 
      value[1] = Float.valueOf(tf[1].getText()).floatValue();
      value[2] = Float.valueOf(tf[2].getText()).floatValue();
  }
  catch (NumberFormatException e) { setCode(3); return; }
  
  if(Bragg.LambdaOutOfRange(value[0], Bragg.FORMULA))   { setCode(1); return; }
  if(Bragg.DistanceOutOfRange(value[1], Bragg.FORMULA)) { setCode(2); return; } 
  if(Bragg.ThetaOutOfRange(value[2]))                   { setCode(3); return; }

  if(message.getType() == Message.ERROR_MSG) setCode(Message.EMPTY);

  bragg = new Bragg(Bragg.FORMULA, value[0], value[1], value[2]);
  graph.setGraph(bragg);
}

private void setCode(int code) {
   message.setCode(code);
   repaint();
}

private void DisplayStatus(Graphics g) {
   g.setColor(Color.lightGray);
   g.fillRect(msg.x+4, msg.y+3, msg.width-6, msg.height-6);

   if(message.getType() == Message.EMPTY) {
      return;
   }      

   Color color;
   if(message.getType() == Message.ERROR_MSG) color = Color.red;
   else if(message.getType() == Message.WARNING_MSG) color = Color.yellow;
   else color = Color.green;

   g.setColor(color);

   g.fillOval(msg.x+10, msg.y+msg.height/2-6, 12, 12);
   g.setColor(Color.black);
   g.drawOval(msg.x+10, msg.y+msg.height/2-6, 12, 12);

   
   g.setFont(new Font("Courier", Font.PLAIN, 16));
   g.setColor(Color.black);
   g.drawString(message.toString(), msg.x+40, msg.y+msg.height/2 + 6);
}

public void setDistTf(String s) {
   tf[1].setText(s);
   if(message.getType() ==Message.ERROR_MSG) {
      message.setCode(Message.EMPTY);
      repaint();
   }
}

public void setThetaTf(String s) {
   tf[2].setText(s);
   if(message.getType() ==Message.ERROR_MSG) { 
      message.setCode(Message.EMPTY);
      repaint();
   }
}   

private void drawControlBorder(Graphics g) {
   g.setColor(Color.gray);
   g.drawRect(control.x, control.y, control.width-3, control.height-3);
   g.setColor(Color.white);
   g.drawRect(control.x+2, control.y+2, control.width-3, control.height-3);
   g.setColor(Color.black);
   g.drawRect(control.x+1, control.y+1, control.width-3, control.height-3);
}

private void drawMsgBorder(Graphics g) {
   g.setColor(Color.gray);
   g.drawRect(msg.x, msg.y, msg.width-3, msg.height-3);

   g.setColor(Color.white);
   g.drawRect(msg.x+2, msg.y+2, msg.width-3, msg.height-3);

   g.setColor(Color.black);
   g.drawRect(msg.x+1, msg.y+1, msg.width-3, msg.height-3);
}

}




