#pragma once

#include <wrl.h>
#include <d3d11on12.h>
#include <dxgi1_6.h>

#include <memory>

class DirectX2dInterface;

struct ID3D12Device;
struct IDXGIFactory7;
struct IDXGIAdapter1;
struct ID3D12CommandQueue;

struct ID3D11DeviceContext;
struct ID3D11On12Device;

class DirectXInterface
{
public:
	DirectXInterface();

	IDXGIFactory7* getDxgiFactory() const;
	ID3D12Device* getD3dDevice() const;
	ID3D12CommandQueue* getCommandQueue() const;

	ID3D11On12Device* get11On12Device() const;
	ID3D11DeviceContext* getD3d11DeviceContext() const;

	DirectX2dInterface* getD2dInterface() const;

	void initialize();
	bool isValid() const;

private:
	bool createD3dFactory();
	bool createD3dDevice(IDXGIAdapter1* ppAdapter);
	bool createCommandQueue();

	void getHardwareAdapter(IDXGIAdapter1** ppAdapter);

	bool initializeD11on12();

	bool mIsValid{ false };

	Microsoft::WRL::ComPtr<IDXGIFactory7> mDxgiFactory;
	Microsoft::WRL::ComPtr<ID3D12Device> mD3dDevice;
	Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;

	Microsoft::WRL::ComPtr<ID3D11DeviceContext> mD3d11DeviceContext;
	Microsoft::WRL::ComPtr<ID3D11On12Device> mD3d11On12Device;

	std::unique_ptr<DirectX2dInterface> mD2dInterface;
};