#pragma once

#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr.h>

#include <string>

struct IShaderParameter;
struct ISemanticHandler;
struct IAnnotationHandler;
struct ICallbackHandler;
struct IShader;


/// <summary>
/// Der Hauptteil des ShaderSystems.
/// </summary>
/*!
*  \include ShaderSystem.cpp
*/
struct IShaderSystem
{
	/// <summary>
	/// Der virtuelle Destruktor des ShaderSystems. Das ShaderSystem wird alle Resourcen im Besitz des ShaderSystems eigenständig vernichten.
	/// </summary>
	virtual ~IShaderSystem() {}

	/// <summary>
	///	Fügt einen Annotationhandler dem Annotationhandlerpool des Shaders hinzu. Annotationhandler welche nicht vom Shadersystem zugewiesen wurden können durch gleichnamige AnnotationHandler überschrieben werden.
	/// </summary>
	/// <param name="inAnnotationHandler">Ein Zeiger auf den Handler, der Besitz des Handlers obliegt bei Erfolg dem Shader.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool AddAnnotationHandler(IAnnotationHandler* inAnnotationHandler) = 0;

	/// <summary>
	///	Entfernt einen Annotationhandler aus dem Annotationhandlerpool des Shaders. Annotationhandler welche übergeben werden, aber nicht im Besitz des Shaders sind werden nicht frei gegeben.
	/// </summary>
	/// <param name="inAnnotationHandler">Ein Zeiger auf den Handler.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveAnnotationHandler(IAnnotationHandler* inAnnotationHandler) = 0;

	/// <summary>
	///	Entfernt einen Annotationhandler aus dem Annotationhandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inAnnotationHandlerName">Der Name des Annotationhandlers.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveAnnotationHandler(const std::string& inAnnotationHandlerName) = 0;

	/// <summary>
	///	Sucht einen Annotationhandler aus dem Annotationhandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inAnnotationHandlerName">Der Name des Annotationhandlers.</param>
	/// <returns>Den gesuchten Annotationhandler oder NULL wenn der Handler nicht gefunden wurde.</returns>
	virtual IAnnotationHandler* get_AnnotationHandler(const std::string& inAnnotationHandlerName) const = 0;

	/// <summary>
	///	Fügt einen Callbackhandler dem Callbackhandlerpool des Shaders hinzu. Callbackhandler welche nicht vom Shadersystem zugewiesen wurden können durch gleichnamige CallbackHandler überschrieben werden.
	/// </summary>
	/// <param name="inCallbackHandler">Ein Zeiger auf den Handler, der Besitz des Handlers obliegt bei Erfolg dem Shader.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool AddCallbackHandler(ICallbackHandler* inCallbackHandler) = 0;

	/// <summary>
	///	Entfernt einen Callbackhandler aus dem Callbackhandlerpool des Shaders. Callbackhandler welche übergeben werden, aber nicht im Besitz des Shaders sind werden nicht frei gegeben.
	/// </summary>
	/// <param name="inCallbackHandler">Ein Zeiger auf den Handler.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveCallbackHandler(ICallbackHandler* inCallbackHandler) = 0;

	/// <summary>
	///	Entfernt einen Callbackhandler aus dem Callbackhandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inCallbackHandlerName">Der Name des Callbackhandlers.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveCallbackHandler(const std::string& inCallbackHandlerName) = 0;

	/// <summary>
	///	Sucht einen Callbackhandler aus dem Callbackhandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inCallbackHandlerName">Der Name des Callbackhandlers.</param>
	/// <returns>Den gesuchten Annotationhandler oder NULL wenn der Handler nicht gefunden wurde.</returns>
	virtual ICallbackHandler* get_CallbackHandler(const std::string& inCallbackHandlerName) const = 0;

