import mkgray.gui.*;
import mkgray.gui.util.*;
//import pia.util.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.net.*;

public class ShoeUIwin implements Runnable {
  Frame f;
  BarCanvas canv;
  boolean initialized, doGraphics;

  ServerSocket ss;
  Vector cons = new Vector();

  public static void main(String s[]){
    new ShoeUIwin(s);
  }

  ShoeUIwin(String args[]) {
    if(args.length != 0)
      if(args[0].equals("-nographics"))
	doGraphics = false;
      else
	doGraphics = true;
    else
      doGraphics = true;

    Thread runthis = new Thread(this);
    runthis.start();
    while(!initialized) {
      try { Thread.sleep(200); } catch (Exception e) { }
    }
    (new Thread(this)).start();
    while(true){
      if(initialized && doGraphics)
	f.repaint();
      try { Thread.sleep(200); } catch (Exception e) { }
    }
  }

  public void run() {
    int value;
    long lastt=0;
    long startt, endt;

    if(initialized){
      network_loop();
    }

    initialize_network();

    f = new Frame();
    f.add(canv=new BarCanvas());
    initialized = true;
    if(doGraphics){
      f.setBounds(0,0,600,520);
      f.pack();
      f.doLayout();
      f.show();
    }
    int ct = 0;
    int n = 0;
    int graphnum = 0;
    double np, pp;
    Random rand = new Random();
    InputStreamReader isr;

    value = 0;
    System.out.println("Initialized");
    byte buf[] = new byte[16];
    byte ping[] = { (byte) 128 };
    SerialPort sp = new SerialPort("COM1", 9600);
    sp.open();
    sp.write(ping, 1);
    try {
      sp.read(buf, 15);
    } catch (Exception e) { }

    while(true) {
      System.out.print(".");
      try {
	int it = 0;
	
	sp.write(ping, 1);
	buf[0] = 0;
	while(buf[0] != 42)
	  sp.read(buf, 1);
	sp.read(buf, 15);
      } catch (Exception e) { }

      spit_to_network(buf);

      for(graphnum=0;graphnum < 14;graphnum++){
	if((graphnum==11) || (graphnum == 12)){
	  if(buf[graphnum] < 0)
	    canv.bars[graphnum] = (int) ((canv.bars[graphnum]+3*(256+buf[graphnum]))/4);
	  else
	    canv.bars[graphnum] = (int) (((3*buf[graphnum])+canv.bars[graphnum])/4);
	}
	else{
	  if(buf[graphnum] < 0)
	    canv.bars[graphnum] = 256+buf[graphnum];
	  else
	    canv.bars[graphnum] = buf[graphnum];
	}
	System.out.println("Read "+((int) canv.bars[graphnum])+" from "+graphnum);
      }
      if(buf[14] != -1){
	canv.bat = buf[14];
	canv.battery = true;
      }
      else{
	canv.bat = buf[14];
	canv.battery = false;
      }
      if(doGraphics)
	canv.repaint();
      try { Thread.sleep(100); } catch (Exception e) { }
    }
  }

  public void initialize_network() {
    try {
      ss = new ServerSocket(9020);
    } catch (Exception e) {
      System.out.println("Couldn't create server socket: "+e);
      return;
    }
  }
  
  public void network_loop(){
    Socket tmp;
    if(ss == null)
      return;
    while(true){
      try { tmp = ss.accept();} catch (Exception e) { return; }
      cons.addElement(tmp);
    }
  }
  
  public void spit_to_network(byte tonet[]) {
    Socket tmp;
    for(Enumeration e = cons.elements();e.hasMoreElements();){
      tmp = (Socket) e.nextElement();
      try {
	(tmp.getOutputStream()).write(42);
	(tmp.getOutputStream()).write(tonet);
	(tmp.getOutputStream()).flush();
      } catch (Exception e2) {}
    }
  }
}

class BarCanvas extends Canvas {
  Image ui;
  boolean battery = false;
  DoubleBuffer db;
  double bat;
  double bars[] = new double[15];
  String barname[] = {"1", "2", "3", "4", "PAN", "Compass (quad)",
		      "Gyro", "Compass (iphase)",
		      "AMP accelerometer #1",
		      "AMP accelerometer #2",
		      "AMP accelerometer #3",
		      "Tilt A",
		      "Tilt B",
		      "Sonar",
		      "nothing"};
  BarCanvas() {
    ui = getToolkit().getImage("ui.jpg");
    db = new DoubleBuffer();
  }

