//Fragment Shader

// Note how the fragment struct was simply copied from our vertex shader code.
// This is necessary if we want to use a vertex and pixel shader together.

struct fragment
{
    float4 color0	:	COLOR0;
    float2 texcoord0	:	TEXCOORD0;
    float3 normal	:	TEXCOORD1;
    float4 objectPos	:	TEXCOORD2;
    float2 texcoord3	:	TEXCOORD3;
	float4 objectPos2	:	TEXCOORD4;
	float3 Light2color	:	TEXCOORD5;
};

struct pixel
{
    float4 color : COLOR;
};

pixel main( 
    fragment IN, 
    uniform float3	globalAmbient,
    uniform float3	paraLightColor,
    uniform float3	paraLightDirection,
    uniform float3	eyePosition,
	uniform float4x4 Worldmatrix,
//    uniform float3	Ke,
//    uniform float3	Ka,
//    uniform float3	Kd,
//    uniform float3	Ks,

//	uniform float	testnum,
//    uniform float	shininess,
    uniform sampler2D	testTexture,
    uniform sampler2D	ShadowMapTexture,
	uniform samplerCUBE	AmbientReflectiveTexture,
	uniform sampler2D	NormalMapTexture,
	uniform sampler2D	SpecularMapTexture
)
{
	float4 MainColor=tex2D( testTexture, IN.texcoord0 );
	float3 T = normalize(IN.color0.xyz);
	float3 Nm = normalize(IN.normal);
	float3 B = normalize(cross (T,Nm));
	float3x3 TBN;
	TBN[0]=T;
	TBN[1]=B;
	TBN[2]=Nm;
	float3 NN = tex2D( NormalMapTexture, IN.texcoord0 ).xyz;
	float3 NN2;
	NN2.x=(NN.x-0.5)*2.0;
	NN2.y=(NN.y-0.5)*2.0;
	NN2.z=(NN.z-0.5)*2.0;
    float3 N = mul(NN2,TBN);

    float3 L = normalize(paraLightDirection);
	float DotNaL=dot(N, L);
    float diffuseLight = max(DotNaL, 0.0);
    float3 diffuse = paraLightColor * diffuseLight;

    float3 V = normalize(eyePosition);
    float3 H = normalize(L + V);
	float DotNaH=dot(N, H);
	float MaxNaH0=max(DotNaH,0.0);
    float specularLight = pow(MaxNaH0, 50.0);
	float4 SpecularMapcolor;
	SpecularMapcolor=tex2D( SpecularMapTexture, IN.texcoord0 );

    if(diffuseLight<=0.0) specularLight=0.0;
    float4 Ocolor;
	//Ocolor.xyz = globalAmbient + diffuse+specularLight*8*SpecularMapcolor.xyz;
    Ocolor.w = 1.0;
    pixel OUT;
	IN.objectPos2.z=IN.objectPos2.z-0.4;
	float colorposZ;
	float v=0.15;
	float4 MX=float4 (v,0.0,0.0,0.0);
	float4 MU=float4 (0.0,v,0.0,0.0);
	colorposZ=0.0;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX+MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX+MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX-MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX-MU ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX*2.0+MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX*2.0+MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX*2.0-MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX*2.0-MU*2.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MX*3.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MX*3.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2+MU*3.0 ).r;
	colorposZ=colorposZ+tex2Dproj( ShadowMapTexture, IN.objectPos2-MU*3.0 ).r;
	float4 R2;
	R2.xyz= reflect((eyePosition-IN.objectPos.xyz/IN.objectPos.w), N);
	R2.w=0.0;
	R2=mul(Worldmatrix,R2);
	Ocolor.xyz=globalAmbient +IN.Light2color+(diffuse+specularLight*10.0*SpecularMapcolor.x)*colorposZ/21.0;




	OUT.color = MainColor*Ocolor*(texCUBE( AmbientReflectiveTexture, R2.xyz)+1.0);
	OUT.color.w=0.5;

    return OUT;
}
