import java.awt.*;

public class Details extends Rectangle {

private int WIDTH;
private int HEIGHT; 

private SineWave sine1, sine2;
private Bragg bragg;


private Rectangle detectorBox;

private int leftMargin = 20;
private int rightMargin = 50;
private int length = 200; // width of sine waves
private int height1 = 40; // height of sine1
private int height2 = 80; // height of sie2
private int amplitude = 12;

private FontMetrics fm;

//--------------------CONSTRUCTOR----------------------------
public Details(int xnew, int ynew, int wnew, int hnew) {
  super(xnew, ynew, wnew, hnew);
  detectorBox = new Rectangle(x+width/2-70, y+height2+40, 140, 80);

}

//---------------------------DRAW---------------------------
public void draw(Graphics g, SineWave s1, SineWave s2, Bragg b) {
   this.bragg = new Bragg(Bragg.FORMULA, b.getLambda(Bragg.FORMULA),
               b.getDistance(Bragg.FORMULA), b.getTheta());
  this.sine1 = new SineWave(s1.getWavelength(), amplitude, s1.getPhase());
  this.sine2 = adjust(s2);
  if(fm == null) fm = g.getFontMetrics();

  initArea(g);
  drawGraphPaper(g);
  drawRays(g);
  drawRightAngle(g);
  drawVertDash(g);
  drawAtoms(g);
  drawSineWaves(g);
  drawText(g);
  drawDetector(g);
  drawDisplay(g);
  drawLight(g);
}

//-------------------------PRIVATE METHODS-----------------
private void initArea(Graphics g) {
  g.setColor(Color.white);
  g.fill3DRect(x, y, width, height, true);
  g.setColor(Color.black); 
  g.drawRect(x,y,width,height);    
}  

//--------
private void drawGraphPaper(Graphics g) {      
  g.setColor(Color.lightGray);
  for (int i = 10; i<width; i+=10) {
    g.drawLine(x+i, y+2, x+i, y+height-2);
  }
  for (int i = 10; i<height; i+=10) {
    g.drawLine(x+2, y+i, x+width-2, y+i); 
  }
}     
 
//----------
private void drawRays(Graphics g) {
  g.setColor(Color.black);
  g.drawLine(x+leftMargin, y+height1, x+leftMargin+length, y+height1);
  g.drawLine(x+leftMargin, y+height2, x+leftMargin+length, y+height2);
}

//-----------
private void drawRightAngle(Graphics g) {
  Rectangle rightAngle = new Rectangle(x+leftMargin, y+height2-10, 10, 10);
  g.drawRect(rightAngle.x,rightAngle.y,rightAngle.width,rightAngle.height);
}

//-----------
private void drawVertDash(Graphics g) {
  Segment.drawVertDashed(g, x+leftMargin, y+20, x+leftMargin, y+100, 5);
}

//----------
private void drawAtoms(Graphics g) {
  g.setColor(Color.red);
  g.fillOval(x+leftMargin-5, 45, 10, 10);
  g.setColor(Color.black);
  g.drawOval(x+leftMargin-5, 45, 10, 10);         
}

//----------
private void drawSineWaves(Graphics g) {      
  g.setColor(new Color(0, 120, 255));
  sine1.draw(g, x+leftMargin, y+height1, length);
  sine1.draw(g, x+leftMargin,  y+height1+1, length);
  sine2.draw(g, x+leftMargin, y+height2, length);
  sine2.draw(g, x+leftMargin, y+height2+1, length);  
}

//-----------
private void drawText(Graphics g) {
  String s = new String();
  // write wave1, wave2 beside sinewaves
  g.setColor(Color.black);
  g.drawString("X ray1", x+width-rightMargin, y+height1-10);
  g.drawString("X ray2", x+width-rightMargin, y+height2-10);
  // write detector on top
  s = "Detector";
  g.drawString(s, x+width/2 - fm.stringWidth(s)/2, detectorBox.y-5);  
  s = bragg.toString();
  g.drawString(s, x+width/2-fm.stringWidth(s)/2, y+height-10);
}

//-----------
private void drawDetector(Graphics g) {
  g.setColor(Color.lightGray);
  g.fill3DRect(detectorBox.x, detectorBox.y, detectorBox.width, 
                             detectorBox.height, true);
}

private void drawDisplay(Graphics g) {
  int radius, length;
//  Point center = new Point((x+width)/2, detectorBox.y+detectorBox.height-5);
  Point center = new Point(detectorBox.x+detectorBox.width/2,
                           detectorBox.y+detectorBox.height-5);
  radius = detectorBox.height-10;
  int startAngle = 215;
  g.setColor(Color.white);
  g.fillArc(center.x-radius, center.y-radius, 2*radius, 2*radius, 
                              startAngle-180, 180-2*(startAngle-180));
  g.setColor(Color.black);
  g.drawArc(center.x-radius, center.y-radius, 2*radius, 2*radius, 
                             startAngle-180, 180-2*(startAngle-180) );
  // draw borders for the scale
  Point p1 = MyMath.rotate(center, startAngle, radius);
  g.drawLine(center.x, center.y, p1.x-1, p1.y);
  Point p2 = MyMath.rotate(center, startAngle+180-2*(startAngle-180), 
                                    radius);
  g.drawLine(center.x, center.y, p2.x, p2.y);        

  // draw center oval
  g.drawOval(center.x-2, center.y-2, 4, 4);

   // draw divisions on the scale
   length = 5;
   radius = 65;
   for (int i = 5; i<110; i+=10)  { 
     if (i==5 || i==55 || i== 105)
         length = 10;
     else length = 5;
     Point upper = MyMath.rotate(center, startAngle+i, radius);
     Point lower = MyMath.rotate(center, startAngle+i, radius-length);
     g.drawLine(upper.x, upper.y, lower.x, lower.y);
  }     

  // draw the arrow indicator
  float ph1 = sine1.getPhase();
  while (ph1 >= 360) 
    ph1 -= 360;
  float ph2 = sine2.getPhase();
  while (ph2 >= 360) 
    ph2 -= 360;
  float combined = Math.abs(ph1 - ph2);     
  if (combined > 180) combined = 360 - combined;
    float fangle = combined*100f/180f;
  radius = 55;
  Point parrow = MyMath.rotate(center, startAngle+105-fangle, radius);
  g.drawLine(center.x, center.y, parrow.x, parrow.y);
  g.drawLine(center.x, center.y, parrow.x-1, parrow.y);
  g.drawLine(center.x, center.y, parrow.x+1, parrow.y);
}

private void drawLight(Graphics g) {
  Rectangle light = new Rectangle(detectorBox.x+detectorBox.width-15,
                                      detectorBox.y+5, 10,10);
  Color color;
  if(bragg.satisfied(1)) 
     color = Color.green;
  else 
     color = Color.red;
  g.setColor(color);
  g.fillOval(light.x, light.y, light.width, light.height);    
  g.setColor(Color.black);
  g.drawOval(light.x, light.y, light.width, light.height);
}

//-------
private SineWave adjust(SineWave s) {
   double distance = bragg.getDistance(Bragg.GRAPH);
   double theta = MyMath.toRadians(bragg.getTheta()); // in Radians
   distance = distance*Math.sin(theta);
   return new SineWave(s.getWavelength(), amplitude, 
                       s.getPhase((float)distance));
}

}

