#version 330 core

// fragment shader supporting lighting

smooth in vec2 UV;
smooth in vec3 vNormal;
smooth in vec4 aPos;

smooth in mat3 NormalMatrix; // identity in this app

out vec4 color;




////// 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.03; //0.03 //ambientCoeff
uniform float fracMdif = 1.0; //0.1; //diffuseCoeff
uniform float fracMspc = 0.1; //0.01; // reflectivity
uniform float Shininess = 32.0; //64.0;

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


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





uniform sampler2D myTextureSampler;


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

uniform int isel=0; // 0=>none, 3=>both, 1=>only 1, 2=>only 2
uniform float prad;

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 /////////////////////////





//const float onepi = 3.14159;
const float onepi = 3.141592654;
const float twopi=2.0*onepi;



//////// insert 20dec17 begin /////////////////////////////////////

uniform int fogcolr=1; 
//  0=>noFog, 1=>white, 2=>brownish, 3=>purple, 4=>gray

uniform int foglevl=0; // 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 vSootColor=vec4(25.0/255,15.0/255,5.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;

const float elip=0.90; //ratio

bool insideEllipse( vec3 cc, vec3 pt )
{
	float dist2 = 
		(cc.x-pt.x)*(cc.x-pt.x)/elip/elip +
		(cc.y-pt.y)*(cc.y-pt.y) +
		(cc.z-pt.z)*(cc.z-pt.z)/elip/elip;
	if( dist2<prad*prad ) return true;
	else return false;
}


void main(){  // see adagate.adb::pgmtexshadid

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

	color = texture( myTextureSampler, UV).rgba;

	if(color.a < 0.01) discard;

	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);

	}

	if(color.a < 0.05) discard;



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


	if(foglevl>0) {
		if( fogcolr==4 )
			color = mix(color,  vDfogColor, getFogFactor(fFogCoord)); //gray
		else if( fogcolr==3 )
			color = mix(color, vMystColor, getFogFactor(fFogCoord)); //purple
		else if( fogcolr==2 )
			color = mix(color, vSootColor, getFogFactor(fFogCoord)); //brown
		else if( fogcolr==1 )
			color = mix(color,  vFogColor, getFogFactor(fFogCoord)); //white
	}



	if( (isel>0) && (prad>0.1) ){
		if(

			 ( ( isel==3 ) && ( ( insideEllipse(port1,aPos.xyz) ) 
			 						|| ( insideEllipse(port2,aPos.xyz) ) ) )
			 ||

			 ( ( isel==2 ) && ( insideEllipse(port2,aPos.xyz) ) )
			 ||

			 ( ( isel==1 ) && ( insideEllipse(port1,aPos.xyz) ) )

		 ) color.a=0.0;
	}



	// fastrgv:  my halfspace-discard addendum:
	vec3 cP1 =  port1 - eyePos;
	vec3 cP2 =  port2 - eyePos;
	vec3 vP0 = aPos.xyz - eyePos;
	float PRAD = 1.3; //0.85; related to maximum "prad"
	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/>.
//--

