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

class Example08_Window {
   int x0, y0; // upper-left corner
   static final int width = 30;
   static final int height = 30;

   public Example08_Window( int x, int y ) {
      x0 = x;
      y0 = y;
   }
   public boolean isInside( int x, int y ) {
      return x0 <= x && x < x0+width
         && y0 <= y && y < y0+height;
   }
   public void move( int delta_x, int delta_y ) {
      x0 += delta_x;
      y0 += delta_y;
   }
   public void draw( Graphics g, boolean isHilited, boolean isFilled ) {
      g.setColor( Color.white );
      g.drawRect( x0, y0, width-1, height-1 );
      g.setColor( Color.black );
      g.fillRect( x0+1, y0+1, width-2, height-2 );
      if ( isHilited || isFilled ) {
         g.setColor( isFilled ? Color.white : Color.gray );
         g.fillRect( x0+2, y0+2, width-4, height-4 );
      }
   }
}

public class Example08 extends Applet
   implements MouseListener, MouseMotionListener {

   Vector< Example08_Window > windows = new Vector< Example08_Window >();
   int indexOfWindowUnderCursor = -1; // -1 for none
   boolean isWindowUnderCursorBeingDragged = false;

   int mouse_x, mouse_y;

   public void init() {
      setBackground( Color.black );

      for ( int i = 0; i < 5; ++i ) {
         windows.addElement(
            new Example08_Window(
               (int)( Math.random() * getWidth() * 0.9f ),
               (int)( Math.random() * getHeight() * 0.9f )
            )
         );

      }

      addMouseListener( this );
      addMouseMotionListener( this );
   }

   private int computeIndexOfWindowUnderCursor() {
      for ( int i = windows.size()-1; i >= 0; --i ) {
         Example08_Window win = windows.elementAt(i);
         if ( win.isInside( mouse_x, mouse_y ) ) {
            return i;
         }
      }
      return -1;
   }

   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mouseClicked( MouseEvent e ) { }
   public void mousePressed( MouseEvent e ) {
      mouse_x = e.getX();
      mouse_y = e.getY();
      if ( ! isWindowUnderCursorBeingDragged
         && indexOfWindowUnderCursor > -1
      ) {
         isWindowUnderCursorBeingDragged = true;
         repaint();
      }
      e.consume();
   }
   public void mouseReleased( MouseEvent e ) {
      if ( isWindowUnderCursorBeingDragged ) {
         isWindowUnderCursorBeingDragged = false;
         repaint();
      }
      e.consume();
   }
   public void mouseMoved( MouseEvent e ) {
      mouse_x = e.getX();
      mouse_y = e.getY();
      int newIndex = computeIndexOfWindowUnderCursor();
      if ( newIndex != indexOfWindowUnderCursor ) {
         indexOfWindowUnderCursor = newIndex;
         repaint();
      }
      e.consume();
   }
   public void mouseDragged( MouseEvent e ) {
      int new_mouse_x = e.getX();
      int new_mouse_y = e.getY();
      if ( isWindowUnderCursorBeingDragged ) {
         Example08_Window win = windows.elementAt(indexOfWindowUnderCursor);
         win.move( new_mouse_x - mouse_x, new_mouse_y - mouse_y );
         repaint();
         e.consume();
      }
      mouse_x = new_mouse_x;
      mouse_y = new_mouse_y;
   }

   public void paint( Graphics g ) {
      for ( int i = 0; i < windows.size(); ++i ) {
         Example08_Window win = windows.elementAt(i);
         win.draw(
            g,
            i == indexOfWindowUnderCursor && !isWindowUnderCursorBeingDragged,
            i == indexOfWindowUnderCursor && isWindowUnderCursorBeingDragged
         );
      }
   }
}

