Updated January 29, 2014, 4:42 pm


#ifndef INC_TEXTUREMNGR_H
#define INC_TEXTUREMNGR_H

#include <map>
#include <string>
#include <d3d9.h>
#include <d3dx9.h>
#include "..\DirectX\RendererTypes.h"

namespace STE
{

        //Texture Manager
	class TextureMngr
	{
	public:
		//
		// constructor
		//
		TextureMngr(Direct3DDevicePtr device);
		

		//
		// Add a texture to texture manager if its already added return a pointer to it
		//
		TexturePtr addTexture(const std::string& fileName,
		UINT mipLevels=D3DX_DEFAULT,
		DWORD filter=D3DX_DEFAULT,
		DWORD mipFilter=D3DX_DEFAULT );

		//
		// Get a pointer to a loaded texture
		//
		TexturePtr getTexture(const std::string& fileName);

		//
		// removes a texture from the texture manager                                                                     
		// if other objects are still holding references to the texture,
		// the texture is not freed until those objects are destroyed
		//
		void removeTexture(const std::string& texture);
		
		//
		// Gets the count of loaded textures                                                                     
		//
		unsigned int getLoadedTextureCount()const{return m_Textures.size();}
		

	private:	
		//private ctor and = operator
		TextureMngr(const TextureMngr&);
		TextureMngr& operator =(const TextureMngr&);
		Direct3DDevicePtr m_Device;

		//
		// map holding all loaded textures
		//
		std::map<std::string,TexturePtr> m_Textures;
		
	};
}

#endif //INC_TEXTUREMNGR_H





#include "DirectX\TextureMngr.h"
#include <assert.h>
#include "STUtil.h"

namespace STE
{


	TextureMngr::TextureMngr(Direct3DDevicePtr device):
	m_Device(device)	
	{
		
	}
	
	void TextureMngr::removeTexture(const std::string& texture)
	{
		std::map<std::string,TexturePtr>::iterator it;
		
		if((it = m_Textures.find(texture)) != m_Textures.end())
		{
			//CComPtr calls release in its destructor if no references are left            
			m_Textures.erase(it);
		}
	}
	

	TexturePtr TextureMngr::addTexture(const std::string& fileName,UINT mipLevels,DWORD filter,DWORD mipFilter )
	{
		assert(m_device!=NULL);

		TexturePtr texture;

		//If same texture is loaded again return a pointer to it
		texture = getTexture(fileName);
		if(texture)
		return texture;

		
		//Load texture
		texture.reset(new Texture);


		if(D3DXCreateTextureFromFileEx(m_Device, 
					fileName.c_str(), 
					D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 
					mipLevels, 0, 
					D3DFMT_UNKNOWN, 
					D3DPOOL_MANAGED, 
					filter, 
					mipFilter, 0, NULL, NULL, &(texture->m_Texture)))
		{
			std::string errorText = "Can not load texture ->" + fileName;
			MSGBOX_ERROR(errorText);
			//reset the shared_ptr and return it
			texture.reset();
			return texture;
		}
		
		//set the name of the texture
		texture->m_Name = fileName;
		D3DSURFACE_DESC desc;
		texture->m_Texture->GetLevelDesc(0,&desc);
		
		texture->m_Width = desc.Width;
		texture->m_Height = desc.Height;
		//Add it to map structure
		m_Textures[fileName] = texture;
		
		return texture;
	}


	TexturePtr TextureMngr::getTexture(const std::string &fileName)
	{
		
		std::map<std::string,TexturePtr>::iterator it;
		TexturePtr texture;
		if((it = m_Textures.find(fileName)) != m_Textures.end())
		{
			texture = it->second;
		}
		
		return texture;
	}
}