import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;
import java.util.Vector;  //  http://java.sun.com/products/jdk/1.1/docs/api/java.util.Vector.html





//---- Gadget

class Gadget
{
  protected int x, y, w, h;
  protected boolean dragable;

  protected Gadget[] gadget;
  protected int numGadgets;

  //---- Gadget - creates a new gadget

  public Gadget()
  {
    setSize(0, 0, 0, 0);
    setDragable(false);

    gadget = new Gadget[32];
    numGadgets = 0;
  }

  //---- Gadget - creates a new gadget with the given parameters

  public Gadget(int x, int y, int w, int h)
  {
    setSize(x, y, w, h);
    setDragable(false);

    gadget = new Gadget[32];
    numGadgets = 0;
  }

  //---- Gadget - creates a new gadget with the given parameters

  public Gadget(int x, int y, int w, int h, boolean dragable)
  {
    setSize(x, y, w, h);
    setDragable(dragable);

    gadget = new Gadget[32];
    numGadgets = 0;
  }

  //---- setSize - sets the size of this gadget

  public void setSize(int x, int y, int w, int h)
  {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }

  //---- setDraggable - sets this gadget's dragable flag

  public void setDragable(boolean dragable)
  {
    this.dragable = dragable;
  }

  //---- addGadget - adds a child gadget

  public void addGadget(Gadget g)
  {
    gadget[numGadgets++] = g;
  }

  //---- hitTest - returns a Gadget if the given position is within this gadget or one of it's child gadgets

  public Gadget hitTest(int hitx, int hity)
  {
    //- Return false if outside the gadget's bounding box

    if(!( hitx >= x && hity >= y && hitx < x+w && hity < y+h )) return false;
    
    //- Check each child gadget
    
    for(int i=0; i<numGadgets; i++)
    {
      Gadget g = gadget[i].hitTest(x, y);
      if(g != null) return g;
    }

    //- Didn't hit any of the child gadgets - so it hit this one
    
    return this;
  }

  //---- render
  
  public void render(Graphics g)
  {
    //- Render child gadgets
    
    for(int i=0; i<numGadgets; i++)
    {
      g.render(g);
    }
  }

  //---- mouseDown

  public void mouseDown(int x, int y)
  {
  
  }
  
  //---- mouseUp

  public void mouseUp(int x, int y)
  {
  
  }
  
  //---- mouseMove

  public void mouseMove(int x, int y)
  {
  
  }
  
  //---- mouseDrag

  public void mouseDrag(int x, int y, int oldx, int oldy)
  {
    this.x += x-oldx;
    this.y += y-oldy;
  }
}



//---- DragRect

class DragRect extends Gadget
{
  Color col;

  public DragRect(int x, int y, int w, int h, Color col)
  {
    super.Gadget(x, y, w, h);
    this.col = col;
  }

  public render(Graphics g)
  {
    g.setColor(col);
    g.fillRect(x, y, w, h);
  }
}



//---- ZgoBuilder

public class ZGoBuilder extends java.applet.Applet implements Runnable
{
  //- Data

  Thread runThread = null;

  int imw, imh;

  Gadget g;

  //- Main code

  public void init()
  {
    System.out.println("LKS ZGoBuilder");
    
    g = new Gadget(0, 0, size().width, size().height);
    
    g.addGadget(new DragRect( 0,  0, 40, 40, Color.red));
    g.addGadget(new DragRect(60,  0, 40, 40, Color.green));
    g.addGadget(new DragRect( 0, 60, 40, 40, Color.blue));
    g.addGadget(new DragRect(60, 60, 40, 40, Color.white));
  }

  public void start()
  {
    if(runThread == null)
    {
      runThread = new Thread(this);
      runThread.start();
    }
  }

  public void stop()
  {
    if(runThread != null)
    {
      runThread.stop();
      runThread = null;
    }
  }

  public void run()
  {
    imw = size().width;
    imh = size().height;
/*
    while(true)
    {
      repaint();
      try { runThread.sleep(10); } catch (InterruptedException e) { return; }
    }
*/
  }

  public void update(Graphics g)
  {
    paint(g);
  }

  int k = 0;

  public void paint(Graphics g)
  {
    g.setColor(Color.black);
    g.fillRect(0, 0, imw, imh);
    g.setColor((k++&1) == 0 ? Color.blue : Color.yellow);
    g.fillRect(0, 0, 10, 10);
  }



  int mouse_x = 0, mouse_y = 0;
  int mouse_oldx = 0, mouse_oldy = 0;
  boolean mouse_drag = true;



  public boolean mouseDown(Event evt, int x, int y)
  {
    mouse_oldx = x;
    mouse_oldy = y;
    mouse_x = x;
    mouse_y = y;
    mouse_drag = true;

    g.hitTest(x, y).mouseDown(x, y);

    return true;
  }


  
  public boolean mouseDrag(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;

    g.hitTest(x, y).mouseDrag(x, y);

    repaint();
    return true;
  }



  public boolean mouseUp(Event evt, int x, int y)
  {
    mouse_drag = false;

    g.hitTest(x, y).mouseUp(x, y);

    return true;
  }
  

}



