#pragma once

#include "Punkt.h"

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

struct ID3D12Device2;
struct D3D12_RESOURCE_DESC;
struct ID3D12Resource;
struct ID3D12GraphicsCommandList2;

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
    {
    protected:
        Bild *bild;
        Punkt lastGr;
        int id;
        int ref;

    public:
        // Konstruktor
        __declspec( dllexport ) Textur();
        // Destruktor
        __declspec( dllexport ) virtual ~Textur();
        // Setzt einen Zeiger auf das Bild, welches die Textur enth�lt
        //  b: Der Zeiger auf das Bild
        __declspec( dllexport ) void setBildZ( Bild *b );
        // Setzt das Bild welches die Textur enth�lt, indem es kopiert wird
        //  b: Das Bild, was kopiert werden soll
        __declspec( dllexport ) void setBild( Bild *b );
        // Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        __declspec( dllexport ) virtual bool updateTextur() = 0;
        // Gibt true zur�k, wenn updateTextur aufgerufen werden muss
        __declspec( dllexport ) virtual bool brauchtUpdate() const = 0;
        // Gibt einen Zeiger auf das Bild zur�ck
        __declspec( dllexport ) Bild *getBild() const;
        // Gibt einen Zeiger auf das Bild ohne erh�hten Reference Counter zur�ck
        __declspec( dllexport ) Bild *zBild() const;
        // Gibt die Id der Textur zur�ck, wenn sie in einer TexturList registriert wurde. (siehe Framework::zTexturRegister())
        __declspec( dllexport ) int getId() const;
        // Erh�ht den Reference Counting Z�hler.
        //  return: this.
        __declspec( dllexport ) Textur *getThis();
        // Verringert den Reference Counting Z�hler. Wenn der Z�hler 0 erreicht, wird das Zeichnung automatisch gel�scht.
        //  return: 0.
        __declspec( dllexport ) Textur *release();

        friend TexturList;
    };

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

    public:
        __declspec( dllexport ) DX11Textur( ID3D11Device *device, ID3D11DeviceContext *context );
        __declspec( dllexport ) ~DX11Textur();
        // Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        __declspec( dllexport ) bool updateTextur() override;
        // Gibt true zur�k, wenn updateTextur aufgerufen werden muss
        __declspec( dllexport ) bool brauchtUpdate() const override;
        // Gibt die verwendtete Shader Resource View zur�ck
        __declspec( dllexport ) operator ID3D11ShaderResourceView *( ) const;
    };

    class DX12Textur : public Textur
    {
    private:
        ID3D12Resource *buffer;
        ID3D12Resource *intermediate;
        ID3D12Device2 *device;
        DX12CopyCommandQueue *copy;
        DX12DirectCommandQueue *direct;
        bool shaderResource;

    public:
        __declspec( dllexport ) DX12Textur( ID3D12Device2 *device, DX12CopyCommandQueue *copy, DX12DirectCommandQueue *direct );
        __declspec( dllexport ) ~DX12Textur();
        // Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
        __declspec( dllexport ) bool updateTextur() override;
        // Gibt true zur�k, wenn updateTextur aufgerufen werden muss
        __declspec( dllexport ) bool brauchtUpdate() const override;
        // Gibt die DX12 Resource zur�ck
        __declspec( dllexport ) ID3D12Resource *getResource();
    };
}