#ifndef MOD_NVG_HLSL
#define MOD_NVG_HLSL

////////////////////////////////////////////////////////////////////////////////////////
////// USER DEFINED VARS - CHANGE TO EFFECT SHAPE, SIZE AND CENTER POSITION OF NVG /////

//overall NVG postion and size
static const float2 EYE_CENTER = float2(0.5f, 0.655f);  // SETS CENTER COORDINATE OF NVG EFFECT ON SCREEN   			def=(0.5f,0.65f)	VR=(0.5f, 0.75f)	Tacca (0.5f, 0.655f)
static const float2 EYE_SIZE = float2(0.5f, 0.8f); // SETS X AND Y DIAMETER OF NVG (PERCENTAGE OF SCREEN) 				def=(0.5,0.88f)		VR=(0.8f, 0.7f)		Tacca Circle (0.47f, 0.75f) Tacca Wide (0.83f, 0.98f)
// To get clear circles, first decide on your x width. NVG tubes usually cover about 40 degrees of FoV, if you want this set realistically, set this value to be about 40/<your DCS fov>*1.2
// Note on FoV: DCS defaults to a value of 80 for most jets, but keep in mind that the NVG will scale alongside zoom.
// To get the y vlaue, multiply your x value by your screen ratio, e.g., x * 16/9 = x * 1.7777

//sets which NVG type to use. 0 = full screen, 1 = NVG with no ring, 2 = NVG with Ring, 3 = NVG with ring and slight zoom (not functional)
//note: if using render mode = 1, nvg will only be size of RInner below. ie RInner(percentage) * Eye_Size = final NVG size
static const int RenderMode = 2;

//FOR RenderMode 2 ONLY above^^, sets which type of goggles/rings to use: 1 = Monocular, 2 = Binocular, 3 = Quad
static const int Tubes = 2;
static const float BiOffset = 0.35f;		// Offsets additional Tubes by this percentage of RInner*2 			def=0.15f	Tacca=0.35f
static const float QuadOffset = 0.7125f;	// Offsets additional Tubes by this percentage of RInner*2			def=0.7125f	Tacca=0.7135f

//RING Sizing
static const float ROFade = 0.90f; 	//sets outside edge of full black ring, outside of the will fade to no effect			def= 0.90f   VR=0.95f	Tacca=0.90f
static const float RMerge = 0.83f;	// sets inside edge of full black ring													def= 0.85f   VR=0.85f	Tacca=0.83f
static const float RInner = 0.73f; 	// sets inside start of fade from NVG effect to black ring								def= 0.70f   VR=0.82f	Tacca=0.73f


static const float ROFadeSQR = pow(ROFade, 2);
static const float RMergeSQR = pow(RMerge, 2);
static const float RInnerSQR = pow(RInner, 2);


// Color to use for NVGs. This is a hue color where the value represents a percentage of a 360 degrees on the HSL color wheel .
// ONLY FIRST VALUE CURRENTLY WORKS!!!!!!!!
// third = nato green, 0.41f = soviet style
static const float COLORIZE_COLOR[2] =
	{	0.37f, 		// A-10C 	def=0.33f
		0.41f   	// KA-50 	def=0.41f (144 degrees hue/360)
	};

// This value and the NVG intensity control (in game) controls the amount of gain of the NVG. 
// Larger value means NVG is brighter. RECOMMENDED AT 50.0f and 40.0f
static const float NVG_LIFT[2] =
	{  	50.0f, // A-10C
		40.0f  // KA-50
	};

// Value controls contrast of NVG scope, higher the value the more contrast but results in more clipping of darks and highlights.
static const float contrast = 1.1f; 	// no contrast curve=1.0f 	def=1.1f  max~1.4f

// Value controls intensity of noise as gain is increased. Larger value means greater noise. Note that Russian NVG has more noise coded into it so value should be higher.
// RECOMMENDED AT 0.2f (no noise on fullmoon, some noise with no moon)
static const float NVG_NOISE[2] =
	{  	0.2f, // A-10C		no noise=0.0f, def= 0.2f 
		0.4f  // KA-50
	};


///////////////////////////////////////////////////////////////////////////////
////// STATIC VARS - DONT CHANGE UNLESS YOU HAVE AN UNDERSTANDING OF CODE /////

// RBG weighting used in dot product of standard colours (ie NVG mainly amplify reds and not very much green or blue)
static const float3 LUM = {0.9f, 0.2f, 0.03f};		// def={0.9f, 0.2f, 0.03f}


//////////////////////////////////////////////////////////////////////////////////
/////DO NOT CHANGE!!!!!!!!!!! PERSISTENT THROUGH MULTIPLE FILES & EFFECT subsections.
// NVG Type 0 = A-10C. 1 = KA-50. 
static const int NVG_A10 = 0;	
static const int NVG_KA50 = 1;  
 
