#pragma once

// ビットマップに関するクラス

// code by Kita-C(c) 2000.1.27
#include <windows.h>
#include <crtdbg.h>
#include <string>

using std::string;

	// ウィンドウズビットマップとコンパチ


	// デフォルトのカラービット値
	const unsigned int DefaultColorBit = 24;

	class CBitMap
	{
	private:
		unsigned char	*m_ImageData;	// カラーデータへのポインタ
		unsigned int	m_ImageSize;			// サイズ
		unsigned char	*m_Palette;		// パレットへのポインタ	RGBOの順. Oはただの0パディング4Byteで1パレット
		unsigned int	m_PaletteSize;
		unsigned int	m_ColorBit;		// カラービット数
		unsigned int	m_Width;		// 幅
		unsigned int	m_Height;		// 高さ
		unsigned int	m_Pitch;		// ピッチ

		// バッファの削除を行うヘルパ関数
		inline DeleteBuffer( unsigned char *&buf)
		{
			delete[] buf;
			buf = NULL;
		}
		// ピッチの計算
		inline int CalcPitch( int Width, int Heightint, int BitCount)
		{
			switch( BitCount)
			{	//カラーBitごとのバイト境界も考慮
			case 1:	return ((( Width + 7) & ~7) / 8 + 3) & ~3;
			case 4:	return ((( Width + 1) & ~1) / 2 + 3) & ~3;
			case 8:	return ( Width + 3) & ~3;
			case 16: return ( Width * 2 + 3) & ~3;
			case 24: return ( Width * 3 + 3) & ~3;
			case 32: return ( Width * 4 + 3) & ~3;
			}
			_ASSERT( 0);
			return 0;
		}
	public:
		// 空のビットマップを作成する
		// カラービットはデフォルト
		explicit CBitMap()
			: m_ImageData( NULL), m_ImageSize( 0), m_Palette( 0), m_PaletteSize( 0),
			m_ColorBit( DefaultColorBit), m_Width( 0), m_Height( 0), m_Pitch( 0) {};

		explicit CBitMap( const string &filename)
			: m_ImageData( NULL), m_ImageSize( 0), m_Palette( 0), m_PaletteSize( 0),
			m_ColorBit( DefaultColorBit), m_Width( 0), m_Height( 0), m_Pitch( 0)
		{ LoadBitmapFile( filename);}

		// メモリからクラスを作成する
		explicit CBitMap( const BITMAPINFO *bmpinfo, const unsigned char *image, const int imagesize);

		// コピーコンストラクタ
		CBitMap( const CBitMap &rhs)
		{
			if ( this == &rhs)
				return;
			// バッファの削除
			DeleteBuffer( m_ImageData);
			DeleteBuffer( m_Palette);
			// 格定数のコピー
			m_ImageSize = rhs.m_ImageSize;
			m_PaletteSize = rhs.m_PaletteSize;
			m_ColorBit = rhs.m_ColorBit;
			m_Width = rhs.m_Width;
			m_Height = rhs.m_Height;
			m_Pitch = rhs.m_Pitch;
			m_ImageData = new unsigned char[ m_ImageSize];
			m_Palette = new unsigned char[ m_PaletteSize];
			memcpy( m_ImageData, rhs.m_ImageData, m_ImageSize);
			memcpy( m_Palette, rhs.m_Palette, m_PaletteSize);
		}
		~CBitMap()
		{
			DeleteBuffer( m_ImageData);
			DeleteBuffer( m_Palette);
		}
//----------------------------------------------------------------------
		// 画像データのリサイズを行う
		// 画像データの拡大縮小はしないただ単に内部バッファのサイズを再確保するだけ
		void Resize( unsigned int width, unsigned int height)
		{
			int Pitch = CalcPitch( width, height, m_ColorBit);
			unsigned char *tmp = new unsigned char[ height * Pitch];
			int CopyHeight = height < m_Height ? height: m_Height;
			int CopyWidth  = width  < m_Width  ? width : m_Width;

			// 画像のコピー
			for ( int i = 0; i < CopyHeight; ++i)
				memcpy( tmp + Pitch, m_ImageData + m_Pitch, CopyWidth);
			DeleteBuffer( m_ImageData);
			m_ImageData = tmp;
			m_Width = width;
			m_Height = height;
			m_Pitch = Pitch;
			m_ImageSize = m_Pitch * m_Height;
		}

		// ファイルパスからビットマップを開く
		bool LoadBitmapFile( const string &filename);
		// ファイルパスにビットマップを保存
		bool SaveBitmapFile( const string &filename);

		// パレットのバイト数を返す
		int GetPaletteSize()
		{
			return m_PaletteSize;
		}
		// パレットデータを取得する
		void GetPaletteData( unsigned char *dest)
		{
			memcpy( dest, m_Palette, m_PaletteSize);
		}
		// 画像データのバイト数を返す
		int GetImageSize()
		{
			return m_ImageSize;
		}
		// 画像データのコピーを取得する
		// 引数に渡したメモリにコピーして返却する
		void GetImageData( unsigned char *dest)
		{
			memcpy( dest, m_ImageData, m_ImageSize);
		}

		int GetColorBit() { return m_ColorBit;}
		int GetWidth() { return m_Width;}
		int GetHeight() { return m_Height;}
		int GetPitch() { return m_Pitch;}
	};
