import java.awt.*;
import java.awt.event.*;

public class CPuzzleField extends Canvas implements MouseListener
{
	private Dimension 	m_dPrefSize;	// Die Groesse wird des Puzzelfeldes
	private CPuzzleElement 	m_Element[];	// Die 9 Puzzelteile
	private boolean m_Down, m_Up;		// für die Mousesteuerung
	private int 		m_OldPos;	// speicher die Position der Mouse beim druecken der Maustaste.
	public CArrayRandom 	m_PuzzleState;
	public CArrayRandom 	m_PuzzlePos;

	public CPuzzleField(Dimension d,CPuzzleElement [] _Element)
	{
		.....
		addMouseListener(this);
	}

	public void merge(){.....}

	public Dimension getPreferredSize(){ return m_dPrefSize;}

	public Dimension getMinimumSize(){ return m_dPrefSize;}

	public void paint(Graphics g)
	{
		update(g);
	}

	public void update(Graphics g)
	{
		g.drawImage(Imgage, 0, 0, this);
		g.drawImage(m_Element[...].getElement(...), 0, 0, this);
		g.drawImage(m_Element[...].getElement(...), 150, 0, this);
                g.drawImage(m_Element[m_PuzzlePos.Get(2)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(2))), 300, 0, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(3)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(3))), 0, 150, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(4)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(4))), 150, 150, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(5)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(5))), 300, 150, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(6)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(6))), 0, 300, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(7)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(7))), 150, 300, this);
		g.drawImage(m_Element[m_PuzzlePos.Get(8)].getElement(m_PuzzleState.Get(m_PuzzlePos.Get(8))), 300, 300, this);
	}

	protected int getPos_isin(int x,int y)
	{
		if (             (x < 150) &&              (y < 150)) return 0;
		if ((149 < x) && (x < 300) &&              (y < 150)) return 1;
		if ((299 < x) && (x < 450) &&              (y < 150)) return 2;
		if (		 (x < 150) && (149 < y) && (y < 300)) return 3;
		if ((149 < x) && (x < 300) && (149 < y) && (y < 300)) return 4;
		if ((299 < x) && (x < 450) && (149 < y) && (y < 300)) return 5;
		if (		 (x < 150) && (299 < y) && (y < 450)) return 6;
		if ((149 < x) && (x < 300) && (299 < y) && (y < 450)) return 7;
		if ((299 < x) && (x < 450) && (299 < y) && (y < 450)) return 8;
		return -1;
	}

	protected void setNextPuzzleState(int i)
	{
		if (i != -1)
		{
			if (m_PuzzleState.Get(i) == 3)
				m_PuzzleState.Set(i, 0);
			else
				m_PuzzleState.Set(i, m_PuzzleState.Get(i) +1);
		}
	}

	protected void ChangePos(int newpos)
	{
		if ((m_OldPos != -1) && (newpos != -1))
		{
			int tmp = m_PuzzlePos.Get(m_OldPos);
			m_PuzzlePos.Set(m_OldPos, m_PuzzlePos.Get(newpos));
			m_PuzzlePos.Set(newpos, tmp);
		}
	}

	protected void ChangePosNeighbour(int newpos)
	{
		switch(m_OldPos)
		{
			case 0 :
				if ((newpos == 1) || (newpos == 3))
					ChangePos(newpos);
				break;
			case 1 :
				if ((newpos == 0) || (newpos == 2) || (newpos == 4))
					ChangePos(newpos);
				break;
			case 2 :
				if ((newpos == 1) || (newpos == 5))
					ChangePos(newpos);
				break;
			case 3 :
				if ((newpos == 0) || (newpos == 4) || (newpos == 6))
					ChangePos(newpos);
				break;
			case 4 :
				if ((newpos == 1) || (newpos == 3) || (newpos == 5) || (newpos == 7))
					ChangePos(newpos);
				break;
			case 5 :
				if ((newpos == 2) || (newpos == 4) || (newpos == 8))
					ChangePos(newpos);
				break;
			case 6 :
				if ((newpos == 3) || (newpos == 7))
					ChangePos(newpos);
				break;
			case 7 :
				if ((newpos == 4) || (newpos == 6) || (newpos == 8))
					ChangePos(newpos);
				break;
			case 8 :
				if ((newpos == 5) || (newpos == 7))
					ChangePos(newpos);
		}
	}

	public void mousePressed(MouseEvent e)
	{
		m_OldPos = getPos_isin(e.getX(), e.getY());
	}

	public void mouseReleased(MouseEvent e)
	{
		int NewPos = getPos_isin(e.getX(), e.getY());
		if(( m_OldPos == NewPos) && ( m_OldPos != -1))
			setNextPuzzleState(m_PuzzlePos.Get(m_OldPos));
		else
			ChangePosNeighbour(NewPos);
			m_OldPos = -1;
		repaint();
	}

	/**
	* Dieser Mausaktion wird nicht beachtet.
	*/
	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}

}