/////////////                                                                                           
// GLOBALS //                                                                                           
/////////////                                                                                           
Texture2D shaderTexture : register( t0 );
SamplerState SampleType;

// The position of the kamera
cbuffer Kamera : register( b0 )
{
    float4 kPosition;
}

// these values should sum up to 1
cbuffer Material : register( b1 )
{
    float ambientFactor;
    float diffusFactor;
    float specularFactor;
};

cbuffer LightCount : register( b2 )
{
    int diffuseLightCount;
    int pointLightCount;
}

// lights
struct DiffuseLight
{
    float3 direction;
    float3 color;
};

struct PointLight
{
    float3 position;
    float3 color;
    float radius;
};

StructuredBuffer< DiffuseLight > difuseLights : register( t1 );
StructuredBuffer< PointLight > pointLights : register( t2 );

//////////////                                                                                          
// TYPEDEFS //                                                                                          
//////////////                                                                                          
struct PixelInputType
{
    float4 worldPos : POSITION;
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : TEXCOORD1;
};

////////////////////////////////////////////////////////////////////////////////                        
// Pixel Shader                                                                                         
////////////////////////////////////////////////////////////////////////////////                        
float4 TexturePixelShader( PixelInputType input ) : SV_TARGET
{
    float3 diffuseLight = float3( 0, 0, 0 );
    float3 specularLight = float3( 0, 0, 0 );
    for( int j = 0; j < diffuseLightCount; j++ )
    {
        if( dot( input.normal, -difuseLights[ j ].direction ) < 0 )
            continue;
        diffuseLight += difuseLights[ j ].color * dot( input.normal, -difuseLights[ j ].direction );
    }
    for( int i = 0; i < pointLightCount; i++ )
    {
        float3 lightDir = pointLights[ i ].position - input.worldPos.xyz;
        float factor;
		if (length(lightDir) < 1)
			factor = 1;
		else
			factor = pointLights[i].radius / length(lightDir);
        float f = dot( input.normal, normalize( lightDir ) );
        if( f > 0 )
        {
            diffuseLight += pointLights[ i ].color * f * factor;
            f = dot( normalize( reflect( normalize( -lightDir ), input.normal ) ), normalize( kPosition.xyz - input.worldPos.xyz ) );
            if( f > 0 )
                specularLight += pointLights[ i ].color * f * factor;
        }
    }
	//if (!(diffuseLight.x >= 0 && diffuseLight.x <= 1))
	//	diffuseLight.x = 0;
    float4 materialColor = shaderTexture.Sample( SampleType, input.tex );
    float4 textureColor = saturate( (materialColor * ambientFactor) + (float4( diffuseLight.x, diffuseLight.y, diffuseLight.z, 0 ) * diffusFactor) + (float4( specularLight.x, specularLight.y, specularLight.z, 0 ) * specularFactor) );
    textureColor.a = materialColor.a;
	if(isnan(diffuseLight.x * diffusFactor))
		textureColor = materialColor;
	return textureColor;
    //return textureColor;
	//if (diffusFactor == 0)
	//	return float4(1, 1, 0, 1);
	/*if (isnan(diffuseLight.x) || isnan(diffusFactor) || isinf(diffuseLight.x) || isinf(-diffuseLight.x))
		return float4(0, 1, 1, 1);
	if (isnan(diffuseLight.x - diffuseLight.x) && isnan(diffuseLight.x * diffusFactor) )
		return float4(1, 1, 1, 1);
	if ((diffuseLight.x * diffusFactor) != 0 && (diffuseLight.x * diffusFactor) != -0)
		return float4(0, 0, 1, 1);
	return float4(0, 1, 0, 1);*/
}