//
// Game.h
//

#pragma once

#include "StepTimer.h"


// A basic game implementation that creates a D3D12 device and
// provides a game loop.
class Game {
public:

	Game();

	// Initialization and management
	void Initialize(IUnknown* window);

	// Basic game loop
	void Tick();

	// Messages
	void OnSuspending();
	void OnResuming();

private:

	void Update(DX::StepTimer const& timer);
	void Render();

	void Clear();
	void Present();

	void CreateDevice();
	void CreateResources();

	void WaitForGpu();
	void MoveToNextFrame();

	// Application state
	IUnknown*                                           m_window;
	int                                                 m_outputWidth;
	int                                                 m_outputHeight;

	// Direct3D Objects
	D3D_FEATURE_LEVEL                                   m_featureLevel;
	static const UINT                                   c_swapBufferCount = 2;
	UINT                                                m_backBufferIndex;
	Microsoft::WRL::ComPtr<ID3D12Device>                m_d3dDevice;
	Microsoft::WRL::ComPtr<ID3D12CommandQueue>          m_commandQueue;
	Microsoft::WRL::ComPtr<ID3D12DescriptorHeap>        m_rtvDescriptorHeap;
	UINT                                                m_rtvDescriptorSize;
	Microsoft::WRL::ComPtr<ID3D12DescriptorHeap>        m_dsvDescriptorHeap;
	UINT                                                m_dsvDescriptorSize;
	Microsoft::WRL::ComPtr<ID3D12CommandAllocator>      m_commandAllocators[c_swapBufferCount];
	Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList>   m_commandList;
	Microsoft::WRL::ComPtr<ID3D12Fence>                 m_fence;
	UINT64                                              m_fenceValues[c_swapBufferCount];
	Microsoft::WRL::Wrappers::Event                     m_fenceEvent;

	// Rendering resources
	Microsoft::WRL::ComPtr<IDXGISwapChain1>             m_swapChain;
	Microsoft::WRL::ComPtr<ID3D12Resource>              m_renderTargets[c_swapBufferCount];
	Microsoft::WRL::ComPtr<ID3D12Resource>              m_depthStencil;

	// Game state
	uint64_t                                            m_frame;
	DX::StepTimer                                       m_timer;
};

// PIX event colors
const DWORD EVT_COLOR_FRAME = PIX_COLOR_INDEX(1);
const DWORD EVT_COLOR_UPDATE = PIX_COLOR_INDEX(2);
const DWORD EVT_COLOR_RENDER = PIX_COLOR_INDEX(3);
