#pragma once

namespace lgr
{


class GdiBmpIO
{
public:
	//! 画像フォーマットを表す列挙態
	enum ImageFormat
	{
		IMGFMT_NONE , // 不明なフォーマット
		IMGFMT_BMP  , // ビットマップ
		IMGFMT_PNG  , // PNG
		IMGFMT_JPG  , // JPEG
	};


public:
	static bool Save(Gdiplus::Bitmap& bmp, const WCHAR* filename);
	static bool Save(Gdiplus::Bitmap& bmp, const WCHAR* filename, const ImageFormat format_typeformat_type);
	static bool Save(Gdiplus::Bitmap& bmp, const WCHAR* filename, const WCHAR* mime_type);

	static bool GetEncoderClsid(const WCHAR* mime_type, CLSID& clsid);
	static const WCHAR* GetMIMETypeString(const ImageFormat& image_format);
};



inline bool GdiBmpIO::Save(Gdiplus::Bitmap& bmp, const WCHAR* filename)
{
	return Save( bmp , filename , GetMIMETypeString(IMGFMT_PNG) );
}

inline bool GdiBmpIO::Save(Gdiplus::Bitmap& bmp, const WCHAR* filename, const ImageFormat format_type)
{
	return Save( bmp , filename , GetMIMETypeString(format_type) );
}

inline bool GdiBmpIO::Save(Gdiplus::Bitmap& bmp, const WCHAR* filename, const WCHAR* mime_type)
{
	CLSID clsid;
	if( !GetEncoderClsid( mime_type , clsid ) )
		return false;

	if( bmp.Save( filename , &clsid ) != Gdiplus::Ok )
		return false;
}

inline bool GdiBmpIO::GetEncoderClsid(const WCHAR* mime_type, CLSID& clsid)
{
	using namespace Gdiplus;

	UINT num = 0 , size = 0;

	GetImageEncodersSize(&num, &size);
	if(size == 0)
		return false;

	std::vector<ImageCodecInfo> pImageCodecInfo(size);

	bool bEncodeFound = false;

	GetImageEncoders(num, size, &pImageCodecInfo[0]);
	for(UINT n=0; n<num; ++n)
	{
		if( wcscmp(pImageCodecInfo[n].MimeType, mime_type) == 0 )
		{
			clsid = pImageCodecInfo[n].Clsid;
			bEncodeFound = true;
			break;
		}
	}

	return bEncodeFound;
}


//! 指定したフォーマットに対するMIMEの文字列を返す
inline const WCHAR* GdiBmpIO::GetMIMETypeString( const GdiBmpIO::ImageFormat& image_format )
{
	switch( image_format )
	{
	case IMGFMT_BMP : return L"image/bmp";
	case IMGFMT_PNG : return L"image/png";
	case IMGFMT_JPG : return L"image/jpeg";
	default:
		break;
	}

	_ASSERT(false);
	return L"";
}


}