  public void update(Graphics g){
    db.update(this, g);
//    g.setColor(Color.white);
//    g.fillRect(125, 295, 128, 16);
//    g.fillRect(103, 334, 128, 16);
//    g.fillRect(118, 382, 128, 16);
//    g.fillRect(128, 425, 128, 16);

//    g.fillRect(547, 315, 17, 170);
//    g.fillRect(475, 315, 17, 170);
//    g.setColor(Color.black);
//    paint(g);
  }

  public void paint(Graphics g){
    int llx, lly, lrx, lry, urx, ury, ulx, uly;
    int x1, x2, y1, y2;

    g.drawImage(ui, 0, 0, this);
    g.fillRect(126, 296, (int) (bars[0]/2), 14);
    g.fillRect(104, 335, (int) (bars[1]/2), 14);
    g.fillRect(119, 383, (int) (bars[2]/2), 14);
    g.fillRect(129, 426, (int) (bars[3]/2), 14);
    g.fillRect(548, (int) (485-(2*bars[4]/3)), 24, (int) (2*bars[4]/3));
    g.fillRect(476, (int) (485-(2*bars[6]/3)), 24, (int) (2*bars[6]/3));

    /* Compass */
    double cang;
    cang = Math.atan2((bars[7]-132), (bars[5]-132));
	 
    g.drawLine(216, 201, 
	       (int) (216+30*Math.cos(cang)),
	       (int) (201+30*Math.sin(cang)));
    g.fillArc((int) (216+(30*Math.cos(cang))-5),
	      (int) (201+(30*Math.sin(cang))-5),
	      10, 10, 0, 360);

    g.drawLine(364, 331, 
	       (int) (364+((bars[8]-128)/2)), 
	       (int) (331+((bars[9]-128)/2)));
    g.fillArc((int) (364+((bars[8]-128)/2)-5),
	      (int) (331+((bars[9]-128)/2)-5),
	      10, 10, 0, 360);

    g.drawLine(391, 393, 
	       (int) (391+((bars[8]-128)/2)), 
	       (int) (393+((bars[10]-128)/2)));
    g.fillArc((int) (391+((bars[8]-128)/2)-5),
	      (int) (393+((bars[10]-128)/2)-5),
	      10, 10, 0, 360);

    double ang;

    ang = Math.atan((bars[12]-128)/(bars[11]-128));
    x1 = 390-((int) (20*Math.sin(ang)));
    x2 = 390+((int) (20*Math.sin(ang)));
    y1 = 185-((int) (20*Math.cos(ang)));
    y2 = 185+((int) (20*Math.cos(ang)));

//    ang = Math.atan((y2-y1)/(x2-x1));
    ang += (Math.PI/2);

    ulx = (int) (x1-(25*Math.sin(ang)));
    llx = (int) (x1+(25*Math.sin(ang)));
    urx = (int) (x2-(25*Math.sin(ang)));
    lrx = (int) (x2+(25*Math.sin(ang)));

    uly = (int) (y1-(25*Math.cos(ang)));
    lly = (int) (y1+(25*Math.cos(ang)));
    ury = (int) (y2-(25*Math.cos(ang)));
    lry = (int) (y2+(25*Math.cos(ang)));


    int sx[] = { llx, lrx, urx, ulx };
    int sy[] = { lly, lry, ury, uly };

//    g.fillPolygon(sx, sy, 4);
    g.drawLine(390, 185, 390+((int) ((bars[11]-128)/1)), 185+((int) ((bars[12]-128)/1)));
    g.drawLine(350, 150, 350, 225);
    g.drawString("Roll", 325, 175);
    g.drawLine(350, 225, 450, 225);
    g.drawString("Pitch", 375, 235);
    g.fillArc(385+((int) ((bars[11]-128)/1)), 180+((int) ((bars[12]-128)/1)), 10, 10, 0, 360);

    if(battery)
      g.drawString("Warning!!!! Warning!!! __Battery Low__"+bat+" Warning!!! Warning!!!!", 200, 115);

    g.setColor(Color.black);
//    for(int b=0;b<13;b++){
//      g.fillRect(5, 12+(b*25), (int) bars[b], 15);
//      g.drawString(barname[b], 5, 10+(b*25));
//    }
  }
}