//Used through out hsl to rgb conversion, save calculation time
static const float third = 1.0f/3.0f;   


////////////////////////////////////
////////// PROCEDURES //////////////

///// CONVERT HUE VALUE SINGLE RGB VALUE, USED IN HSL TO RBG
float hue2rgb(const float p, const float q, const float t)
{
  float T = t;
  if (t < 0.0f)
	{ T += 1.0f;
	}
  if (t > 1.0f)
	{ T -= 1.0f;
	}
  if (T < 1.0f / 6.0f)
	{ return p + (q - p) * 6.0f * T;
	}
  if (T < 1.0f / 2.0f)
	{ return q;
	}
  if (T < 2.0f / 3.0f)
	{return p + (q - p) * (2.0f/3.0f - T) * 6.0f;
	}
  return p;
}

///// HSL TO RGB COLOR CONVERSION
float3 HSLtoRGB(const float3 hsl): COLOR0
{
  const float h = hsl.r;
  const float s = hsl.g;
  const float l = hsl.b;
  float r = 0.0f;
  float g = 0.0f;
  float b = 0.0f;
  if (l == 0.0f)
  { 
	r = 0.0f;
    g = 0.0f;
    b = 0.0f;
  }
  else
  {
    float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
    float p = 2 * l - q;
    r = hue2rgb(p, q, h + (third));			//third is just 1/3 but calculated at start to save time
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - (third));			//third is just 1/3 but calculated at start to save time
  }
return float3(r, g, b);
}


//////creates nvg scope
float3 maskNVG(const float2 uv): SV_TARGET0
{
	const float ESRx = pow((EYE_SIZE.x)/2, 2);  //radius of NVG - x axis
	const float ESRy = pow((EYE_SIZE.y)/2, 2);  //radius of NVG - y axis
	float x = 0.0f;        //used for mask
	float y = 0.0f;        //used for mask
	float z = 0.0f;        //used for mask
	float posy = uv.y - (1-EYE_CENTER.y);		//pixel distance from nvg center - y axis
	float posx = 0.0f;
	float posx0 = 0.0f;
	float posx1 = 0.0f;
	float posx2 = 0.0f;
	float dist0 = 0.0f;
	float dist1 = 0.0f;
	float dist2 = 0.0f;
	float distance = 0.0f;

	if(Tubes == 1)
	{
		posx = uv.x - EYE_CENTER.x; 			//pixel distance from nvg center - x axis
		distance = (pow(posx, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
	}
	if(Tubes == 2)
	{
	float offset = (BiOffset * RInner)/2.0f;
		posx0 = uv.x - EYE_CENTER.x + offset/2.0f;               //pixel distance from nvg center - x axis
		posx1 = uv.x - EYE_CENTER.x - offset/2.0f;               //pixel distance from nvg center - x axis
		dist0 = (pow(posx0, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
		dist1 = (pow(posx1, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
		distance = min(dist0, dist1);
	}
	if(Tubes == 3)
	{
		float offset = (QuadOffset * RInner)/2.0f;
		posx0 = uv.x - EYE_CENTER.x + offset;                		 //pixel distance from nvg center - x axis
  	posx1 = uv.x - EYE_CENTER.x - offset;                    //pixel distance from nvg center - x axis
	  posx2 = uv.x - EYE_CENTER.x;             								 //pixel distance from nvg center - x axis
		dist0 = (pow(posx0, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
		dist1 = (pow(posx1, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
		dist2 = (pow(posx2, 2)/(ESRx)) + (pow(posy, 2)/(ESRy));  //pixel distance from nvg center - radial
		distance = min(dist0, dist1);
		distance = min(distance, dist2);
	}
	
	{if (distance > 1)
		{return float3(x, y, z);
			}
	else
		{if (distance > ROFadeSQR)
			{
			x = 0.0f;
			y = 1.0f;
			z = (1 - smoothstep(ROFadeSQR, 1.0, distance))*0.9;
			return float3(x, y, z);
			}
		else if (distance > RMergeSQR)
			{
			x = 0.0f;
			y = 1.0f;
			z = 1.0f;
			return float3(x, y, z);
			}
		else if (distance > RInnerSQR)
			{
			// note order for calculations
			y = (smoothstep(RInnerSQR, RMergeSQR, distance))*0.95f;
			x = 1.0f - y;
			z = 1.0f;
			return float3(x, y, z);
			}
		else
			{
			x = 1.0f;
			y = 0.0f;
			z = 1.0f;
			return float3(x, y, z);
			}
		}
	}
}	


#endif