#pragma once

#include <Shas.h>

#include "../../Common/ScreenMask/ScreenMask.h"

#include "../../HelanDll/Interfaces/IPlugin.h"
#include "../../HelanDll/Interfaces/IEnvironment.h"

#include "../../HelanDll/Parameter/Checkbox.h"
#include "../../HelanDll/Parameter/Slider.h"
#include "../../HelanDll/Parameter/EditBox.h"
//#include "../../HelanDll/Parameter/NullParameter.h"

#include "../../HelanDll/Core/DetourHelper.h"

#include "../ParameterGuids.h"

#include "Texture.h"


#define SAFEDELETE(x) if (x) delete x; x = NULL;

class k_Plugin : public k_Direct3D9BasePlugin
{
public:
	k_Plugin(IServiceLocator& ar_ServiceLocator);
	virtual ~k_Plugin();

	virtual void Initialize(IDirect3DDevice9* ar_Device_);
	virtual void Deinitialize();

	virtual void Render();
	virtual void OnBeforeReset();
	virtual void OnAfterReset();

	virtual void set_Active(bool ab_State);

protected:
	bool UpdateParameters();

	LPDIRECT3DTEXTURE9 CreateTexture(int ai_Width, int ai_Height, D3DFORMAT ae_Format);
	IShader* LoadShader(const std::string& as_FileName, const std::string& as_Path="Core");
	D3DXMATRIX GenerateTonemapMatrix(float af_Saturation, float af_Contrast, float af_Brightness);

	void CopyRenderTarget(IDirect3DTexture9* ar_Texture_, RECT* ar_Rect_);

	void Render(ScreenMask* ar_ScreenMask_, IShader* ar_Shader_);
	void Blur(int ai_Steps);

	void RebuildTextures();
	void UpdateTextures();
	void UpdateRendering();

	bool CanRender();

private:
	r_Texture mr_BackBufferTexture;
	r_Texture mr_BlurTexture;
	r_Texture mr_LastBlurTexture;
	ScreenMask* mr_ScreenMask_;
	ScreenMask* mr_QuarterMask_;
	ScreenMask* mr_BlurMask_;
	ScreenMask* mr_BlurToScreenMask_;

	IShaderSystem* mr_ShaderSystem_;
	IShader* mr_ShowTextureShader_;
	IShader* mr_ShowBlurTextureShader_;
	IShader* mr_ShowLastBlurTextureShader_;
	IShader* mr_BlurShader_;
	IShader* mr_BloomShader_;
	IShader* mr_ToneBloomShader_;
	IShader* mr_BloomToScreenShader_;
	IShader* mr_TonemapShader_;

	bool mb_Initialized;
	DWORD mdw_LastTime;

	float mf_BloomBias;
	float mf_BloomExponent;
	float mf_BloomBrightness;
	float mf_BloomMotionFeedback;
	float mf_BloomSizeFactor;
	int mi_BloomBlurSteps;
	bool mb_UseBloomMotionBlur;
	bool mb_UseBloom;

	float mf_TonemapSaturation;
	float mf_TonemapContrast;
	float mf_TonemapBrightness;
	bool mb_UseTonemapping;
	D3DXMATRIX mr_TonemapMatrix;

	IDirect3DStateBlock9* mr_DefaultStateBlock_;
	IDirect3DStateBlock9* mr_CurrentStateBlock_;

	D3DCAPS9 mr_Caps;
	std::wstring ms_LogFile;

	bool mb_NeedToReset;
};


class HelTextureSemanticHandler
	: public ISemanticHandler
{
public:
	HelTextureSemanticHandler(const std::string& as_Name, r_Texture* ar_Texture_)
		: Name(as_Name)
		, mr_Texture_(ar_Texture_)
	{}

	virtual ~HelTextureSemanticHandler()
	{}

	virtual void OnHandle(IShader* inShader, IShaderParameter* inParameter)
	{
		if (inParameter->get_Type() == ShaderParameterType::Texture2D)
		{
			inParameter->set_Texture2D(mr_Texture_->mr_Texture_);
		}
	}

	virtual void OnShaderSystemRefresh(IShader* inShader)
	{}

	virtual const std::string& get_Name() const
	{
		return Name;
	}

protected:
	std::string Name;
	r_Texture* mr_Texture_;
};
