import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class FuchsSimulation extends JFrame
{
	int anzBreite 		= 240;
	int anzHoehe		= 160;
	int pixel		= 3;
	int msec		= 50;
	Brett brett;
	FuchsGUI gui;
	SpielManager manager;
	Container container;
	public FuchsSimulation()
	{
		this.setSize(1000, 650);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		brett	= new Brett(anzBreite, anzHoehe, pixel);
		manager	= new SpielManager(brett, msec);
		gui			= new FuchsGUI(manager);
		container	= getContentPane();
		brett.setBackground(new Color(50, 200, 50));
		container.setLayout(new BorderLayout());
		container.add("Center", brett);
		container.add("East", gui);
	}
	public static void main(String[] args)
	{
		FuchsSimulation fuchs = new FuchsSimulation();
		fuchs.setVisible(true);
	}
}
class FuchsGUI extends JPanel
{
	SpielManager manager;
	int anzPanel = 5;
	Panel[] panel = new Panel[anzPanel];
	JSlider slider1;
	JButton bStart;
	Checkbox cRiechen = new Checkbox();
	boolean check = false;
	public FuchsGUI(SpielManager manager)
	{
		this.manager = manager;
		setKomponenten();
		setPanel();
		setBackground(new Color(50, 200, 50));
		setVisible(true);
	}
	public void setKomponenten()
	{
		cRiechen = new Checkbox("um diese CheckBox geht s", true);
		bStart 	= new JButton(" START ");
		bStart.setBackground(new Color(150, 180, 250));
		slider1 = new JSlider(JSlider.HORIZONTAL, 1, 10, 5);
		slider1.setBackground(new Color(50, 200, 50));
		cRiechen.addItemListener
		(new ItemListener()
			{public void itemStateChanged(ItemEvent e)
				{
					check = !check;
					System.out.println("CheckBox "+check);
				}
			}
		);
		bStart.addActionListener
		(new ActionListener()  // Start-Button
			{public void actionPerformed(ActionEvent e)
				{
					manager.neuStart();
					manager.start();
				}
			}
		);
	}
	public void setPanel()
	{
		for (int i=0; i<anzPanel; i++)
			panel[i] = new Panel();
		panel[0].setLayout(new GridLayout(0,1));
		panel[1].setLayout(new GridLayout(0,1));
		panel[2].setLayout(new GridLayout(0,1));
		panel[3].setLayout(new GridLayout(0,1));
		panel[4].setLayout(new FlowLayout());
		panel[0].add(slider1);
		panel[1].add(cRiechen);
		bStart.setSize(40, 60);
		panel[2].add(bStart);
		panel[3].add(panel[0]);
		panel[3].add(panel[1]);
		panel[3].add(panel[2]);
		add(panel[3]);
	}
}
class SpielManager extends Thread
{
	BrettGrund grund;
	Feld nachbarfeld;
	Brett brett;
	int msec;
	Thread running;
	public SpielManager(Brett brett, int msec)
	{
		this.brett	= brett;
		this.msec	= msec;
	}
	public void start()
	{	if (running == null)
		{	running = new Thread (this);
			running.start();
	}	}
	public void run()
	{
		while(true)
		{
			verzoegerung (msec);
			wandern();
			brett.repaint();
		}
	}
	public void neuStart()
	{
		int i = 0;
		while (i <3000)
		{
			int x = (int)(Math.random()*(double)brett.getAnzBreite());
			int y = (int)(Math.random()*(double)brett.getAnzHoehe());
			if(brett.feld[x][y].getBesetzt()) continue;
			brett.feld[x][y].setBesetzt(true);
			i++;
		}
	}
	public void wandern()
	{
		Feld nachbar = null;
		for (int x=0; x<brett.getAnzBreite(); x++)
		for (int y=0; y<brett.getAnzHoehe(); y++)
		{	if(brett.feld[x][y].getBesetzt()==false) continue;
			nachbar = nachbarfeldLeer(x, y);
			nachbar.setBesetzt(true);
			brett.feld[x][y].setBesetzt(false);
		}
	}
	public Feld nachbarfeldLeer(int x, int y)
	{
		Feld nachbar;
		int nr = (int)(4.*Math.random());
		for(int i=0; i<4; i++)
		{
			nachbar = brett.nachbarfeld(x, y, (nr+i)%4+1);
			if(nachbar.getBesetzt()==false) return nachbar;
		}
		return brett.nachbarfeld(x, y, 0);
	}
	public void verzoegerung (int msec)
	{
		try {Thread.sleep (msec);}
		catch(Exception e){}
	}
}
class Brett extends JPanel
{
	int anzBreite, anzHoehe, pix;
	Feld[][] feld;
	Feld nachbarfeld;
	public Brett(int anzBreite, int anzHoehe, int pix)
	{
		this.anzBreite	= anzBreite;
		this.anzHoehe	= anzHoehe;
		this.pix			= pix;
		Feld.setParameter(pix);
		feld 				= new Feld[anzBreite][anzHoehe];
		neu();
	}
	public void neu()
	{
		for (int x=0; x<anzBreite; x++)
		for (int y=0; y<anzHoehe; y++)
			feld[x][y] = new Feld(x, y);
	}
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		for (int x=0; x<anzBreite; x++)
		for (int y=0; y<anzHoehe; y++)
			feld[x][y].paintComponent(g);
	}
	public Feld nachbarfeld(int x, int y, int nr)
	{
		switch(nr)
		{
			case 0 :
			{
				return feld[x][y];
			}
			case 1 :
			{
				int xx = x+1;
				if(xx > anzBreite-1)	xx = 0;
				return feld[xx][y];
			}
			case 2 :
			{
				int yy = y+1;
				if(yy > anzHoehe-1) yy = 0;
				return feld[x][yy];
			}
			case 3 :
			{
				int xx = x-1;
				if(xx< 0) xx = anzBreite-1;
				return feld[xx][y];
			}
			case 4 :
			{
				int yy = y-1;
				if(yy< 0) yy = anzHoehe-1;
				return feld[x][yy];
			}
		}
		return null;
	}
	int getAnzBreite()
	{
		return anzBreite;
	}
	int getAnzHoehe()
	{
		return anzHoehe;
	}
	public void update (Graphics screen)
	{
		paint (screen);
	}
}
class Feld extends JPanel
{
	private static int pix;
	private int x, y;
	private boolean besetzt;
	public Feld(int x, int y)
	{
		this.x		= x;
		this.y		= y;
	}
	public static void setParameter(int pixel)
	{
		pix	= pixel;
	}
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		g.setColor(new Color(100, 250, 100));
		g.fillRect(10+x*pix, 10+y*pix, pix, pix);
		if(besetzt)
		{
			g.setColor(Color.black);
			g.fillOval(10+x*pix, 10+y*pix, pix, pix);
		}
	}
	public boolean getBesetzt()
	{
		return besetzt;
	}
	public void setBesetzt (boolean besetzt)
	{
		this.besetzt = besetzt;
	}
}