#ifndef RT_DX11_DEVICE_HPP
#define RT_DX11_DEVICE_HPP

#ifndef __cplusplus
#error This file must only be used from C++ code
#endif

#include "renderer/common/renderer_api.h"
#include "runtime/runtime.h"

#include <d3d11_4.h>
#include <dxgi1_5.h>
#include <wrl.h>

// Smart pointer for COM Objects
template <class T> using ComPtr = Microsoft::WRL::ComPtr<T>;

class rt_dx11_device {
  public:
    static RT_INLINE rt_dx11_device *GetInstance() {
        static rt_dx11_device dev;
        return &dev;
    }

    rt_result Initialize(const rt_renderer_init_info *info);
    void Shutdown(void);

  private:
    rt_dx11_device();
    ~rt_dx11_device();
    rt_dx11_device(const rt_dx11_device &)            = delete;
    rt_dx11_device &operator=(const rt_dx11_device &) = delete;

    void GetDisplayInfo(IDXGIOutput *output);

  public:
    static constexpr float VARIABLE_REFRESH_RATE = 0.f;

    float m_monitor_refresh_rate;
    BOOL m_tearing_supported;

  private:
    bool m_is_initialized;
    ComPtr<IDXGIFactory5> m_dxgi_factory;
    ComPtr<IDXGISwapChain1> m_swap_chain;
    ComPtr<IDXGIAdapter3> m_adapter;
    ComPtr<ID3D11DeviceContext3> m_context;
    ComPtr<ID3D11Device5> m_device;
};

#endif
