#pragma once

#include "dllinterface.h"
#include "..\Utilities\util.h"
#include "..\Utilities\list.h"
#include "..\Utilities\XString.h"
#include "dxtexture.h"
#include "rendertarget.h"

class DeviceStateManager;
class DXViewPort;

class DXFUNCTIONS_API TextureManager
{
	friend DXSurface;
	friend DXTexture;
	friend RenderSurface;
	friend RenderTarget;
	friend RenderTexture;
	friend CubeRenderTexture;
	friend OffscreenRenderTexture;

	DeviceStateManager* const m_Device;
	LList<DXSurface> m_Textures;
	LList<RenderSurface> m_RenderSurfaces;
	
	void Release(DXSurface* const t);
	void Release(RenderSurface* const rs);

	unsigned m_ManagedMemory;
	unsigned m_DeviceMemory;
	unsigned m_SystemMemory;

	void MemoryAllocated(const unsigned bytes, const POOL pool);
	void MemoryReleased(const unsigned bytes, const POOL pool);

protected:
	friend DeviceStateManager;
	friend DXViewPort;
	
	TextureManager(DeviceStateManager* const device);
	~TextureManager(void);

	ViewPortRenderTexture* CreateViewPortRenderTexture(DXViewPort* const vp, const FORMAT format, const float scale);

	void Invalidate(void);
	void Restore(void);
public:

	DXTexture* CreateTexture(const unsigned xl, const unsigned yl, const unsigned levels, const unsigned usage, const FORMAT format, const POOL pool);
	DXTexture* CreateTexture(const XString& filename, const UINT xl, const UINT yl, const unsigned levels, const unsigned usage, const FORMAT format, const POOL pool);
	DXTexture* CreateTexture(const XString& filename, const  FORMAT format, const POOL pool);
	DXTexture* CreateTextureCopy(DXTexture* const tex, const POOL pool);

	DXCubeTexture* CreateCubeTexture(const unsigned edgelength, const unsigned levels, const unsigned usage, const FORMAT format, const POOL pool);
	DXCubeTexture* CreateCubeTexture(const XString& filename, const unsigned edgelength, const unsigned levels, const unsigned usage, const FORMAT format, const POOL pool);
	DXCubeTexture* CreateCubeTexture(const XString& filename, const  FORMAT format, const POOL pool);

	OffscreenRenderTexture* CreateOffscreenRenderTexture(const unsigned xl, const unsigned yl, const FORMAT format, const bool autolock = true, const bool autorestore = true, const bool autoupdate = true);
	DepthStencilBuffer* CreateDepthStencilBuffer(const unsigned xl, const unsigned yl, const FORMAT format);
	DepthStencilTexture* CreateDepthStencilTexture(const unsigned xl, const unsigned yl, const FORMAT format);
	RenderTexture* CreateRenderTexture(const unsigned xl, const unsigned yl, const FORMAT format);
	CubeRenderTexture* CreateCubeRenderTexture(const unsigned edgelength, const FORMAT format);
	
	DeviceStateManager* GetDevice(void){return m_Device;}

	unsigned GetUsedDeviceMemory(void) const { return m_DeviceMemory; }
	unsigned GetUsedManagedMemory(void) const { return m_ManagedMemory; }
	unsigned GetUsedSystemMemory(void) const { return m_SystemMemory; }

	void PreLoad(void);
};