#version 330 core
precision highp float;

uniform vec3      iResolution;           // viewport resolution (in pixels)
uniform float     iTime;                 // shader playback time (in seconds)
uniform float     iTimeDelta;            // render time (in seconds)
uniform int       iFrame;                // shader playback frame
uniform float     iChannelTime[4];       // channel playback time (in seconds)
uniform vec3      iChannelResolution[4]; // channel resolution (in pixels)
uniform vec4      iMouse;                // mouse pixel coords. xy: current (if MLB down), zw: click
uniform sampler2D iChannel0;             // input channel. XX = 2D/Cube
uniform sampler2D iChannel1;             // input channel. XX = 2D/Cube
uniform sampler2D iChannel2;             // input channel. XX = 2D/Cube
uniform sampler2D iChannel3;             // input channel. XX = 2D/Cube
uniform vec4      iDate;                 // (year, month, day, time in seconds)
uniform float     iSampleRate;           // sound sample rate (i.e., 44100)
uniform float     alpha;                 // alpha value

in vec2 fragCoord;
out vec4 fragColor;

#define PI 3.1415926538

float noise1(float f_x, float f_y)
{
	int x = int(f_x*1000.0);
	int y = int(f_x*1000.0);
	int n;
	n = x+y*57;
	x = (n<<13) ^ n;
	return ( 1.0 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);

}

float metaCalc(vec2 uv, vec3 pos)
{
	return 1.0/((pos.x*pos.x)+(pos.y*pos.y)+(pos.z*pos.z));
}

struct Ray
{
	vec3 origin;
	vec3 dir;
};

Ray generateRayFromPixel(vec2 fragCoord)
{
	// Normalized pixel coordinates (from 0 to 1)
	vec2 uv = fragCoord/iResolution.xy;

	// Time varying pixel color
	vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

	vec3 eyeOrigin = vec3(cos(iTime * 1.41) * 2.0f,sin(iTime),sin(iTime * 1.325) * 0.5f);

	float nearPlaneDist = 0.1f;

	// horizontal FoV
	float FoV = (60.0f / 180.0f) * 3.1415926535f;

	float halfNearPlaneWidth = (sin(FoV / 2.0f));

	float aspect = iResolution.x / iResolution.y;

	vec3 nearPlaneOrigin = eyeOrigin + vec3(-halfNearPlaneWidth, -halfNearPlaneWidth / aspect, nearPlaneDist);

	vec3 rayOrigin = nearPlaneOrigin + vec3(uv.x * halfNearPlaneWidth*2.0f, uv.y * (halfNearPlaneWidth / aspect) * 2.0f, 0.0f);

	vec3 rayDir = normalize(rayOrigin - eyeOrigin);

	Ray ray;
	ray.origin = rayOrigin;
	ray.dir = rayDir;

	return ray;
}

// returns whether a position is below the signal
bool sampleSignal(vec3 position)
{
	float signal = (cos(position.x*0.6) * cos(position.z*0.6) * cos(iTime * 3.5 ))*2.0 - 3.5f;
	return (signal > position.y);
}

void main()
	{
	fragColor = vec4(0,0,1,1.0);

	Ray ray = generateRayFromPixel(fragCoord);

	int numIterations = 400;
	float farDist = 20.0;

	for(int iteration = 0; iteration < numIterations; iteration++)
	{
		float dist = (float(iteration) / float(numIterations)) * farDist;
		vec3 position = ray.origin + (ray.dir * dist);
		if(sampleSignal(position))
		{
			float scaledDist = (dist / farDist);
			scaledDist = scaledDist * scaledDist * scaledDist *scaledDist;
			float n = noise1(position.x*0.3,position.y*1.6);
			fragColor = vec4(n, 1, 1, 1);
			//fragColor = vec4(scaledDist, 0, 0, 1);
			//return;
		}
		else {
			fragColor = vec4(0, 0, 0, 0);
		}
	}

	//METABALL
	// init stuff
	float speed = 2.0;
	vec3 pos = vec3(-0.2+0.1*cos(iTime*speed), -0.2*cos(iTime*speed), 0.5);
	vec3 pos2 = vec3(0.0+-0.1, -0.1+-0.1, 0.0)*sin(iTime*speed);

	float startDropTime = 1.2;
	if (iTime < startDropTime) {
		pos.y += 0.9 * (iTime-startDropTime);
		pos2.y += 0.9 * (iTime-startDropTime);
	}

	float endDropTimeLength = 1.2;
	float endDropTime = 13.2 - endDropTimeLength;
	if (iTime > endDropTime) {
		pos.y += 0.9 * (iTime-endDropTime);
		pos2.y += 0.9 * (iTime-endDropTime);
	}

	// Normalized pixel coordinates (from 0 to 1)
	vec2 uv = fragCoord/iResolution.xy;

	uv -= 0.5; // set center/origo to vec2(0.0,0.0);
	uv.x *= iResolution.x/iResolution.y; // how do you really do aspect ratio?

	vec3 varCol = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

	// metaball
	float amplitude1 = metaCalc(uv, vec3(uv.x - pos.x,uv.y - pos.y,pos.z));
	float amplitude2 = metaCalc(uv, vec3(uv.x - pos2.x,uv.y - pos2.y, pos.z));

	float amplitude = amplitude1+amplitude2;

	if(amplitude > 5.0)
	{
		if(amplitude < 6.5)
		{
			float amplitudeColor = amplitude/10.0;
			float depthColor = amplitudeColor*(pos.z*amplitude1+pos2.z*amplitude2);
			fragColor = vec4(vec3(depthColor,depthColor/3.0,depthColor), 1.0);
		}
	}
	else
	{
		//fragColor = vec4(vec3(0.0), 1.0);
	}

	// Output to screen
	//fragColor = vec4(0,0,1,1.0);
}

