uniform float ptimer;

const float origin_z = 0.0;
const float plane_z = 16.0;
const float far_z = 256.0;

const float near_dist = 0.025;

const float scale = 16.0;

const int num_sphere = 4;
vec4 sphere[num_sphere];

float time;
int shit;

float dist_from_sphere(vec3 pos, vec4 sphere)
{
	float d = sqrt((sphere.x - pos.x) * (sphere.x - pos.x) + (sphere.y - pos.y) * (sphere.y - pos.y) + (sphere.z - pos.z) * (sphere.z - pos.z)) - sphere.w;
	return d;
}

float dist_from_all(vec3 pos)
{
	float d[num_sphere];

	for (int i=0; i<num_sphere; i++)
	{
		d[i] = dist_from_sphere(pos, sphere[i]);
	}

	float fuck = min(d[0], min(d[1], min(d[2], d[3])));

	if (fuck== d[0]) shit = 0;
	if (fuck== d[1]) shit = 1;
	if (fuck== d[2]) shit = 2;
	if (fuck== d[3]) shit = 3;

	return fuck;
}

void calc_sphere_pos()
{
	for (int i=0; i<num_sphere; i++)
	{
		sphere[i].x = sin((time + 512.0 * float(i*i*i*i)) * 0.2) * 16.0; 
		sphere[i].y = sin((2.0*time + 32.0 * float(i*i)) * 0.3) * 12.0;
		sphere[i].z = sin((1.5*time + 48.0 * float(i*i*i)) * 0.25) * 32.0 + 64.0;
		sphere[i].w = 2.0 * float(num_sphere) - float(i);
	}
}

void main()
{
	time = ptimer * 0.001;
	calc_sphere_pos();

	float xt = (gl_TexCoord[0].x - 0.5) * scale;
	float yt = (gl_TexCoord[0].y - 0.5) * scale;

	vec3 pos = vec3(xt, yt, plane_z);
	vec3 origin = vec3(0.0, 0.0, origin_z);
	vec3 step = normalize(pos - origin);

	vec3 dir = origin;


	float r;

	do
	{
		if (dir.y < -4.0)
		{
			shit = 4;
			break;
		}

		r = dist_from_all(dir);

		if (r < near_dist)
			break;

		dir = dir + step * r;

	}while(dir.z < far_z);

	vec4 sphere_hit;

	if (shit < 4)
	{
		if (shit==0)
			sphere_hit = sphere[0];
		if (shit==1)
			sphere_hit = sphere[1];
		if (shit==2)
			sphere_hit = sphere[2];
		if (shit==3)
			sphere_hit = sphere[3];

		vec3 normal = normalize(vec3(sphere_hit.x - dir.x, sphere_hit.y - dir.y, sphere_hit.z - dir.z));
		if (normal.z < 0.0) normal.z = 0.0;
		float cc = pow(normal.z, 2.0);

		gl_FragColor = vec4(cc, cc, cc, 1.0) * 0.75 + vec4(1.0, 0.0, 0.0, 0.0) * 0.25;
	}
	else
	{
		vec3 normal = vec3(0.0, -1.0, 0.0);
		vec3 light = normalize(dir);
		float cp = normal.x * light.x + normal.y * light.y + normal.z * light.z;
		gl_FragColor = vec4(0.0, 0.0, cp, 1.0);
	}
}
