////////////////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////////////////

#include "../../../types.txt"
#include "../../colorSpace.txt"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Structures
////////////////////////////////////////////////////////////////////////////////////////////////////

struct PS_INPUT
{
#if MIX_SM_HIGH
	float4 pos : SV_POSITION;
#endif //MIX_SM_HIGH
	float2 tex : TEXCOORD0;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Grobal values
////////////////////////////////////////////////////////////////////////////////////////////////////

#if MIX_SM_HIGH

	cbuffer cbInput : register( b0 )
	{
		float4 g_Params;
	};

	Texture2D g_ColorTexture       : register( t0 );
	SamplerState g_ColorSampler    : register( s0 );

	#if ENABLE_LUM
		Texture2D g_LumTexture     : register( t1 );
		SamplerState g_LumSampler  : register( s1 );
	#endif //ENABLE_LUM
	
#else //MIX_SM_HIGH

	float4 g_Params : register( c0 );

	sampler g_ColorSampler    : register( s0 );

	#if ENABLE_LUM
		sampler g_LumSampler  : register( s1 );
	#endif //ENABLE_LUM

#endif //MIX_SM_HIGH

////////////////////////////////////////////////////////////////////////////////////////////////////
// Macros
////////////////////////////////////////////////////////////////////////////////////////////////////

#if MIX_SM_HIGH

	#define TEX_COLOR( uv ) g_ColorTexture.Sample( g_ColorSampler, uv )

	#if ENABLE_LUM
		#define TEX_LUM( uv ) g_LumTexture.Sample( g_LumSampler, uv )
	#endif //ENABLE_LUM

#else //MIX_SM_HIGH

	#define TEX_COLOR( uv ) tex2D( g_ColorSampler, uv )

	#if ENABLE_LUM
		#define TEX_LUM( uv ) tex2D( g_LumSampler, uv )
	#endif //ENABLE_LUM

#endif //MIX_SM_HIGH

#define MIDDLE_GRAY g_Params.x
#define WHITE2_INV  g_Params.y
#define THRESHOLD   g_Params.z
#define OFFSET      g_Params.w

////////////////////////////////////////////////////////////////////////////////////////////////////
// Sub function
////////////////////////////////////////////////////////////////////////////////////////////////////

#if ENABLE_LUM

	float CuttoffBlack( float Y, float middleGray, float lumAdapted )
	{
		float lumScaled;
		float lumThreshold;
		float lumOT;
		float output;

		lumScaled = Y * middleGray / ( lumAdapted + 0.0001 );
		lumThreshold = max( 0.0, lumScaled * ( 1.0 + lumScaled * WHITE2_INV ) - THRESHOLD );
		lumOT = OFFSET + lumThreshold;

		if( any( lumOT ) == true )
		{
			output = lumThreshold / lumOT;
		}	
		else
		{
			output = 0.0;
		}

		return output;
	}

#endif //ENABLE_LUM

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function
////////////////////////////////////////////////////////////////////////////////////////////////////

float4 main( PS_INPUT input ) : MSV_TARGET0
{
	float4 output;

#if ENABLE_LUM

	float4 color = TEX_COLOR( input.tex );
	float3 Yxy = RGBToYxy( color.rgb );
	float lum = TEX_LUM( float2( 0.5, 0.5 ) ).r;

	#if ENABLE_AUTO_MIDDLEGRAY

		float middleGray = 1.03 - ( 2.0 / ( 2.0 + log10( lum + 1.0 ) ) );

		Yxy.r = CuttoffBlack( Yxy.r, middleGray, lum );

	#else //ENABLE_AUTO_MIDDLEGRAY

		Yxy.r = CuttoffBlack( Yxy.r, MIDDLE_GRAY, lum );

	#endif //ENABLE_AUTO_MIDDLEGRAY

	output.rgb = YxyToRGB( Yxy );
	output.a = color.a;
//	output.rgb = YxyToRGB( Yxy ) * color.a;
//	output.a = 1.0;

#else //ENABLE_LUM

	output = TEX_COLOR( input.tex );

	output.rgb = output.rgb + ( output.rgb * output.rgb ) * WHITE2_INV;
	output.rgb = max( 0.0, output.rgb - THRESHOLD );
	output.rgb = output.rgb / ( OFFSET + output.rgb );
	
//	output.rgb *= output.a;
//	output.a = 1.0;

#endif //ENABLE_LUM

	return max( 0.0, output );

};
