/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
   - FX11 compilers
*/

#include "../../compat_includes.inc"
uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

struct out_vertex {
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD0;
	float4 t1 : TEXCOORD1;
	float4 t2 : TEXCOORD2;
	float4 t3 : TEXCOORD3;
	float4 t4 : TEXCOORD4;
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
};

out_vertex main_vertex(COMPAT_IN_VERTEX)
{
	out_vertex OUT;
#ifdef HLSL_4
	float4 position = VIN.position;
	float2 texCoord = VIN.texCoord;
#else
	OUT.Color = color;
#endif
	OUT.position = mul(modelViewProj, position);
	OUT.texCoord = texCoord;
	
	float x = 0.5 * (1.0 / COMPAT_texture_size.x);
	float y = 0.5 * (1.0 / COMPAT_texture_size.y);
	float2 dg1 = float2( x, y);
	float2 dg2 = float2(-x, y);
	float2 dx = float2(x, 0.0);
	float2 dy = float2(0.0, y);

	OUT.t1 = float4(texCoord.xy - dg1, texCoord.xy - dy);
	OUT.t2 = float4(texCoord.xy - dg2, texCoord.xy + dx);
	OUT.t3 = float4(texCoord.xy + dg1, texCoord.xy + dy);
	OUT.t4 = float4(texCoord.xy + dg2, texCoord.xy - dx);
	
	return OUT;
};

const static float3 dt = float3(1.0, 1.0, 1.0);

const float mx = 0.325;      // start smoothing wt.
const float k = -0.250;      // wt. decrease factor
const float max_w = 0.25;    // max filter weigth
const float min_w =-0.05;    // min filter weigth
const float lum_add = 0.25;  // effects smoothing

float4 TwoxScaleHQ(float4 t1, float4 t2, float4 t3, float4 t4, float2 texCoord, COMPAT_Texture2D(decal))
{

   float3 c00 = COMPAT_SamplePoint(decal, t1.xy).xyz; 
   float3 c10 = COMPAT_SamplePoint(decal, t1.zw).xyz; 
   float3 c20 = COMPAT_SamplePoint(decal, t2.xy).xyz; 
   float3 c01 = COMPAT_SamplePoint(decal, t4.zw).xyz; 
   float3 c11 = COMPAT_SamplePoint(decal, texCoord).xyz; 
   float3 c21 = COMPAT_SamplePoint(decal, t2.zw).xyz; 
   float3 c02 = COMPAT_SamplePoint(decal, t4.xy).xyz; 
   float3 c12 = COMPAT_SamplePoint(decal, t3.zw).xyz; 
   float3 c22 = COMPAT_SamplePoint(decal, t3.xy).xyz; 

   float md1 = dot(abs(c00 - c22), dt);
   float md2 = dot(abs(c02 - c20), dt);

   float w1 = dot(abs(c22 - c11), dt) * md2;
   float w2 = dot(abs(c02 - c11), dt) * md1;
   float w3 = dot(abs(c00 - c11), dt) * md2;
   float w4 = dot(abs(c20 - c11), dt) * md1;

   float t1_ = w1 + w3;
   float t2_ = w2 + w4;
   float ww = max(t1_, t2_) + 0.0001;

   c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1_ + t2_ + ww);

   float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);
   float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);

   w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);
   w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);
   w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);
   w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);

   return float4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1.0);
}

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return TwoxScaleHQ(VOUT.t1, VOUT.t2, VOUT.t3, VOUT.t4, VOUT.texCoord, decal);
}
COMPAT_END