const vertex_shader_source = `
	attribute vec4 aPos;
	attribute vec3 aNormal;

	uniform mat4 uModView;
	uniform mat4 uProj;
	uniform mat4 uNormalMat;

	varying highp vec3 vLighting;
/*
	vec3 lightColor = vec3(1.0, 0.8, 0.8);
	vec3 lightDir = normalize(vec3(-0.2, -1.0, -0.3));

	vec3 viewPos = vec3(0.0, 0.0, 0.0);

	vec3 calculateLighting()
	{
		vec3 norm = normalize(aNormal);
		// ambient
		vec3 ambient = 0.3 * lightColor;
		// diffuse
		float diff = max(dot(lightDir, norm), 0.0);
		vec3 diffuse = diff * lightColor;
		// specular
		vec3 viewDir = normalize(viewPos - vec3(aPos.xyz));
		vec3 reflectDir = reflect(-lightDir, norm);
		vec3 halfwayDir = normalize(lightDir + viewDir);  
		float spec = pow(max(dot(norm, halfwayDir), 0.0), 32.0);
		vec3 specular = vec3(0.3) * spec; // assuming bright white light color  

		return (ambient + diffuse + specular);
	}
*/
	void main()
	{
		gl_Position = uProj * uModView * aPos;

		highp vec3 ambientLight = vec3(0.3, 0.3, 0.3);
		highp vec3 directionalLightColor = vec3(1, 1, 1);
		highp vec3 directionalVector = normalize(vec3(1, 15, -1.75));

		highp vec4 transformedNormal = uNormalMat * vec4(aNormal, 1.0);

		highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);
		vLighting = ambientLight + (directionalLightColor * directional);

//		vLighting = calculateLighting();
	}
`;

const fragment_shader_source = `
	varying highp vec3 vLighting;

	void main()
	{
		highp vec3 color = vec3(1.0, 1.0, 1.0);
		gl_FragColor = vec4(color * vLighting, 1.0);
	}
`;

function initShaderProgram(gl)
{
	const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertex_shader_source);
	const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragment_shader_source);

	const shaderProgram = gl.createProgram();
	gl.attachShader(shaderProgram, vertexShader);
	gl.attachShader(shaderProgram, fragmentShader);
	gl.linkProgram(shaderProgram);

	if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
	{
		alert(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
		return null;
	}
	return shaderProgram;
}

function loadShader(gl, type, source)
{
	const shader = gl.createShader(type);

	gl.shaderSource(shader, source);
	gl.compileShader(shader);

	if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
	{
		alert(`An error occurred while compiling the shaders: ${gl.getShaderInfoLog(shader)}`);
		gl.deleteShader(shader);
		return null;
	}

	return shader;
}

export { initShaderProgram };
