#pragma once

#include "..\..\Interfaces\IShaderSystem.h"

#include "..\Shader\Shader.h"

class ShaderSystem :
	public IShaderSystem
{
public:
	ShaderSystem(IDirect3DDevice9* inDevice);
	virtual ~ShaderSystem();

	virtual bool AddAnnotationHandler(IAnnotationHandler* inAnnotationHandler);
	virtual bool RemoveAnnotationHandler(IAnnotationHandler* inAnnotationHandler);
	virtual bool RemoveAnnotationHandler(const std::string& inAnnotationHandlerName);
	virtual IAnnotationHandler* get_AnnotationHandler(const std::string& inAnnotationHandlerName) const;

	virtual bool AddCallbackHandler(ICallbackHandler* inCallbackHandler);
	virtual bool RemoveCallbackHandler(ICallbackHandler* inCallbackHandler);
	virtual bool RemoveCallbackHandler(const std::string& inCallbackHandlerName);
	virtual ICallbackHandler* get_CallbackHandler(const std::string& inCallbackHandlerName) const;

	virtual bool AddSemanticHandler(ISemanticHandler* inSemanticHandler);
	virtual bool RemoveSemanticHandler(ISemanticHandler* inSemanticHandler);
	virtual bool RemoveSemanticHandler(const std::string& inSemanticHandlerName);
	virtual ISemanticHandler* get_SemanticHandler(const std::string& inSemanticHandlerName) const;

	virtual IShader* CreateShader(const std::string& inShaderName, const std::string& inShaderCode);
	virtual IShader* LoadShader(const std::string& inShaderName, const std::string& inShaderFileName);
	virtual IShader* get_Shader(const std::string& inShaderName) const;
	virtual bool RemoveShader(IShader* inShader);
	virtual bool RemoveShader(const std::string& inShaderName);

	virtual void Refresh(IDirect3DDevice9* inDevice);

private:
	bool AddShader(Shader* inShader);
	void FillShaderWithHandlers(Shader* inShader);

	std::map<std::string, IAnnotationHandler*> AnnotationHandlerList;
	std::map<std::string, ISemanticHandler*> SemanticHandlerList;
	std::map<std::string, ICallbackHandler*> CallbackHandlerList;
	std::map<std::string, IShader*> ShaderList;

	IDirect3DDevice9* Device;
};
