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

cbuffer TexturEffect : register(b3)
{
    bool effectEnabled;
	float effectPercentage;
};

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

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

////////////////////////////////////////////////////////////////////////////////                        
// Pixel Shader                                                                                         
////////////////////////////////////////////////////////////////////////////////                        
float4 TexturePixelShader(PixelInputType input) : SV_TARGET
{
	float3 diffuseLight = float3(0, 0, 0);
	float3 specularLight = float3(0, 0, 0);
	float4 materialColor = shaderTexture.Sample(SampleType, input.tex);
	if (effectEnabled)
	{
        bool effectAlpha = effectPercentage > 1.f;
        float percentage = effectPercentage;
        if (effectAlpha) percentage -= 1.f;
        if (effectEnabled && !effectAlpha) clip(materialColor.a - 0.25);
		float dist = sqrt((input.tex.x - 0.5f) * (input.tex.x - 0.5f) + (input.tex.y - 0.5f) * (input.tex.y - 0.5f)) / sqrt(0.5f);
        if (dist < percentage)
		{
            float alphaMultiplier = (percentage - dist) / 0.2f;
			if (alphaMultiplier > 1)
				alphaMultiplier = 1.f;
			float4 effectColor = additionalTexture.Sample(SampleType, input.tex);
            float effectA = effectColor.a;
			materialColor = effectColor * (effectColor.a * alphaMultiplier) + materialColor * (1 - effectColor.a * alphaMultiplier);
            if (effectAlpha)
			{
                materialColor.a = effectA * alphaMultiplier;
                if (materialColor.a > 1.0) materialColor.a = 1.0;
			}
		}
    }
	else
	{
        clip(materialColor.a - 0.25);
        //materialColor.a = 1.0;
	}
	if (input.light1.w > 0)
    {
        diffuseLight = float3(materialColor.x * input.light1.x,
            materialColor.y * input.light1.y,
            materialColor.z * input.light1.z);
        float4 diffuseLight2 = float4(materialColor.x * input.light2.x,
						materialColor.y * input.light2.y,
						materialColor.z * input.light2.z, 0);
        if (diffuseLightCount > 0)
        {
            float factor = dot(input.normal, -difuseLights[0].direction);
			if (factor < 0)
				factor = 0;
            factor = factor * 0.5 + 0.5;
            diffuseLight = diffuseLight * factor;
        }
		else
        {
            diffuseLight = diffuseLight * 0.5;
		}

        if (diffuseLight2.x > diffuseLight.x)
        {
            diffuseLight.x = diffuseLight2.x;
        }
        if (diffuseLight2.y > diffuseLight.y)
        {
            diffuseLight.y = diffuseLight2.y;
        }
        if (diffuseLight2.z > diffuseLight.z)
        {
            diffuseLight.z = diffuseLight2.z;
        }
	}
	else
	{
		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);
		}
        diffuseLight = float3(1.0, 1.0, 1.0);
		/*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 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)) clip(-1);
	//	textureColor = materialColor;
    if (effectEnabled && effectPercentage == 0)
	{
        clip(textureColor.a - 0.5);
        //textureColor.a = 1.0;
	}
	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);*/
}