#pragma once

#include <d3d11_4.h>
#include <wrl.h>
#include <GL\glew.h>
#include <GL\GL.h>

#include <map>
#include <memory>

#include "CameraRenderingResources.hpp"

using namespace Microsoft::WRL;

#define LEFT_EYE  0u
#define RIGHT_EYE 1u

class Dx11OglRenderer
{
public:
	~Dx11OglRenderer();

	bool init(LUID adapterId, unsigned int eyeWidth, unsigned int eyeHeight);
	void getGlTextures(GLuint& left, GLuint& right);

	bool createOrRecreateCameraData(ComPtr<ID3D11Texture2D> backbufferTexture, unsigned int Id);
	bool initSharedTexturesAfterLoadingCameraData();

	ComPtr<ID3D11Device> getDevice() const { return _device; }

	void getEyeWidthHeight(unsigned int& width, unsigned int& height) const;

	void lockTexturesForGL();
	void unlockTexturesFromGL();
	void copyTextures();
	void removeCameraByID(unsigned int id);

protected:
	bool _createDeviceFromAdapterLuid(LUID adapterID);
	bool _initGl();
	bool _initSharedTexturesLike(ComPtr<ID3D11Texture2D> tex);
	bool _initOglDxInterop();
	bool _hookSharedTextures();

	void _copyTextureToRendertarget(ComPtr<ID3D11Texture2D> tex, unsigned int eye);

private:

	ComPtr<ID3D11Device>		_device  = nullptr;
	HANDLE						_glDevice = nullptr;
	ComPtr<ID3D11DeviceContext> _context = nullptr;
	
	std::map<unsigned int, std::shared_ptr<CameraRenderingResources>> _cameras;
	
	ComPtr<ID3D11Texture2D> _oglSharedStereoColorBufferLeft = nullptr;
	HANDLE					_shrStereoColorBufferHandleLeft = nullptr;
	GLuint					_shrStereoColorBufferLeft = 0;

	ComPtr<ID3D11Texture2D> _oglSharedStereoColorBufferRight = nullptr;
	HANDLE					_shrStereoColorBufferHandleRight = nullptr;
	GLuint					_shrStereoColorBufferRight = 0;

	unsigned int _eyeWidth = 0;
	unsigned int _eyeHeight = 0;
};