# version 440
layout(binding = 0) buffer dcA { int A [  ]; };
layout(binding = 1) buffer dcB { int B [  ]; };
layout(rgba8, binding = 2) uniform writeonly image2D img;
layout(rgba8, binding = 3) uniform image2D img2;
layout(local_size_x = 10, local_size_y = 10, local_size_z = 1) in;

int per(int x, int nx)
{
	if (x < 0) x += nx;
	if (x >= nx) x -= nx;
	return x;
}

uniform int NX;
uniform int NY;
uniform int c;

void main()
{
	vec4 col2 = imageLoad(img2, ivec2(gl_GlobalInvocationID.xy));       // pixel from image
	int i = int(gl_GlobalInvocationID.x);
	int j = int(gl_GlobalInvocationID.y);
	int idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, suma, ip, jp, im, jm;

	ip = i + 1;// per(i+1,NX);     // periodicity
	im = i - 1;// per(i-1,NX);
	jp = per(j + 1, NY);
	jm = per(j - 1, NY);

	if (ip >= NX || jp >= NY || im < 0 || jm < 0)
		return;
	idx0 = i + NX * j;           // neighbours
	idx1 = ip + NX * (jp);
	idx2 = ip + NX * (j);        // i+1,j
	idx3 = ip + NX * (jm);
	idx4 = i + NX * (jm);        // i,j-1
	idx5 = im + NX * (jm);
	idx6 = im + NX * (j);        // i-1, j
	idx7 = im + NX * (jp);
	idx8 = i + NX * (jp);        // i, j+1

	int sumuj = 1;
	if (j > NY - NY / 4)
		sumuj = 0;
	suma = int(A[idx1] + A[idx2] + A[idx3] + A[idx4] + A[idx5] + A[idx6] + A[idx7] + A[idx8] + sumuj * col2.a * 6 * col2.r);

	//    wikipedia
	//    1 Any live cell with fewer than two live neighbours dies, as if caused by under-population.
	//    2 Any live cell with two or three live neighbours lives on to the next generation.
	//    3 Any live cell with more than three live neighbours dies, as if by overcrowding.
	//    4 Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

	// Game of Life
	B[idx0] = A[idx0];
	if (A[idx0] == 1)
	{
		if (suma < 2) B[idx0] = 0;
		if (suma > 3) B[idx0] = 0;
	}
	else
	{
		if (suma == 3) B[idx0] = 1;
	}

	/*
	suma = A[idx0] + A[idx1] + A[idx2] + A[idx3] + A[idx4] + A[idx5] + A[idx6] + A[idx7] + A[idx8];
	// G. Vichniac [63] from B. Chopard & M. Droz book
	int tab[] = { 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 };
	//int tab[] = { 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 };
	//	int tab[] = { 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 };
	//	int tab[] = { 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 };
	//	int tab[] = { 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 };
	B[idx0] = tab[suma];*/




	float b = B[idx0];
	vec4 col = vec4(b, b, b, 1);

	//
	//img2

	col = mix(col, col2, col2.a);
	//if(col2.a==0)
	//	col= col * suma/8.0;

	/*col.r = col.a * col2.r + (1 - col2.a) * col.r;
	col.g = col.a * col2.g + (1 - col2.a) * col.g;
	col.b = col.a * col2.b + (1 - col2.a) * col.b;*/

	//if (i < 10 || i > NX - 10 || j < 10 || j > NY - 10)
		//col = vec4(0, 0, 0, 1);

	col.a = 1.0;
	imageStore(img, ivec2(gl_GlobalInvocationID.xy), col);
}

