#version 130 

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

uniform vec3 playerPos;
uniform vec3 sunPosition;
uniform float elapsedTime;

in vec3 vPosition;
in vec3 vNormal;
in vec3 vTangent;

out vec3 fWorldPos;
out vec3 fNormal;
out float fIntensity;

float lowFreqFunc(vec3 pos)
{
	float loF = cos(pos.x/5) + abs(sin(pos.y/5)+0.5) + cos(pos.z/5);
	float param1 = elapsedTime/1.5*1.334721 + loF;
	return cos(2.471214*param1);
}

float hiFreqFunc(vec3 pos)
{
	float hiF = cos(pos.x) + abs(sin(pos.y)+0.5) + cos(pos.z);
	float param2 = elapsedTime/1.5 + hiF;
	return sin(param2);
}

vec3 calcVertexLoc(vec3 pos, float factor)
{
	return vPosition + vNormal * factor * (0.4*hiFreqFunc(pos) + lowFreqFunc(pos));
}

vec3 calcNormal(vec3 origPos, vec3 newPos)
{
	vec3 vBitangent = cross(vNormal, vTangent);
	vec3 locTP, locTN, locBP, locBN;	// locations - tangent/bitanget positive/negative
	float scale = 0.15;
	locTP = origPos + vTangent * scale;
	locTN = origPos - vTangent * scale;
	locBP = origPos + vBitangent * scale;
	locBN = origPos - vBitangent * scale;
	float valTP, valTN, valBP, valBN;
	valTP = length(calcVertexLoc(locTP, 0.05)) - length(newPos);
	valTN = length(calcVertexLoc(locTN, 0.05)) - length(newPos);
	valBP = length(calcVertexLoc(locBP, 0.05)) - length(newPos);
	valBN = length(calcVertexLoc(locBN, 0.05)) - length(newPos);

	float tanOffset = valTN - valTP;
	float bitOffset = valBN - valBP;
	return vNormal + tanOffset*vTangent/scale + bitOffset*vBitangent/scale;
}

void main()
{	
	vec3 vVertex = vec3(modelViewMatrix * vec4(vPosition, 1));
	
	vec3 pos = calcVertexLoc(vPosition, 0.05);
			
	fWorldPos = pos;
	fNormal = calcNormal(vPosition, pos);

	vec3 corePosition = vec3(0.0f, 0.0f, 0.0f);  // change to uniform
	vec3 upFromCore = normalize(fWorldPos - corePosition);
	vec3 positionToSun = normalize(sunPosition - fWorldPos);
	float seeSun = dot(positionToSun, upFromCore);
	float C = 0.2;	 
	seeSun = clamp(seeSun, 0, C);
	fIntensity = 1.0f;
	fIntensity = max(0.1, seeSun / C);
	
	mat4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix;
	gl_Position = modelViewProjectionMatrix * vec4(fWorldPos, 1);
}
