 /*
  <PRE>
  JailEscape
  (C) 11.3.1997
  Wolfram Koerner, Lehrstuhl Informatik II
  Universitaet Wuerzburg, Deutschland
 
  Ziel des Spieles:
  -----------------
  Der rote Spielstein soll mit moeglichst wenigen Zuegen zum
  Ausgang des Gefaengnisses (am unteren Spielfeldrand)
  bewegt werden.
 
 */
 
 import java.awt.Rectangle;
 import java.awt.Event;
 import java.awt.Graphics;
 import java.awt.Color;
 import java.awt.Font;
 import java.io.*;
 // import java.lang.*;
 
 
 public class JailEscape extends java.applet.Applet {
     Rectangle AppletRect;
	 Rectangle AllStoneRect;  // Bereich in dem Klicks erlaubt sind
     Rectangle stone[];       // Bereiche der Spielsteine
     Color stone_fill[];
     Color stone_border;
     int selectedStone;
     int field_width;
     int field_height;
     int stone_width;
     int stone_height;
     int first_paint = 1;
     int move_count;
 
     public synchronized void init() {
         selectedStone = -1;
         stone = new Rectangle[10];
         stone_fill = new Color[10];
         stone_border = Color.black;
         move_count = 0;
     }
 
     public boolean handleEvent(Event event)
     {
         switch (event.id)
             {
             case Event.MOUSE_DOWN:
                 int i;
                 int Klick_on_Stone = 0;
                 int debug = selectedStone;
 
                 if (! AllStoneRect.inside(event.x, event.y)) // Klick ausserhalb Spielfeld
					return true;
				 for(i=0; i<10;i++)
                 {
                     if (stone[i].inside(event.x, event.y)) // Klick auf i-ten Stein
                     {
                         if (selectedStone == i) // ist schon gewaehlt !
                         {
                             selectedStone = -1;
                             Klick_on_Stone = 1;
                             repaint(5+stone[i].x, 5+stone[i].y
                                 ,stone[i].width, stone[i].height);
                         }
                         else                    // noch nicht gewaehlt
                         {
                             int tmpsel = selectedStone;
                             selectedStone = i;
                             Klick_on_Stone = 1;
                             if (tmpsel != -1)
                             {
                                 repaint(5+stone[tmpsel].x, 5+stone[tmpsel].y
                                         ,stone[tmpsel].width, stone[tmpsel].height);
                             }
                             repaint(5+stone[i].x, 5+stone[i].y
                                 ,stone[i].width, stone[i].height);
                         }
 
                     }
                 }
                 if (Klick_on_Stone == 1)  // Auf Stein geklickt -> fertig !
                 {
                     return true;
                 }
 
                 if (selectedStone != -1)  // es ist ein Stein selektiert !
                 // Jetzt versuchen, Stein in Richtung Klick zu bewegen.
                 {
                     Rectangle newStoneRect =
                         // bissl kleiner, damit keine Randueberschneidungen
                                 new Rectangle(stone[selectedStone].x+1
                                       ,stone[selectedStone].y+1
                                       ,stone[selectedStone].width-2
                                       ,stone[selectedStone].height-2);
                     Rectangle oldStoneRect =
                         new Rectangle(stone[selectedStone].x
                                       ,stone[selectedStone].y
                                       ,stone[selectedStone].width
                                       ,stone[selectedStone].height);
                     if (event.x < stone[selectedStone].x)     	// LINKS
                     {
                         newStoneRect.translate(-stone_width,0);
                     }
                     else if (event.x > stone[selectedStone].x   // RECHTS
                              +stone[selectedStone].width)
                     {
                         newStoneRect.translate(stone_width,0);
                     }
                     else if (event.y < stone[selectedStone].y)  // OBEN
                     {
                         newStoneRect.translate(0, -stone_height);
                     }
                     else if (event.y > stone[selectedStone].y   // UNTEN
                              +stone[selectedStone].height)
                     {
                         newStoneRect.translate(0, stone_height);
                     }
                     
                     int newPosOK = 1;
                     for (i=0; i<10;i++)  // Test, ob neue Position O.K.
                     {
                         System.out.println("Test:"+i);
                         if ((i!=selectedStone)
                             && (newStoneRect.intersects(stone[i])))
                         {
                             newPosOK = 0;
                         }
                     }
                     if (newPosOK == 1)  // Keine Kollisionen ?
                     {
 
                         // Selektierten Stein verschieben
                         // wieder groesser machen...
                         newStoneRect.reshape(newStoneRect.x-1,newStoneRect.y-1
                                                                 ,newStoneRect.width+2,newStoneRect.height+2);
                         stone[selectedStone] = newStoneRect;
                         // Alte Position neu zeichnen
                         repaint(5+oldStoneRect.x, 5+oldStoneRect.y
                                 ,oldStoneRect.x + oldStoneRect.width
                                 ,oldStoneRect.y + oldStoneRect.height);
                         // Neue Position neu zeichnen
                         repaint(5+newStoneRect.x, 5+newStoneRect.y
                                 ,newStoneRect.x + newStoneRect.width
                                 ,newStoneRect.y + newStoneRect.height);
                         move_count++;
                             
                     }
                 }
                 return true;
             default:
                 return false;
             }
     }
     
 
     public synchronized void paint(Graphics g) {
         if (first_paint == 1)
         {
             // Init
             first_paint = 0;
             AppletRect = new Rectangle (g.getClipRect().x, g.getClipRect().y
                                       ,g.getClipRect().width, g.getClipRect().height);
			 AllStoneRect = new Rectangle (g.getClipRect().x+10, g.getClipRect().y+10
                                       ,g.getClipRect().width-20, g.getClipRect().height-20);
             field_width  = g.getClipRect().width-10;
             field_height = g.getClipRect().height-10;
             stone_width = field_width / 4;
             stone_height = field_height / 5;
             // Die Spielsteine mit Anfangspositionen
             stone[0] = new Rectangle (1 * stone_width,0 * stone_height
                                       ,2 * stone_width,2 * stone_height);
             stone[1] = new Rectangle (0 * stone_width,0 * stone_height
                                       ,1 * stone_width,2 * stone_height);
             stone[2] = new Rectangle (3 * stone_width,0 * stone_height
                                       ,1 * stone_width,2 * stone_height);
             stone[3] = new Rectangle (1 * stone_width,2 * stone_height
                                       ,2 * stone_width,1 * stone_height);
             stone[4] = new Rectangle (0 * stone_width,3 * stone_height
                                       ,1 * stone_width,2 * stone_height);
             stone[5] = new Rectangle (3 * stone_width,3 * stone_height
                                       ,1 * stone_width,2 * stone_height);
             stone[6] = new Rectangle (1 * stone_width,3 * stone_height
                                       ,1 * stone_width,1 * stone_height);
             stone[7] = new Rectangle (2 * stone_width,3 * stone_height
                                       ,1 * stone_width,1 * stone_height);
             stone[8] = new Rectangle (1 * stone_width,4 * stone_height
                                       ,1 * stone_width,1 * stone_height);
             stone[9] = new Rectangle (2 * stone_width,4 * stone_height
                                       ,1 * stone_width,1 * stone_height);
             // Farben der Spielsteine
             stone_fill[0] = Color.red;
             stone_fill[1] = Color.blue;
             stone_fill[2] = Color.blue;
             stone_fill[3] = Color.blue;
             stone_fill[4] = Color.blue;
             stone_fill[5] = Color.blue;
             stone_fill[6] = Color.yellow;
             stone_fill[7] = Color.yellow;
             stone_fill[8] = Color.yellow;
             stone_fill[9] = Color.yellow;
 
         }
             
         paintField(g);
         showStatus("Zuege bis jetzt: " + move_count);
     }
     
     public synchronized void paintField(Graphics g) {
         int i;
         int j;
 
         // Spielfeldrahmen zeichnen
         g.setColor(Color.black);
         for(i=0; i<5; i++)
         {
             g.drawRect(i,i,AppletRect.width-2*i
                        ,AppletRect.height-2*i);
         }
         g.setColor(getBackground());
         g.fillRect(1*stone_width, AppletRect.height-5 //Oeffnung unten
                    ,2*stone_width, 5);
         g.setColor(Color.black);
 
         // Spielsteine zeichnen
         for (i=0; i<10; i++)
         {
             g.setColor(stone_fill[i]);
             g.fillRoundRect(5+stone[i].x, 5+stone[i].y
                             ,stone[i].width, stone[i].height
                             ,20,20);
             g.setColor(Color.black);
             g.drawRoundRect(5+stone[i].x, 5+stone[i].y
                             ,stone[i].width, stone[i].height
                             ,20,20);
             // Markierung des selektierten Spielsteines
             if (i==selectedStone)
             {
                 g.drawLine(stone[i].x+15, stone[i].y+15,
                            stone[i].x+stone[i].width-5, stone[i].y+stone[i].height-5);
                 g.drawLine(stone[i].x+stone[i].width-5, stone[i].y+15,
                            stone[i].x+15, stone[i].y+stone[i].height-5);
 
                 g.setColor(Color.white);
                 g.drawLine(1+stone[i].x+15, stone[i].y+15,
                            1+stone[i].x+stone[i].width-5, stone[i].y+stone[i].height-5);
                 g.drawLine(1+stone[i].x+stone[i].width-5, stone[i].y+15,
                            1+stone[i].x+15, stone[i].y+stone[i].height-5);
                 g.setColor(Color.black);
             }
         }
     }
 }
 
 /*
  </PRE>
  */
