
import java.lang.*;
import java.awt.*;
import java.util.*;

public class Proj extends java.applet.Applet {
  
  GraphCanvas graph = new GraphCanvas(this);
  Options opt = new Options(this);   
  
  public void init() {
    setLayout(new BorderLayout(10, 10));
    add("Center", graph);
    add("East", opt);
  }

  public static void main(String arg[]){
    Proj p  = new Proj();
    Frame frame = new Frame("K-Means");
    p.init();
    frame.add("Center", p);
    frame.resize(800,600);
    frame.show();
    frame.resize(800,600);
  }
}

class GraphCanvas extends Canvas {

private final int       maxN = 30;      // the max number of terminals
private int             n = 15;         // the current number of terminals
private final int       r = 4;          // the radius of a terminal
private Point           p[];            // the terminals
private Point           current;        // the current one and its old location
private Rectangle       border, inner;  // applet borders
private Scrollbar       sb;             // scrollbar for changing n
private Image           buffer;         // buffer for double-buffering
private Graphics        bufg;           // buffer's Graphics
private Proj parent;

GraphCanvas(Proj myparent) {
        parent = myparent;
        this.init();
    }

public void init() {
  p = new Point[maxN];
  current = null;

  border = new Rectangle(0, 0, size().width - 1, size().height - 1);
  inner = new Rectangle(r + 1, r + 1,
                        size().width - 2 * r - 3, size().height - 2 * r - 23);

  // initialize the terminals to random locations
  for (int i = 0; i < maxN; i++) {
    p[i] = new Point((int) Math.round(Math.random()
                                  * (size().width - 2 * r - 2) + r + 1),
                     (int) Math.round(Math.random()
                                  * (size().height - 20 - 2 * r - 2) + r + 1));

  }

  setBackground(Color.white);
  // setLayout(new BorderLayout());

  sb = new Scrollbar(Scrollbar.HORIZONTAL, n, 5, 2, maxN);
  //  add(sb);

  buffer = createImage(size().width, size().height);
  bufg = buffer.getGraphics();
  bufg.setFont(getFont());
} // init()


public void update(Graphics g) {
  bufg.setColor(getBackground());
  bufg.fillRect(border.x, border.y, border.width, border.height);
  bufg.setColor(Color.black);
  bufg.drawRect(border.x, border.y, border.width, border.height);

  
  // redraw the terminals
  for (int i = 0; i < n; i++) {
    bufg.setColor(Color.green);
    bufg.fillOval(p[i].x - r, p[i].y - r, 2 * r, 2 * r);
    bufg.setColor(Color.black);
    bufg.drawOval(p[i].x - r, p[i].y - r, 2 * r, 2 * r);
  }

  // draw the current one in cyan
  if (current != null) {
    bufg.setColor(Color.cyan);
    bufg.fillOval(current.x - r, current.y - r, 2 * r, 2 * r);
    bufg.setColor(Color.black);
    bufg.drawOval(current.x - r, current.y - r, 2 * r, 2 * r);
  } 

  g.drawImage(buffer, 0, 0, null);
} // update(Graphics)


public void paint(Graphics g) {
  update(g);
} // paint(Graphics)


public boolean handleEvent(Event evt) {
  switch (evt.id) {

  case Event.MOUSE_DOWN: {
    Rectangle rect = new Rectangle();

    current = null;
    for (int i = 0; (i < n) && (current == null); i++) {
      rect.reshape(p[i].x - r, p[i].y - r, 2 * r, 2 * r);
      if (rect.inside(evt.x, evt.y)) {
        current = p[i];
      }
    }

    if (current == null && n < maxN) {
      p[++n] = new Point(evt.x, evt.y);
      current = p[n];
      if (inner.inside(evt.x, evt.y)) {
        current.move(evt.x, evt.y);
      }
      else {
        current.move(Math.max(Math.min(evt.x, inner.x + inner.width), inner.x),
                   Math.max(Math.min(evt.y, inner.y + inner.height), inner.y));
      }
      repaint();
    }
      
    break;
  }

  case Event.MOUSE_UP: {
    current = null;
    repaint();
    break;
  }

  case Event.MOUSE_DRAG: {
    if (current != null) {
      if (inner.inside(evt.x, evt.y)) {
        current.move(evt.x, evt.y);
      }
      else {
        current.move(Math.max(Math.min(evt.x, inner.x + inner.width), inner.x),
                   Math.max(Math.min(evt.y, inner.y + inner.height), inner.y));
      }
      repaint();
    }
    break;
  }

  case Event.SCROLL_LINE_UP: case Event.SCROLL_LINE_DOWN:
  case Event.SCROLL_PAGE_UP: case Event.SCROLL_PAGE_DOWN:
  case Event.SCROLL_ABSOLUTE: {
    n = Math.min(Math.max(sb.getValue(),n),maxN);
    repaint();
    break;
  }

  default: {
    break;
  }

  } // switch

  return(true);
} // handleEvent(Event)


// Euclidean distance between two points (x1,y1) and (x2,y2)
private int distance(int x1, int y1, int x2, int y2) {
  return((int) Math.round(Math.sqrt(
                     (double) (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))));
} // distance(int,int,int,int)


} // class GraphCanvas extends Canvas


class Options extends Panel {
// set of options at the right of the screen
Button b1 = new Button("clear");
Button b2 = new Button("run");
Button b3 = new Button("step");
Button b4 = new Button("reset");
Button b5 = new Button("example");
Button b6 = new Button("exit");
Proj parent;   

Options(Proj myparent) {
  parent = myparent;
  setLayout(new GridLayout(6, 1, 0, 10));
  add(b1);
  add(b2);
  add(b3);
  add(b4);
  add(b5); 
  add(b6);
}

public boolean action(Event evt, Object arg) {
  if (evt.target instanceof Button) {
    if (((String)arg).equals("step")) {
    }
    if (((String)arg).equals("next step")) {
    } 
    if (((String)arg).equals("reset")) { 
    }
    if (((String)arg).equals("clear")) { 
    }
    if (((String)arg).equals("run")) {
    }
    if (((String)arg).equals("example")) {
    } 
    if (((String)arg).equals("exit")) { 
    } 
  }                   
  return true; 
}    

}






