package Life;

import java.awt.*;
import java.awt.image.*;
/**
 * This type was created by Jens Elbæk
 */
public class EcologicalSystem extends Panel implements Runnable
{
	private int pi = 0;
	Cell[][] cells;
	int[] pixels;
	final static int pointsize = 4;
	protected int bredde, højde;
	int xMax, yMax;
	MemoryImageSource imgsrc;
	Image memimg;
	int lifecount = 0;
	int background, foreground;
	private int minX, minY, maxX, maxY;
	private ArtificialLife ai;

	public Thread thisthread;

/**
 * EcologicalSystem constructor comment.
 */
public EcologicalSystem(ArtificialLife parmai) 
{
	super();
	ai = parmai;
	bredde = ai.getwidth()/pointsize;
	højde = (ai.getheight()-100)/pointsize;
	setSize(bredde*pointsize, højde*pointsize);
	pixels = new int[bredde*pointsize * højde*pointsize];
	background = (255 << 24) | (255 << 16) | (255 << 8) | 255;
	foreground = (255 << 24) | (0 << 16) | (0 << 8) | 0;
	for (int i = 0; i < pixels.length; i++)
	{
		pixels[i] = background;
	}
	imgsrc = new MemoryImageSource(bredde*pointsize,
									højde*pointsize,
									pixels,
									0,
									bredde*pointsize);
	imgsrc.setAnimated(true);
	memimg = createImage(imgsrc);


	xMax = bredde-1;
	yMax = højde-1;
	cells = new Cell[bredde][højde];
	for (int x1 = 0; x1 < bredde; x1++)
	{
		for (int y1 = 0; y1 < højde; y1++)
		{
			cells[x1][y1] = new Cell(this, new CellLocation(x1,y1));
		}
	
	}

}
/**
 * Insert the method's description here.
 * Creation date: (08-04-01 23:41:53)
 */
public void changestate() 
{
	for (int y=0; y < højde-1; y++)
	{
		for (int x=0; x < bredde-1; x++)
		{
			cells[x][y].alive = cells[x][y].nextstate;
		}
	}
}
/**
 * Insert the method's description here.
 * Creation date: (08-04-01 23:41:53)
 */
public void changestate(int x, int y) 
{
	cells[x][y].alive = cells[x][y].nextstate;
}
/**
 * Insert the method's description here.
 * Creation date: (14-04-01 17:06:40)
 * @param pixels int[]
 */
public void drawcells(int[] pixels) 
{
	for (int y=0; y<højde-1; y++)
	{
		for (int x=0; x<bredde-1; x++)
		{
			cells[x][y].draw(pixels);
		}
	}
}
/**
 * Insert the method's description here.
 * Creation date: (29-04-01 21:18:21)
 * @param cells Life.Cell[][]
 */
public void killAll(Cell[][] cells)
{
	for (int x1 = 0; x1 < bredde; x1++)
	{
		for (int y1 = 0; y1 < højde; y1++)
		{
			cells[x1][y1].kill();
		}
	}
 	changestate();
}
/**
 *
 * Creation date: (08-04-01 21:50:52)
 */
public synchronized void lifecicle()
{
	lifecount++;
	minX = bredde;
	minY = højde;
	maxX = 0;
	maxY = 0;

	for (int y=0; y < højde-1; y++)
	{
		for (int x=0; x < bredde-1; x++)
		{
			cells[x][y].nextstate = cells[x][y].alive;
			int n = cells[x][y].neighboursAlive();
			if (n == 3)
			{
				if (cells[x][y].setAlive())
					saveXY(x, y);
				continue;
			}
			if (n == 2)
			{
				if (cells[x][y].alive)
					continue;
			}
			if (cells[x][y].kill())
				saveXY(x, y);
			continue;
		}		
	}

	changestate();

	drawcells(pixels);

	int x = minX*pointsize;
	int y = minY*pointsize;
	int w = (maxX-minX+1)*pointsize;
	int h = (maxY-minY+1)*pointsize;
//	System.out.println("newPixels(" + x + "," + y + "," + w + "," + h + ")");
	imgsrc.newPixels(0, 0, bredde*pointsize, højde*pointsize);
//	imgsrc.newPixels(x,y,w,h);
//	repaint();

}
/**
 * Insert the method's description here.
 * Creation date: (08-04-01 16:38:08)
 * @param g java.awt.Graphics
 */
public void paint(Graphics g) 
{
	if (imgsrc != null)
	{
		g.drawImage( memimg, 0, 0, this );
	}

}
/**
 * 
 * Creation date: (14-04-01 16:12:01)
 */
public void run() 
{
	long milliseconds = 500;
	repaint();
	for(;;)
	{
//		System.out.println("lifecycle number " + lifecount);
		lifecicle();
//		repaint();
		try
		{
			thisthread.sleep(milliseconds);
		}
		catch(InterruptedException e)
		{
			return;
		}

	}

}
/**
 * Insert the method's description here.
 * Creation date: (09-04-01 10:35:23)
 * @param x int
 * @param y int
 */
public void saveXY(int x, int y) 
{
	if (x < minX)
		minX=x;
	if (y < minY)
		minY=y;
	if (x > maxX)
		maxX=x;
	if (y > maxY)
		maxY=y;
}
/**
 * Insert the method's description here.
 * Creation date: (19-04-01 00:01:36)
 */
public void startGlider() 
{
	killAll(cells);
	
	cells[2][1].setAlive();
	cells[3][2].setAlive();
	cells[1][3].setAlive();
	cells[2][3].setAlive();
	cells[3][3].setAlive();

//	eath.cells[2][2].setAlive();
//	eath.cells[2][3].setAlive();
//	eath.cells[2][4].setAlive();

	cells[25][5].setAlive();
	cells[25][6].setAlive();
	cells[25][7].setAlive();

	cells[17][17].setAlive();
	cells[17][18].setAlive();
	cells[18][17].setAlive();
	cells[18][18].setAlive();
	changestate();
//	saveXY(0,0);
//	saveXY(bredde,højde);
	drawcells(pixels);
	repaint();
}
/**
 * Insert the method's description here.
 * Creation date: (19-04-01 00:02:20)
 */
public void startGliderkanon() 
{
	killAll(cells);
	
 	cells[4][15].setAlive();
	cells[4][16].setAlive();
 	
 	cells[5][15].setAlive();
	cells[5][16].setAlive();

 	
 	cells[10][14].setAlive();
	cells[10][15].setAlive();

 	
	cells[14][12].setAlive();
	cells[14][13].setAlive();
	cells[14][17].setAlive();
	cells[14][18].setAlive();

	cells[15][13].setAlive();
	cells[15][14].setAlive();
	cells[15][15].setAlive();
	cells[15][16].setAlive();
	cells[15][17].setAlive();

	cells[16][13].setAlive();
	cells[16][14].setAlive();
	cells[16][16].setAlive();
	cells[16][17].setAlive();
	
	cells[17][13].setAlive();
	cells[17][14].setAlive();
	cells[17][16].setAlive();
	cells[17][17].setAlive();
	
	cells[18][14].setAlive();
	cells[18][15].setAlive();
	cells[18][16].setAlive();

	cells[25][19].setAlive();
	
	cells[26][13].setAlive();
	cells[26][17].setAlive();
	cells[26][19].setAlive();
	
	cells[27][12].setAlive();
	cells[27][13].setAlive();
	cells[27][14].setAlive();
	cells[27][18].setAlive();
	cells[27][19].setAlive();

	cells[28][11].setAlive();
	cells[28][12].setAlive();
	cells[28][13].setAlive();
	cells[28][14].setAlive();
	cells[28][15].setAlive();

	cells[29][10].setAlive();
	cells[29][12].setAlive();
	cells[29][14].setAlive();
	cells[29][16].setAlive();
	
	cells[30][10].setAlive();
	cells[30][11].setAlive();
	cells[30][15].setAlive();
	cells[30][16].setAlive();


	cells[33][13].setAlive();

	cells[34][12].setAlive();
	cells[34][14].setAlive();

	cells[35][12].setAlive();
	cells[35][14].setAlive();

	cells[36][13].setAlive();

	cells[37][13].setAlive();
	cells[37][14].setAlive();

	cells[38][13].setAlive();
	cells[38][14].setAlive();

	cells[39][13].setAlive();
	cells[39][14].setAlive();

	
	changestate();
//	saveXY(0,0);
//	saveXY(bredde,højde);
	drawcells(pixels);
	repaint();
}
/**
 * Insert the method's description here.
 * Creation date: (19-04-01 00:03:06)
 */
public void startParadis() 
{
	killAll(cells);

 	cells[12][13].setAlive();
 	cells[12][14].setAlive();
 	cells[12][15].setAlive();
 	cells[12][16].setAlive();
 	cells[12][18].setAlive();
 	cells[12][20].setAlive();
 	cells[12][21].setAlive();

  	cells[13][13].setAlive();
 	cells[13][15].setAlive();
 	cells[13][17].setAlive();
 	cells[13][18].setAlive();
 	cells[13][19].setAlive();
 	cells[13][21].setAlive();

  	cells[14][13].setAlive();
  	cells[14][14].setAlive();
  	cells[14][15].setAlive();
  	cells[14][16].setAlive();
   	cells[14][18].setAlive();
  	cells[14][20].setAlive();
  	cells[14][21].setAlive();

  	cells[15][13].setAlive();
 	cells[15][15].setAlive();
 	cells[15][17].setAlive();
 	cells[15][18].setAlive();
 	cells[15][19].setAlive();
 	cells[15][21].setAlive();

  	cells[16][13].setAlive();
  	cells[16][14].setAlive();
  	cells[16][15].setAlive();
  	cells[16][16].setAlive();
   	cells[16][18].setAlive();
  	cells[16][20].setAlive();
  	cells[16][21].setAlive();

  	cells[17][13].setAlive();
 	cells[17][15].setAlive();
 	cells[17][17].setAlive();
 	cells[17][18].setAlive();
 	cells[17][19].setAlive();
 	cells[17][21].setAlive();

  	cells[18][13].setAlive();
  	cells[18][14].setAlive();
  	cells[18][15].setAlive();
  	cells[18][16].setAlive();
   	cells[18][18].setAlive();
  	cells[18][20].setAlive();
  	cells[18][21].setAlive();

  	cells[19][13].setAlive();
 	cells[19][15].setAlive();
 	cells[19][17].setAlive();
 	cells[19][18].setAlive();
 	cells[19][19].setAlive();
 	cells[19][21].setAlive();

  	cells[20][13].setAlive();
  	cells[20][14].setAlive();
  	cells[20][15].setAlive();
  	cells[20][16].setAlive();
   	cells[20][18].setAlive();
  	cells[20][20].setAlive();
  	cells[20][21].setAlive();

  	cells[21][13].setAlive();
 	cells[21][15].setAlive();
 	cells[21][17].setAlive();
 	cells[21][18].setAlive();
 	cells[21][19].setAlive();
 	cells[21][21].setAlive();

  	cells[22][13].setAlive();
  	cells[22][14].setAlive();
  	cells[22][15].setAlive();
  	cells[22][16].setAlive();
   	cells[22][18].setAlive();
  	cells[22][20].setAlive();
  	cells[22][21].setAlive();

  	cells[23][13].setAlive();
 	cells[23][15].setAlive();
 	cells[23][17].setAlive();
 	cells[23][18].setAlive();
 	cells[23][19].setAlive();
 	cells[23][21].setAlive();

  	cells[24][13].setAlive();
  	cells[24][14].setAlive();
  	cells[24][15].setAlive();
  	cells[24][16].setAlive();
   	cells[24][18].setAlive();
  	cells[24][20].setAlive();
  	cells[24][21].setAlive();

  	cells[25][13].setAlive();
  	cells[25][14].setAlive();
  	cells[25][16].setAlive();
  	cells[25][17].setAlive();
   	cells[25][18].setAlive();
  	cells[25][19].setAlive();
  	cells[25][21].setAlive();

	cells[26][14].setAlive();
	cells[26][15].setAlive();
	cells[26][17].setAlive();
	cells[26][19].setAlive();
	cells[26][19].setAlive();
	cells[26][20].setAlive();
	cells[26][21].setAlive();

	cells[27][13].setAlive();
	cells[27][14].setAlive();
	cells[27][16].setAlive();
	cells[27][17].setAlive();
	cells[27][18].setAlive();
	cells[27][19].setAlive();
	cells[27][21].setAlive();

	cells[28][13].setAlive();
	cells[28][15].setAlive();
	cells[28][16].setAlive();
	cells[28][18].setAlive();
	cells[28][20].setAlive();
	cells[28][21].setAlive();

	cells[29][13].setAlive();
	cells[29][14].setAlive();
	cells[29][16].setAlive();
	cells[29][17].setAlive();
	cells[29][18].setAlive();
	cells[29][19].setAlive();
	cells[29][21].setAlive();

	cells[30][13].setAlive();
	cells[30][14].setAlive();
	cells[30][15].setAlive();
	cells[30][16].setAlive();
	cells[30][18].setAlive();
	cells[30][19].setAlive();
	cells[30][20].setAlive();
	cells[30][21].setAlive();

	cells[31][13].setAlive();
	cells[31][15].setAlive();
	cells[31][16].setAlive();
	cells[31][17].setAlive();
	cells[31][19].setAlive();
	cells[31][20].setAlive();
	cells[31][21].setAlive();

	cells[32][13].setAlive();
	cells[32][14].setAlive();
	cells[32][15].setAlive();
	cells[32][17].setAlive();
	cells[32][18].setAlive();
	cells[32][19].setAlive();
	cells[32][21].setAlive();

	cells[33][13].setAlive();
	cells[33][14].setAlive();
	cells[33][16].setAlive();
	cells[33][17].setAlive();
	cells[33][18].setAlive();
	cells[33][20].setAlive();
	cells[33][21].setAlive();

	cells[34][13].setAlive();
	cells[34][14].setAlive();
	cells[34][15].setAlive();
	cells[34][16].setAlive();
	cells[34][18].setAlive();
	cells[34][19].setAlive();
	cells[34][20].setAlive();
	cells[34][21].setAlive();

	cells[35][13].setAlive();
	cells[35][15].setAlive();
	cells[35][16].setAlive();
	cells[35][17].setAlive();
	cells[35][19].setAlive();
	cells[35][20].setAlive();
	cells[35][21].setAlive();

	cells[36][13].setAlive();
	cells[36][14].setAlive();
	cells[36][15].setAlive();
	cells[36][17].setAlive();
	cells[36][18].setAlive();
	cells[36][19].setAlive();
	cells[36][21].setAlive();

	cells[37][13].setAlive();
	cells[37][14].setAlive();
	cells[37][16].setAlive();
	cells[37][17].setAlive();
	cells[37][18].setAlive();
	cells[37][20].setAlive();
	cells[37][21].setAlive();

	cells[38][13].setAlive();
	cells[38][14].setAlive();
	cells[38][15].setAlive();
	cells[38][16].setAlive();
	cells[38][18].setAlive();
	cells[38][19].setAlive();
	cells[38][20].setAlive();
	cells[38][21].setAlive();

	cells[39][13].setAlive();
	cells[39][15].setAlive();
	cells[39][16].setAlive();
	cells[39][17].setAlive();
	cells[39][19].setAlive();
	cells[39][20].setAlive();
	cells[39][21].setAlive();

	cells[40][13].setAlive();
	cells[40][14].setAlive();
	cells[40][15].setAlive();
	cells[40][17].setAlive();
	cells[40][18].setAlive();
	cells[40][19].setAlive();
	cells[40][21].setAlive();

	cells[41][13].setAlive();
	cells[41][14].setAlive();
	cells[41][16].setAlive();
	cells[41][18].setAlive();
	cells[41][20].setAlive();
	cells[41][21].setAlive();

	cells[42][13].setAlive();
	cells[42][15].setAlive();
	cells[42][16].setAlive();
	cells[42][17].setAlive();
	cells[42][18].setAlive();
	cells[42][19].setAlive();
	cells[42][21].setAlive();

	cells[43][13].setAlive();
	cells[43][14].setAlive();
	cells[43][15].setAlive();
	cells[43][16].setAlive();
	cells[43][18].setAlive();
	cells[43][20].setAlive();
	cells[43][21].setAlive();

	cells[44][13].setAlive();
	cells[44][14].setAlive();
	cells[44][16].setAlive();
	cells[44][17].setAlive();
	cells[44][18].setAlive();
	cells[44][19].setAlive();
	cells[44][20].setAlive();
	cells[44][21].setAlive();

	changestate();
	drawcells(pixels);
	repaint();
}
/**
 * Returns a String that represents the value of this object.
 * @return a string representation of the receiver
 */
public String toString() {
	// Insert code to print the receiver here.
	// This implementation forwards the message to super. You may replace or supplement this.
	return super.toString();
}
}

