#pragma once

#include "Punkt.h"
#include "ReferenceCounter.h"

struct ID3D11Texture2D;
struct ID3D11ShaderResourceView;
struct ID3D11Device;
struct ID3D11DeviceContext;

namespace Framework
{
    class Bild; //! Bild.h
    class Render3D; //! Render3D.h
    class TexturList; //! TexturList.h
    class DX12CopyCommandQueue;
    class DX12DirectCommandQueue;

    //! Wandelt ein Bild in eine Textur um, die an die Grafikkarte zum rendern übergeben werden kann
    class Textur : public virtual ReferenceCounter
    {
    protected:
        Bild* bild;
        Punkt lastGr;
        int id;

    public:
        //! Konstruktor
        DLLEXPORT Textur();
        //! Destruktor
        DLLEXPORT virtual ~Textur();
        //! Setzt einen Zeiger auf das Bild, welches die Textur enthält
        //! \param b Der Zeiger auf das Bild
        DLLEXPORT void setBildZ( Bild* b );
        //! Setzt das Bild welches die Textur enthält, indem es kopiert wird
        //! \param b Das Bild, was kopiert werden soll
        DLLEXPORT void setBild( Bild* b );
        //! Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        DLLEXPORT virtual bool updateTextur() = 0;
        //! Gibt true zurük, wenn updateTextur aufgerufen werden muss
        DLLEXPORT virtual bool brauchtUpdate() const = 0;
        //! Gibt einen Zeiger auf das Bild zurück
        DLLEXPORT Bild* getBild() const;
        //! Gibt einen Zeiger auf das Bild ohne erhöhten Reference Counter zurück
        DLLEXPORT Bild* zBild() const;
        //! Gibt die Id der Textur zurück, wenn sie in einer TexturList registriert wurde. (siehe Framework::zTexturRegister())
        DLLEXPORT int getId() const;

        friend TexturList;
    };

    //! Wandelt ein Bild in eine Textur um, die an die Grafikkarte zum rendern übergeben werden kann
    class DX9Textur : public Textur
    {
    public:
        //! Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        DLLEXPORT virtual bool updateTextur() override;
        //! Gibt true zurük, wenn updateTextur aufgerufen werden muss
        DLLEXPORT virtual bool brauchtUpdate() const override;
    };

    class DX11Textur : public Textur
    {
    private:
        ID3D11Texture2D* txt;
        ID3D11ShaderResourceView* view;
        ID3D11Device* device;
        ID3D11DeviceContext* context;
        bool renderTarget;

    public:
        DLLEXPORT DX11Textur( ID3D11Device* device, ID3D11DeviceContext* context );
        DLLEXPORT ~DX11Textur();
        //! Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        DLLEXPORT bool updateTextur() override;
        //! Gibt true zurük, wenn updateTextur aufgerufen werden muss
        DLLEXPORT bool brauchtUpdate() const override;
        //! Gibt die verwendtete Shader Resource View zurück
        DLLEXPORT operator ID3D11ShaderResourceView* () const;
        //! Gibt die verwendete Textur zurück
        DLLEXPORT operator ID3D11Texture2D* () const;
        //! specifies that this texture is used as a render target
        DLLEXPORT void setRenderTarget( bool rt );
        //! copy the texture to an image
        DLLEXPORT void copyToImage( Bild* zB );
    };
}