#version 330 core
// fragment shader

smooth in vec2 UV;
smooth in vec3 vNormal;
smooth in vec4 aPos;
smooth in mat3 NormalMatrix; // identity in this app


out vec4 color;

uniform sampler2D myTextureSampler; // #1



////// begin lighting uniforms ///////////


uniform int lightFlag = 0; // 0=>no, 1=>yes


uniform vec3 ambCol = vec3(1.0,1.0,1.0);
uniform float fracAmb  = 0.2; //0.1 //ambientCoeff
uniform float fracMdif = 1.0; //0.1; //diffuseCoeff
uniform float fracMspc = 0.01; //0.01; // reflectivity
uniform float Shininess = 64.0; //128.0;

uniform vec3 vPtColor; // 254:203:33
uniform vec3 vPos1;
uniform vec3 vPos2;
uniform vec3 vPos3;
const float fPtQuadAtt = 0.5; //0.04
////// end point-light //////////////////


////// end lighting uniforms ///////////




// halfspace discard uniforms: ////////////////////////////////////

uniform int iside=0; // 0=>noDiscard

uniform vec3 eyePos;

uniform vec3  port1;
uniform vec3  port2;

// halfspace discard uniforms end /////////////////////////////////






//////// begin lighting ftns /////////////////////////

vec4 getAmbientLight( vec4 texCol ) // ambient
{
	vec4 ambient = fracAmb*vec4(ambCol,1.0)*texCol;
	return ambient;
}


vec4 getBlinnPhong( vec4 texCol, vec3 litePos ) // specular + diffuse
{
	vec3 liteCol=vPtColor;
	vec3 vPosToLight = litePos-aPos.xyz;
	float liteDist = length(vPosToLight);
	float attenuation = 1.0 / (1.0 + fPtQuadAtt*liteDist*liteDist);

// all vectors below here are in the Transformed Space
// i.e. AFTER applying NormalMatrix.

	vec3 surfaceToLight = normalize(NormalMatrix*vPosToLight);
	vec3 surfaceToCamera = normalize(eyePos - NormalMatrix*aPos.xyz);
	vec3 surfaceNormal = normalize(NormalMatrix*vNormal);

	float cosLitAngl = max(0.0, dot(surfaceNormal, surfaceToLight) );

	vec3 fDiffuse = vec3(0.0,0.0,0.0);
	vec3 fSpecular = vec3(0.0,0.0,0.0);

	if( cosLitAngl > 0.0 ) {

		vec3 halfDir = normalize(surfaceToLight + surfaceToCamera);
		float specAngl = max(dot(halfDir, surfaceNormal), 0.0);
		fSpecular = liteCol*fracMspc*pow(specAngl, Shininess);

		fDiffuse= liteCol*fracMdif*texCol.rgb*cosLitAngl;

	}

	vec3 linearColor = attenuation*(fDiffuse+fSpecular);
	return vec4( linearColor, texCol.a); //no gamma-correction

}

vec4 fixGamma( vec4 linearColor ) 
{

	// do gamma correction:
	vec3 gamma = vec3(1.0/2.2);
	vec3 finalColor = pow(linearColor.rgb,gamma);
	return vec4( finalColor, linearColor.a );

}

//////// end lighting ftns /////////////////////////





// fog addendum begin ////////////////////////////



//////// insert 20dec17 begin /////////////////////////////////////
uniform int fogcolr=2; //  0=>noFog, 1=>white, 2=>brownish, 3=>purple, 4=>gray
uniform int foglevl=2; // 0=>noFog, 1=>Fog, 2=>heavy

const vec4 vFogColor=vec4(0.9,0.9,0.9,1.0); //normal
const vec4 vDfogColor=vec4(0.3,0.3,0.3,1.0); //gray
const vec4 vSootColor=vec4(50.0/255,30.0/255,10.0/255,1.0); // brown
const vec4 vMystColor=vec4(0.7,0.5,0.7,1.0); // purple
//////// insert 20dec17 end /////////////////////////////////////



const float fStart=0.0;
const float fEnd=30.0; // normal fog
const float sEnd=20.0; // use this for soot (lava room)

float getFogFactor(float fFogCoord)
{
	float fResult = 0.0;

	if(foglevl==2)
		fResult = (sEnd-fFogCoord)/(sEnd-fStart);
	else
		fResult = (fEnd-fFogCoord)/(fEnd-fStart);

	fResult = 1.0-clamp(fResult, 0.0, 1.0);
	
	return sqrt(fResult);
}

const float yc=-2.85;

// fog addendum end /////////////////////////////




void main(){

	color = texture( myTextureSampler, UV).rgba;


	// lighting addendum:
	if( lightFlag > 0 ) { // use light effects

		vec4 vTexColor = color;
		vec4 vLightColor = 
			getAmbientLight(vTexColor) +
			getBlinnPhong(vTexColor,vPos1) +
			getBlinnPhong(vTexColor,vPos2) +
			getBlinnPhong(vTexColor,vPos3);
		
		vLightColor.a = color.a;
		color = clamp(vLightColor, 0.0, 1.0);

	}


	color = fixGamma(color);


	vec4 vEyePos = vec4( aPos.xyz-eyePos, 1.0 );

	if( foglevl>0 ) {

		// fog addendum:
		float dist = length( vEyePos.xz );
		float fFogCoord = exp(-0.4*abs(aPos.y-yc)) * dist/vEyePos.w;

		if( fogcolr==4 )
			color = mix(color, vDfogColor, getFogFactor(fFogCoord));
		else if( fogcolr==3 )
			color = mix(color, vMystColor, getFogFactor(fFogCoord));
		else if( fogcolr==2 )
			color = mix(color, vSootColor, getFogFactor(fFogCoord));
		else
			color = mix(color, vFogColor, getFogFactor(fFogCoord));

	}

	color.a=1.0; //otherwise we might see thru to brick-bottom


	// fastrgv:  my halfspace-discard addendum:
	vec3 cP1 =  port1 - eyePos;
	vec3 cP2 =  port2 - eyePos;
	vec3 vP0 = aPos.xyz - eyePos;
	float PRAD = 0.80; // larger, but synched with adagate.adb
	float FOV1 = atan(PRAD/length(cP1));
	float FOV2 = atan(PRAD/length(cP2));
	vec3 nP1 = normalize(cP1);
	vec3 nP2 = normalize(cP2);
	vec3 nP0 = normalize(vP0);
	float d1=dot(nP0,nP1);
	float d2=dot(nP0,nP2);
	float a1=acos(d1);
	float a2=acos(d2);
	if( iside != 0 ) {
		if( (iside==2) && (a1>FOV1) ) discard;
		if( (iside==1) && (a2>FOV2) ) discard;
	}

}



//--
//-- Copyright (C) 2020  <fastrgv@gmail.com>
//--
//-- This program is free software: you can redistribute it and/or modify
//-- it under the terms of the GNU General Public License as published by
//-- the Free Software Foundation, either version 3 of the License, or
//-- (at your option) any later version.
//--
//-- This program is distributed in the hope that it will be useful,
//-- but WITHOUT ANY WARRANTY; without even the implied warranty of
//-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//-- GNU General Public License for more details.
//--
//-- You may read the full text of the GNU General Public License
//-- at <http://www.gnu.org/licenses/>.
//--

