#pragma once
#include "EmberCLPch.h"
/// 
/// OpenCLInfo class.
/// 
namespace EmberCLns
{
/// 
/// Keeps information about all valid OpenCL devices on this system.
/// Devices which do not successfully create a test command queue are not
/// added to the list.
/// The pattern is singleton, so there is only one instance per program,
/// retreivable by reference via the Instance() function.
/// This class derives from EmberReport, so the caller is able
/// to retrieve a text dump of error information if any errors occur.
/// 
class EMBERCL_API OpenCLInfo : public EmberReport
{
public:
	const vector& Platforms() const;
	const string& PlatformName(size_t platform) const;
	const vector& PlatformNames() const;
	const vector>& Devices() const;
	const string& DeviceName(size_t platform, size_t device) const;
	const vector>& DeviceIndices() const;
	const vector& AllDeviceNames() const;
	const vector& DeviceNames(size_t platform) const;
	size_t TotalDeviceIndex(size_t platform, size_t device) const;
	string DumpInfo() const;
	bool Ok() const;
	bool CreateContext(const cl::Platform& platform, cl::Context& context, bool shared);
	bool CheckCL(cl_int err, const char* name);
	string ErrorToStringCL(cl_int err);
	/// 
	/// Get device information for the specified field.
	/// Template argument expected to be cl_ulong, cl_uint or cl_int;
	/// 
	/// The index platform of the platform to use
	/// The index device of the device to use
	/// The device field/feature to query
	/// The value of the field
	template
	T GetInfo(size_t platform, size_t device, cl_device_info name) const
	{
		T val = T();
		if (platform < m_Devices.size() && device < m_Devices[platform].size())
			m_Devices[platform][device].getInfo(name, &val);
		return val;
	}
	SINGLETON_INSTANCE_DECL(OpenCLInfo);
private:
	OpenCLInfo();
	bool m_Init;
	vector m_Platforms;
	vector> m_Devices;
	vector m_PlatformNames;
	vector> m_DeviceNames;
	vector> m_DeviceIndices;
	vector m_AllDeviceNames;
};
}