#ifndef Context_hpp
#define Context_hpp

#include "Sampler.hpp"
#include "FVF.hpp"

#include <map>
#include <vector>

namespace swShader
{
	class RenderTarget;
	class VertexBuffer;
	struct LTVertex;
	class PS_2_0Shader;
	class Renderer;

	class Context
	{
	public:
		enum ColorDepth
		{
			COLOR_B8G8R8A8,

			COLOR_LAST = COLOR_B8G8R8A8
		};

		enum ShadingMode
		{
			SHADING_NONE,
		//	SHADING_FLAT,
			SHADING_GOURAUD,

			SHADING_LAST = SHADING_GOURAUD
		};

		enum DepthCompareMode
		{
			DEPTH_ALWAYS,
			DEPTH_NEVER,
			DEPTH_LESS,
			DEPTH_LESSEQUAL,
			DEPTH_GREATER,
			DEPTH_GREATEREQUAL,

			DEPTH_LAST = DEPTH_GREATEREQUAL
		};

		enum AlphaCompareMode
		{
			ALPHA_ALWAYS,
			ALPHA_NEVER,
			ALPHA_LESS,
			ALPHA_LESSEQUAL,
			ALPHA_GREATER,
			ALPHA_GREATEREQUAL,

			ALPHA_LAST = ALPHA_GREATEREQUAL
		};

		enum CullMode
		{
			CULL_NONE,
			CULL_CLOCKWISE,
			CULL_COUNTERCLOCKWISE,

			CULL_LAST = CULL_COUNTERCLOCKWISE
		};

		enum BlendFactor
		{
			BLEND_ZERO,
			BLEND_ONE,
			BLEND_SOURCE,
			BLEND_INVSOURCE,
			BLEND_DEST,
			BLEND_INVDEST,
			BLEND_SOUCEALPHA,
			BLEND_INVSOURCEALPHA,
			BLEND_DESTALPHA,
			BLEND_INVDESTALPHA,

			BLEND_LAST = BLEND_INVDESTALPHA
		};

		static void init();

	protected:
		static const RenderTarget *renderTarget;
		static void (*scanline)();

		// States
		static ColorDepth colorDepth;   // Render target color depth
		static DepthCompareMode depthCompareMode;
		static AlphaCompareMode alphaCompareMode;
		static bool depthWriteEnable;
		static bool alphaTestEnable;
		static bool alphaBlendEnable;
		static ShadingMode shadingMode;
		static bool specularEnable;
		static FVFFlags FVF;
		static BlendFactor sourceBlendFactor;
		static BlendFactor destBlendFactor;

		static CullMode cullMode;
		static int alphaReference;
		static Sampler sampler[16];

		// Mipmap bias
		static float bias;

		// Gradients
		static float dz_dx;
		static float dz_dy;
		static float dw_dx;
		static float dw_dy;

		static Color<float> dC_dx;
		static Color<float> dC_dy;
		static Color<float> dL_dx;
		static Color<float> dL_dy;

		static UVW dT_dx[8];
		static UVW dT_dy[8];

		// Pixel location
	//	static int x;   // ecx
		static int y;

		// Interpolants
		static int lx;
		static int rx;
		
		static float z;
		static float w;

		static Color<float> C;
		static Color<float> L;

		static UVW T[8];

		// Color and depth buffer scanlines
		static unsigned int *colorBuffer;
		static float *depthBuffer;
	};
}

#endif   // Context_hpp