/*---------------------------------------------------------------------------------
	Applet: JigSaw	Author: Jan Stvesand	Date: 01/14/96	Version: 1.0
	Description:
	JigSaw Applet v1.0 Description
	Variables:		Usages:
	To compile: javac -g JigSaw.java
-----------------------------------------------------------------------------------------------*/import java.applet.Applet;import java.awt.BorderLayout;import java.awt.Button;import java.awt.Color;import java.awt.Dimension;import java.awt.Event;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.Panel;import java.net.URL;public class Jigsaw extends Applet{	private BlockPuzzle block;	final String sSolve = "Solve";	final String sScramble = "Scramble";	private Button bSolve;	private Button bScramble;	private int rows, cols;	// PARAMS	private String image;	private int scrambleDepth;	// ------	public void init()	{		image = getParameter("image");		rows = Integer.parseInt(getParameter("rows"));		cols = Integer.parseInt(getParameter("cols"));		scrambleDepth = Integer.parseInt(getParameter("scrambleDepth"));		// setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 10));		setLayout(new BorderLayout(10, 10));		bSolve = new Button(sSolve);		bScramble = new Button(sScramble);		block = new BlockPuzzle(image, cols, rows, scrambleDepth, this);		add("North", bSolve);		add("South", bScramble);		add("Center", block);		this				.resize(new Dimension(block.getWidth(),						block.getHeight() + 20 + 50));	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void start()	{		// Add start-up code here		this				.resize(new Dimension(block.getWidth(),						block.getHeight() + 20 + 50));	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void stop()	{		// Add code here	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void destroy()	{		// Add clean-up code here	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void paint(Graphics g)	{	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public boolean keyDown(Event evt, int key)	{		// key - The that is pressed. See the Event class		return true;	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public boolean action(Event evt, Object arg)	{		String capt;		if (evt.target instanceof Button)		{			capt = (String) arg;			System.out.println("arg : " + capt);			if (capt.equals(sSolve))				block.resetImage(true);			if (capt.equals(sScramble))				block.scrambleImage();		}		return true;	}} // class Jigsaw// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////class BlockPuzzle extends Panel{	final int border = 5;	final int up = 0;	final int down = 1;	final int right = 2;	final int left = 3;	// PARAMS	private int rows;	private int cols;	//	private int tileX;	private int tileY;	private int curx, cury;	private int x, y;	private int h, w;	private Font font;	private Color fg;	private Color bg;	private URL Home;	private Image iGIF, Puzzle;	private Graphics gGIF;	private int Grid[][];	private Applet parent;	// members for imageUpdate	public int Height;	public int Width;	boolean complete;	// *****************	private boolean scrambling;	private int Depth;	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	BlockPuzzle(String image, int iColumns, int iRows, int depth, Applet Parent)	{		super();		rows = iRows;		if (rows < 2)			rows = 2;		cols = iColumns;		if (cols < 2)			cols = 2;		parent = Parent;		Depth = depth < 5 ? 5 : depth;		Puzzle = loadImage(image);		if (Puzzle == null)		{			System.out.println("Error creating image Ib");		}		System.out.println(Puzzle.getWidth(this) + " : "				+ Puzzle.getHeight(this));		Grid = new int[cols + 1][rows + 1];		repaint();	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void paint(Graphics g)	{		if (complete)			g.drawImage(iGIF, 0, 0, this);		else		{			g.drawString("Sorry. Picture not ready, yet", 0, Height / 2);		}	}	/**	 * ---------------------------------------------------	 * 	 * ----------------------------------------------------	 */	public void update(Graphics g)	{		if (!scrambling)			paint(g);	}	public boolean mouseDown(Event evt, int x, int y)	{		int ax, ay;		int xg, yg;		int dx = 0, dy = 0;		xg = x / tileX;		yg = y / tileY;		System.out.println("GridPosition : " + xg + "," + yg);		if ((xg == curx - 1) && (yg == cury)) // right		{			moveHole(left);		}		else if ((xg == curx + 1) && (yg == cury)) // left		{			moveHole(right);		}		else if ((xg == curx) && (yg == cury + 1)) // up		{			moveHole(down);		}		else if ((xg == curx) && (yg == cury - 1)) // down		{			moveHole(up);		}		else			return true; // nothing		repaint();		return true;	}	Image loadImage(String image)	{		Image img, temp;		Graphics g;		img = parent.getImage(parent.getCodeBase(), image);		img.getWidth(this);		// while ( (this.Width == 0) || (this.Height==0) );		return img;	}	void resetImage(boolean update)	{		gGIF.setColor(Color.blue);		gGIF.fillRect(0, 0, w, h);		gGIF.setColor(Color.white);		setBackground(Color.green);		gGIF.drawImage(Puzzle, border, border, this);		for (x = 0; x < cols; x++)			for (y = 0; y < rows; y++)				Grid[x][y] = y * cols + x + 1;		Grid[cols - 1][rows - 1] = 0;		curx = cols - 1;		cury = rows - 1;		gGIF.clearRect(curx * tileX, cury * tileY, tileX, tileY);		if (update)			repaint();	}	void scrambleImage()	{		int loop, dx = 0, dy = 0;		int direction;		boolean nothing = false;		scrambling = true;		resetImage(false);		for (loop = 0; loop <= Depth; loop++)		{			parent.getAppletContext().showStatus(					"Scramble..." + loop + "/" + Depth);			direction = (int) (Math.random() * 4.0);			moveHole(direction);		}		parent.getAppletContext().showStatus("Scramble...done.");		scrambling = false;		repaint();	}	boolean moveHole(int dir) // moves the hole	{		int dx = 0, dy = 0;		switch (dir) {		case left: // left			if (curx > 0)			{				Grid[curx][cury] = Grid[curx - 1][cury];				Grid[--curx][cury] = 0;				dx = tileX;				dy = 0;			}			break;		case right: // right			if (curx < cols - 1)			{				Grid[curx][cury] = Grid[curx + 1][cury];				Grid[++curx][cury] = 0;				dx = -tileX;				dy = 0;			}			break;		case up: // up			if (cury > 0)			{				Grid[curx][cury] = Grid[curx][cury - 1];				Grid[curx][--cury] = 0;				dx = 0;				dy = tileY;			}			break;		case down: // down			if (cury < cols - 1)			{				Grid[curx][cury] = Grid[curx][cury + 1];				Grid[curx][++cury] = 0;				dx = 0;				dy = -tileY;			}			break;		} // switch		if ((dx + dy) != 0)		{			gGIF.copyArea(curx * tileX, cury * tileY, tileX, tileY, dx, dy);			gGIF.clearRect(curx * tileX, cury * tileY, tileX, tileY);		}		else			return false;		return true;	} // moveHole	public boolean imageUpdate(Image img, int infoflags, int x, int y,			int width, int height)	{		// System.out.println("Info :"+img+" "+infoflags+" "+x+" "+y+" "+width+"		// "+height);		if ((infoflags & (HEIGHT | WIDTH)) != 0)		{ // Initialisation of the background context			Height = height;			Width = width;			tileX = (Width + 2 * border) / cols;			tileY = (Height + 2 * border) / rows;			w = tileX * cols;			h = tileY * rows;			this.resize(new Dimension(w, h));			try			{				iGIF = parent.createImage(w, h);				if (iGIF == null)					System.out.println("Error creating image Iaa");				else					gGIF = iGIF.getGraphics();			}			catch (Exception e) {				System.out.println("Error while preparing Image" + e);			}			gGIF.drawImage(Puzzle, 0, 0, this);		}		if ((infoflags & (FRAMEBITS | SOMEBITS)) != 0)		{			parent.getAppletContext().showStatus(					"Loading..." + y * 100 / Height + "%");		}		if ((infoflags & ALLBITS) != 0)		{			complete = true;			scrambleImage();		}		return super.imageUpdate(img, infoflags, x, y, width, height);	}	public int getWidth() {		return Width;	}	public int getHeight() {		return Height;	}} // class
