Texture1D tex : WAVEFORMDATA;

SamplerState sTex
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
};

struct VS_IN
{
	float2 pos : POSITION;
	float2 tc : TEXCOORD0;
};

struct PS_IN
{
	float4 pos : SV_POSITION;
	float2 tc : TEXCOORD0;
};


float4 backgroundColor : BACKGROUNDCOLOR;
float4 highlightColor  : HIGHLIGHTCOLOR;
float4 selectionColor  : SELECTIONCOLOR;
float4 textColor       : TEXTCOLOR;
float cursorPos        : CURSORPOSITION;
bool cursorVisible     : CURSORVISIBLE;
float seekPos          : SEEKPOSITION;
bool seeking           : SEEKING;
float4 replayGain      : REPLAYGAIN; // album gain, track gain, album peak, track peak
float2 viewportSize    : VIEWPORTSIZE;
bool horizontal        : ORIENTATION;
bool shade_played      : SHADEPLAYED;

PS_IN VS( VS_IN input )
{
	PS_IN output = (PS_IN)0;

	float2 half_pixel = float2(1,-1) / viewportSize;
	output.pos = float4(input.pos - half_pixel, 0, 1);
	if (horizontal)
		output.tc = float2((input.tc.x + 1.0) / 2.0, input.tc.y);
	else
		output.tc = float2((-input.tc.y + 1.0) / 2.0, input.tc.x);

	return output;
}

float4 bar( float pos, float2 tc, float4 fg, float4 bg, float width, bool show )
{
	float dist = abs(pos - tc.x);
	float4 c = (show && dist < width)
		? lerp(fg, bg, smoothstep(0, width, dist))
		: bg;
	return c;
}

float4 evaluate(float4 bg, float4 fg, float factor)
{
	return saturate(lerp(bg, fg, factor));
}

float4 played( float pos, float2 tc, float4 bg, float factor)
{
	float4 c = bg;
	if (pos < tc.x)
	{
		c = evaluate(backgroundColor, highlightColor, factor);
	}
	else
	{
		c = evaluate(highlightColor, backgroundColor, factor);
	}
	return c;
}

float RMSfactor( float2 tc, float border )
{
	// alpha 1 indicates biased texture
	float4 minmaxrms = tex.Sample(sTex, tc.x);
	if (replayGain.g != -1000) {
		minmaxrms.rgb *= pow(10,(replayGain.g) / 20) * 2; //use track gain
	} else if (replayGain.r != -1000) {
		minmaxrms.rgb *= pow(10,(replayGain.r) / 20) * 2; //use album gain
	}
	minmaxrms.rgb -= 0.5 * minmaxrms.a;
	minmaxrms.rgb *= 1.0 + minmaxrms.a;

	float belowWave = tc.y + border - minmaxrms.r;
	float aboveWave = tc.y - border - minmaxrms.g;
	float factorWave = min(abs(belowWave), abs(aboveWave));
	bool insideWave = (belowWave > 0 && aboveWave < 0);

	float factor = insideWave ? (saturate(factorWave / border / 2)) : 0.0;

	return factor;
}

float4 PS( PS_IN input ) : SV_Target
{
	float dx, dy;
	if (horizontal)
	{
		dx = 1/viewportSize.x;
		dy = 1/viewportSize.y;
	}
	else
	{
		dx = 1/viewportSize.y;
		dy = 1/viewportSize.x;
	}

	float factor = RMSfactor(input.tc, 2.5 * dy);

	float4 c0 = evaluate(backgroundColor, textColor, factor);
	if (shade_played)
		c0 = played(cursorPos, input.tc, c0, factor);
	c0 = bar(cursorPos, input.tc, selectionColor, c0, dx, cursorVisible);
	c0 = bar(seekPos,   input.tc, selectionColor, c0, dx, seeking      );
	return c0;
}

technique Render9
{
	pass
	{
		VertexShader = compile vs_2_0 VS();
		PixelShader = compile ps_2_0 PS();
	}
}
