
import java.awt.*;
import java.applet.*;
import java.util.*;

public class BezierApplet
  extends Applet
{
  public Hashtable htDr;
  private int W;
  private int H;
  private Dot grabbedDot;
  private int xBase = 250;
  private int yBase = 250;

  private boolean showContrib = true;
  private boolean doSpline = false;
  private boolean doLagrange = true;

  private Color gold = new Color( 255, 215, 0 );
  private Color steelBlue = new Color( 70, 130, 180 );
  private Color curveColor[] = {
                             Color.cyan, Color.magenta, Color.yellow,
                             Color.red, Color.green, Color.blue,
                             Color.orange, Color.pink
                           };

  public BezierApplet()
  {
    this( 500, 500 );
  }

  public BezierApplet( int w, int h )
  {
    W = w;
    H = h;
    htDr = new Hashtable();
    setBackground( Color.black );
  }

  public Dimension minimumSize()
  {
    return new Dimension( W, H );
  }
  public Dimension preferredSize()
  {
    return minimumSize();
  }

  public void paint( Graphics g )
  {
    Enumeration e = htDr.elements();

    while( e.hasMoreElements() ) {
      Drawable dr = (Drawable)( e.nextElement() );
      dr.paint( g );
    }
  }

  public void addDrawable( String name, Drawable dr )
  {
    htDr.put( name, dr );
  }

  public Drawable getDrawable( String name )
  {
    return (Drawable)( htDr.get( name ) );
  }

  public Dot closestDot( int x, int y )
  {
    Dot d = null;
    Enumeration e = htDr.elements();

    int minSep = 7;

    while( e.hasMoreElements() ) {
      Drawable dr = (Drawable)( e.nextElement() );
      if( dr instanceof Dot ) {
        Dot a = (Dot)dr;
        int sep =  a.separation( x, y );
        if( ( sep < 6 ) && ( minSep > sep ) ) {
          minSep = sep;
          d = a;
        }
      }
    }
    return d;
  }

  public boolean handleEvent( Event evt )
  {
    if( evt.id == Event.MOUSE_DOWN ) {
      grabbedDot = closestDot( evt.x, evt.y );
    }
    if( evt.id == Event.MOUSE_DRAG ) {
      if( grabbedDot != null ) {
        grabbedDot.requestMove( evt.x, evt.y );
        repaint();
      }
    }
    if( evt.id == Event.MOUSE_UP ) {
      if( grabbedDot != null ) {
        grabbedDot.requestMove( evt.x, evt.y );
        repaint();
      }
    }
    return super.handleEvent( evt );
  }

  public void init()
  {
    htDr.clear();
    Dot p0 = new Dot( "p0", 50, 250, true, true, Color.white );
    addDrawable( "p0", p0 );
    Dot p1 = new Dot( "p1", 250, 50, true, true, Color.blue );
    addDrawable( "p1", p1 );
    Dot p2 = new Dot( "p2", 250, 450, true, true, Color.green );
    addDrawable( "p2", p2 );
    Dot p3 = new Dot( "p3", 450, 250, true, true, Color.white );
    addDrawable( "p3", p3 );
    BezierSegment bz = new BezierSegment( "bz", p0, p1, p2, p3, steelBlue );
    addDrawable( "bz", bz );
    Line t1 = new Line( "t1", p0, p1, Color.gray );
    addDrawable( "t1", t1 );
    Line t2 = new Line( "t2", p3, p2, Color.gray );
    addDrawable( "t2", t2 );

    Dot q0 = new Dot( "q0", 450, 50, true, true, Color.white );
    addDrawable( "q0", q0 );
    Dot q1 = new Dot( "q1", 475, 75, true, true, Color.red );
    addDrawable( "q1", q1 );
    Dot q2 = new Dot( "q2", 450, 100, true, true, Color.white );
    addDrawable( "q2", q2 );
    QuadBezierSegment qbz = new QuadBezierSegment( "qbz", q0, q1, q2, gold );
    addDrawable( "qbz", qbz );
    Line u1 = new Line( "u1", q0, q1, Color.gray );
    addDrawable( "u1", u1 );
    Line u2 = new Line( "u2", q2, q1, Color.gray );
    addDrawable( "u2", u2 );
    repaint();
  }

  public static void main( String[] args )
  {
    BezierApplet p = new BezierApplet( 500, 500 );
    p.init();
    KFrame fr = new KFrame( "Bezier Spline" );
    fr.add( "Center", p );
    fr.pack();
    fr.show();
  }
}
