//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2007)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: loadableTexture_common.inl
//      Краткое описание: текстура, загружаемая из файла
//

namespace rs_private
{
	inline rs::DSEFORMAT LoadableTexture::_tryToSetPixelFormat(const bool is_signed, const unsigned int bpp)
	{
		// D3DFMT_A2B10G10R10
		if(!is_signed && masks.amask == 0xc0000000 && masks.bmask == 0x000003ff && masks.gmask == 0x000FFC00 && masks.rmask == 0x3FF00000)
			return rs::DFMT_R10G10B10A2_UNORM;
		// D3DFMT_A8
		if(!is_signed && bpp == 8 && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0 && masks.rmask == 0)
			return rs::DFMT_A8_UNORM;
		// D3DFMT_L8
		if(!is_signed && bpp == 8 && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0 && masks.rmask == 255)
			return rs::DFMT_R8_UNORM;
		// D3DFMT_L16
		if(!is_signed && bpp == 16 && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0 && masks.rmask == 0x0000ffff)
			return rs::DFMT_R16_UNORM;
		// D3DFMT_V8U8
		if(is_signed && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0x0000ff00 && masks.rmask == 0x000000ff)
			return rs::DFMT_R8G8_SNORM;
		// D3DFMT_Q8W8V8U8
		if(is_signed && masks.amask == 0xff000000 && masks.bmask == 0x00ff0000 && masks.gmask == 0x0000ff00 && masks.rmask == 0x000000ff)
			return rs::DFMT_R8G8B8A8_SNORM;
		// D3DFMT_V16U16
		if(is_signed && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0xffff0000 && masks.rmask == 0x0000ffff)
			return rs::DFMT_R16G16_SNORM;
		// D3DFMT_G16R16
		if(!is_signed && masks.amask == 0 && masks.bmask == 0 && masks.gmask == 0xffff0000 && masks.rmask == 0x0000ffff)
			return rs::DFMT_R16G16_UNORM;
		return _tryToSetSpecificPlatfromPixelFormat(is_signed, bpp);
	}

	inline rs::DSEFORMAT LoadableTexture::_tryToSetPixelFormat(const unsigned int fourcc)
	{
		switch(fourcc)
		{
		case D3DFMT_DXT1:
			{
				return rs::DFMT_BC1_UNORM;
			};break;
		case D3DFMT_DXT3:
			{
				return rs::DFMT_BC2_UNORM;
			};break;
		case D3DFMT_DXT5:
			{
				return rs::DFMT_BC3_UNORM;
			};break;
		case D3DFMT_A16B16G16R16:
			{
				return rs::DFMT_R16G16B16A16_UNORM;
			};break;
		case D3DFMT_CxV8U8:
			{
				return rs::DFMT_R8G8_SNORM;
			};break;
		case D3DFMT_Q16W16V16U16:
			{
				return rs::DFMT_R16G16B16A16_SNORM;
			};break;
		case D3DFMT_G8R8_G8B8:
			{
				return rs::DFMT_R8G8_B8G8_UNORM;
			};break;
		case D3DFMT_R8G8_B8G8:
			{
				return rs::DFMT_G8R8_G8B8_UNORM;
			};break;
		case D3DFMT_R16F:
			{
				return rs::DFMT_R16_FLOAT;
			};break;
		case D3DFMT_G16R16F:
			{
				return rs::DFMT_R16G16_FLOAT;
			};break;
		case D3DFMT_A16B16G16R16F:
			{
				return rs::DFMT_R16G16B16A16_FLOAT;
			};break;
		case D3DFMT_R32F:
			{
				return rs::DFMT_R32_FLOAT;
			};break;
		case D3DFMT_G32R32F:
			{
				return rs::DFMT_R32G32_FLOAT;
			};break;
		case D3DFMT_A32B32G32R32F:
			{
				return rs::DFMT_R32G32B32A32_FLOAT;
			};break;
		};
		return rs::DFMT_UNKNOWN;
	};

	inline void _reduceTmpValues(unsigned int& tmp_width, unsigned int& tmp_height, unsigned int& tmp_depth, const unsigned int i)
	{
		tmp_width >>= i;
		if(tmp_width == 0)
			tmp_width = 1;
		tmp_height >>= i;
		if(tmp_height == 0)
			tmp_height = 1;
		tmp_depth >>= i;
		if(tmp_depth == 0)
			tmp_depth = 1;
	};

	inline unsigned int _getShiftAndSize(const unsigned int mask, unsigned int& size)
	{
		bool find_start = false;
		unsigned int shift;
		// if we have not this mask at all then shift = 0 and we don't need to factor so size will be
		// set 100 > 8
		size = 100;
		for(unsigned int i = 0; i < 32; ++i)
			if((mask >> i) % 2 == 1)
			{
				if(!find_start)
				{
					shift = i;
					find_start = true;
				};
			}
			else
				if(find_start)
				{
					size = i - shift;
					return shift;
				};
		if(find_start)
		{
			size = 32 - shift;
			return shift;
		};
		return 0;
	};

	inline bool setCorrectSizeToDXT(unsigned int& width, unsigned int& height)
	{
		unsigned int wd = width % 4;
		unsigned int hd = height % 4;
		bool need_to_change = false;
		if(wd)
		{
			width += 4 - wd;
			need_to_change = true;
		};
		if(hd)
		{
			height += 4 - hd;
			need_to_change = true;
		};
		return need_to_change;
	};
};