#pragma once

#include <Core/Common/NonNullPtr.h>
#include <Core/Common/NonNullPtr.h>
#include <Graphics/GraphicsBuffer.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>

namespace Juliet
{
    struct CommandList;
    struct GPUDriver;
} // namespace Juliet
namespace Juliet::D3D12
{
    struct D3D12Buffer
    {
        Internal::D3D12Descriptor Descriptor;
        ID3D12Resource*           Handle;
        D3D12_RESOURCE_STATES     CurrentState;
        size_t                    Size;
    };

    extern GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GPUDriver> driver, size_t size, size_t stride, BufferUsage usage, bool isDynamic);
    extern void            DestroyGraphicsBuffer(NonNullPtr<GraphicsBuffer> buffer);

    extern GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GPUDriver> driver, size_t size, TransferBufferUsage usage);
    extern void DestroyGraphicsTransferBuffer(NonNullPtr<GraphicsTransferBuffer> buffer);

    extern void*  MapBuffer(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
    extern void   UnmapBuffer(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsTransferBuffer> buffer);
    extern uint32 GetDescriptorIndex(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsBuffer> buffer);
    extern void   CopyBuffer(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> dst,
                             NonNullPtr<GraphicsTransferBuffer> src, size_t size, size_t dstOffset, size_t srcOffset);
    extern void   TransitionBufferToReadable(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsBuffer> buffer);
} // namespace Juliet::D3D12