	/// <summary>
	///	Fügt einen Semantichandler dem Semantichandlerpool des Shaders hinzu. Semantichandler welche nicht vom Shadersystem zugewiesen wurden können durch gleichnamige SemanticHandler überschrieben werden.
	/// </summary>
	/// <param name="inSemanticHandler">Ein Zeiger auf den Handler, der Besitz des Handlers obliegt bei Erfolg dem Shader.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool AddSemanticHandler(ISemanticHandler* inSemanticHandler) = 0;

	/// <summary>
	///	Entfernt einen Semantichandler aus dem Semantichandlerpool des Shaders. Semantichandler welche übergeben werden, aber nicht im Besitz des Shaders sind werden nicht frei gegeben.
	/// </summary>
	/// <param name="inSemanticHandler">Ein Zeiger auf den Handler.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveSemanticHandler(ISemanticHandler* inSemanticHandler) = 0;

	/// <summary>
	///	Entfernt einen Semantichandler aus dem Semantichandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inSemanticHandlerName">Der Name des Semantichandlers.</param>
	/// <returns>True für Erfolg, false für Fehlschlag der Aktion.</returns>
	virtual bool RemoveSemanticHandler(const std::string& inSemanticHandlerName) = 0;

	/// <summary>
	///	Sucht einen Semantichandler aus dem Semantichandlerpool des Shaders mit den angegebenen Namen.
	/// </summary>
	/// <param name="inSemanticHandlerName">Der Name des Semantichandlers.</param>
	/// <returns>Den gesuchten Annotationhandler oder NULL wenn der Handler nicht gefunden wurde.</returns>
	virtual ISemanticHandler* get_SemanticHandler(const std::string& inSemanticHandlerName) const = 0;

	/// <summary>
	///	Erstellt einen neuen Shader aus dem angegebenen klartext String.
	/// </summary>
	/// <param name="inShaderName">Der eindeutige Name des Shaders.</param>
	/// <param name="inShaderCode">Der klartext Effektcode aus dem ein Shader generiert werden soll.</param>
	/// <returns>Den erstellten Shader, oder NULL im Falle eines gravierenden Fehlers.</returns>
	virtual IShader* CreateShader(const std::string& inShaderName, const std::string& inShaderCode) = 0;

	/// <summary>
	///	Lädt einen Shader anhand des angegebenen Dateinamens.
	/// </summary>
	/// <param name="inShaderName">Der eindeutige Name des Shaders.</param>
	/// <param name="inShaderFileName">Der Pfad und Dateiname des zu ladenenen Shaders.</param>
	/// <returns>Den erstellten Shader, oder NULL im Falle eines gravierenden Fehlers.</returns>
	virtual IShader* LoadShader(const std::string& inShaderName, const std::string& inShaderFileName) = 0;

	/// <summary>
	///	Sucht einen Shader anhand des angegenenen Namens.
	/// </summary>
	/// <param name="inShaderName">Der eindeutige Name des Shaders.</param>
	/// <returns>Den gefundenen Shader, oder NULL im Falle eines Fehlschlags.</returns>
	virtual IShader* get_Shader(const std::string& inShaderName) const = 0;

	/// <summary>
	///	Entfernt einen angegebenen Shader.
	/// </summary>
	/// <param name="inShader">Der zu entfernende Shader.</param>
	/// <returns>True wenn der Shader erfolgreich entfernt werden konnte, oder false für einen Fehlschlag.</returns>
	virtual bool RemoveShader(IShader* inShader) = 0;

	/// <summary>
	///	Entfernt den Shader mit dem angegebenen Namen.
	/// </summary>
	/// <param name="inShaderName">Der Name des zu entfernenden Shaders.</param>
	/// <returns>True wenn der Shader erfolgreich entfernt werden konnte, oder false für einen Fehlschlag.</returns>
	virtual bool RemoveShader(const std::string& inShaderName) = 0;


	/// <summary>
	///	Aktualisiert das ShaderSystem anhand des neuen DX9 Devices
	/// </summary>
	/// <param name="inDevice">Das neue DX9 Device.</param>
	virtual void Refresh(IDirect3DDevice9* inDevice) = 0;
}; 
