//////////////////////////////////////////
// IconView_DLL.h
// Copyright (c) 03/01/2021 by BCCSkelton
//////////////////////////////////////////
//BCCSkeltonのヘッダー−これに必要なヘッダーが入っている
#include	"BCCSkelton.h"
#include	"CICON.h"
//リソースIDのヘッダー
#include	"ResIconView_DLL.h"


///////////////////////////////////////////
// CDLGクラスからICONVIEW_DLGクラスを派生
///////////////////////////////////////////
class ICONVIEW_DLG : public CDLG {
public:
	//メンバー変数
	HINSTANCE 	m_hInstance;
	CICON m_Icon;
	char m_FileName[MAX_PATH];
	int m_ImageType;
	//ウィンドウメッセージ関数
	bool OnInit(WPARAM, LPARAM);
	bool OnNotify(WPARAM, LPARAM);
	//コントロール関連関数
	bool OnIdok();
	//ユーザー定義関数
	bool SetListView();
	bool ShowIconData(int);
};

////////////////////////////////////////////////////////////////////////////////
// ICONVIEW_DLGクラスダイアログ変数の生成とそのコールバック関数（マクロ）を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////////
//ICONVIEW_DLGクラスのインスタンス
ICONVIEW_DLG iconview_dlg;
//コールバック関数マクロ
BEGIN_MODALDLGMSG(iconview_dlgProc, iconview_dlg)	//第1引数がコールバック関数の名前
	ON_COMMAND(iconview_dlg, IDOK, OnIdok())
END_DLGMSG

///////////////////////////////////////////
// ICONVIEW_DLGクラスの関数定義
///////////////////////////////////////////
//コントロール関数
bool ICONVIEW_DLG::OnInit(WPARAM wParam, LPARAM lParam) {

	//コモンコントロールの初期化
	InitCommonControls();
	//リストビュー拡張スタイルの設定
	INITCOMMONCONTROLSEX ic;
	ic.dwSize = sizeof(ic);
	ic.dwICC = ICC_LISTVIEW_CLASSES;
	InitCommonControlsEx(&ic);
	DWORD lvStyle = SendItemMsg(IDC_LISTVIEW, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
	lvStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES;
	SendItemMsg(IDC_LISTVIEW, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES, lvStyle);
	//リストビューの初期化
	char* column[11] = {"bWidth", "bHeight", "bColorCount", "dwBitCount",
						"dwBytesInRes", "dwImageOffset", "biWidth",
						"biHeight", "biPlanes", "biBitCount", "biSizeImage"};
	int w[11] = {60, 60, 80, 80, 90, 100, 60, 60, 60, 80, 80};
	LV_COLUMN lvcol;
	lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
	lvcol.fmt = LVCFMT_LEFT;
	for(int i = 0; i < 11; i++) {
		lvcol.cx = w[i];
		lvcol.pszText = column[i];
		lvcol.iSubItem = i;
		SendItemMsg(IDC_LISTVIEW, LVM_INSERTCOLUMN, i, (LPARAM)&lvcol);
	}
	//CICONインスタンスの初期化
	m_Icon.Init();
	m_Icon.Clear();
	m_Icon.SetWindow(m_hWnd);
	//ファイル読込処理
	char* errmsg;
	if(!m_Icon.Load_Icon(m_FileName, m_ImageType, TRUE)) {
		if(m_ImageType == IMAGE_ICON)			//Iconファイル
			errmsg = "アイコンファイルを読み込めませんでした";
		else if(m_ImageType == IMAGE_CURSOR)	//Cursorファイル
			errmsg = "カーソルファイルを読み込めませんでした";
		MessageBox(m_hWnd, errmsg, "エラー", MB_OK | MB_ICONSTOP);
		return FALSE;
	}
	//アイコンを表示
	SendItemMsg(IDC_ICONVIEW, STM_SETIMAGE, IMAGE_ICON, (LPARAM)m_Icon.GetIcon());
	//リストビューに登録ビットマップ情報を表示
	SetListView();
 
	return TRUE;
}

bool ICONVIEW_DLG::OnNotify(WPARAM wParam, LPARAM lParam) {

	if((int)wParam == IDC_LISTVIEW) {	//リストビューからのメッセージ
		if(((LPNMLISTVIEW)lParam)->hdr.code == NM_CLICK){
			int n = ListView_GetNextItem(GetDlgItem(m_hWnd, IDC_LISTVIEW), -1,
										LVNI_ALL | LVIS_SELECTED);
			if(n== -1) {
				MessageBox(m_hWnd, "選択されていません", "エラー", MB_OK | MB_ICONERROR);
				return FALSE;
			}
			//ビットマップを表示
			SendItemMsg(IDC_BMPVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_Icon.GetColBmp(n));
			SendItemMsg(IDC_MSKVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_Icon.GetMaskBmp(n));
			//エディットボックスの表示
			ShowIconData(n);
		}
		return TRUE;
	}
	return FALSE;
}

bool ICONVIEW_DLG::OnIdok() {

	int n = ListView_GetNextItem(GetDlgItem(m_hWnd, IDC_LISTVIEW), -1,
								LVNI_ALL | LVIS_SELECTED);
	if(n== -1) {
		MessageBox(m_hWnd, "ビットマップが選択されていません", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
    else {
		//複数ビットマップファイルを破壊しないよう警告する
		char str[MAX_PATH];
		wsprintf(str, "構成ビットマップ%d個のうち、%d番目が選択されました。\r\n"\
				"このままで上書きや同ファイル名で保存すると、他のビットマップ"\
				"が失われてしまいますので必ず別ファイル名で保存してください。",
				m_Icon.GetCount(), n + 1);
		MessageBox(m_hWnd, str, "警告", MB_OK | MB_ICONEXCLAMATION);
		EndModal(n);
		return TRUE;
	}
}

///////////////////
//ユーザー定義関数
///////////////////
bool ICONVIEW_DLG::SetListView() {

	//リストビューへのデータ登録
	HWND hLV = GetDlgItem(m_hWnd, IDC_LISTVIEW);
	SendMessage(hLV, LVM_DELETEALLITEMS, 0, 0);	//リストビューの全データ抹消
	int IconNum = m_Icon.GetCount();
	LPICONDIRENTRY lpIde;
	PBITMAPINFOHEADER pBmi;
	LV_ITEM item;
	CSTR str;
	for(int i = 0; i < IconNum; i++) {
		//ICONDIRENTRYの情報を取得する
		m_Icon.GetIDEntry(i, &lpIde);
		//リスト先頭列の設定（幅）
		item.mask = LVIF_TEXT;
		str = lpIde->bWidth;
		item.pszText = str.ToChar();
		item.iItem = i;
		item.iSubItem = 0;
		SendMessage(hLV, LVM_INSERTITEM, 0, (LPARAM)&item);
		//第２列の設定（高さ）
		str = lpIde->bHeight;
		item.pszText = str.ToChar();
		item.iSubItem = 1;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第３列の設定（色数）0=256色
		str = lpIde->bColorCount;
		item.pszText = str.ToChar();
		item.iSubItem = 2;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第４列の設定（色数）BitCount
		str = lpIde->wBitCount;
		item.pszText = str.ToChar();
		item.iSubItem = 3;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第５列の設定（画像データ部の大きさ）
		str = lpIde->dwBytesInRes;
		item.pszText = str.ToChar();
		item.iSubItem = 4;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第６列の設定（ファイル先頭から画像データまでのオフセット）
		str = lpIde->dwImageOffset;
		item.pszText = str.ToChar();
		item.iSubItem = 5;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//BITMAPINFOHEADERの情報を取得する
		m_Icon.GetBmpInfo(i, &pBmi);
		//第７列の設定（画像の幅）
		str = pBmi->biWidth;
		item.pszText = str.ToChar();
		item.iSubItem = 6;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第８列の設定（画像の高さ×2 の値）
		str = pBmi->biHeight;
		item.pszText = str.ToChar();
		item.iSubItem = 7;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第９列の設定（プレーンの数）
		str = pBmi->biPlanes;
		item.pszText = str.ToChar();
		item.iSubItem = 8;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第10列の設定（ピクセル当りの色数・1, 4, 8(, 16), 24(, 32)のいずれか）
		str = pBmi->biBitCount;
		item.pszText = str.ToChar();
		item.iSubItem = 9;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
		//第11列の設定（表示データ部とマスクデータ部の合計サイズ）
		str = pBmi->biSizeImage;
		item.pszText = str.ToChar();
		item.iSubItem = 10;
		SendMessage(hLV, LVM_SETITEM, 0, (LPARAM)&item);
	}
}

bool ICONVIEW_DLG::ShowIconData(int i) {

	PBITMAPINFOHEADER Bmi;
	LPICONDIRENTRY IDE;
	m_Icon.GetBmpInfo(i, &Bmi);
	m_Icon.GetIDEntry(i, &IDE);
	CSTR IconInfo = "【ICONDIR】		： 6bytes\r\n";
	//アイコン基本情報の表示
	if(m_ImageType == IMAGE_ICON)
		IconInfo = IconInfo + "ファイル種類		： ICON\r\n";
	else if(m_ImageType == IMAGE_CURSOR)
		IconInfo = IconInfo + "ファイル種類		： CURSOR\r\n";
	else
		return FALSE;
	IconInfo = IconInfo + "画像数			： ";
	IconInfo = IconInfo + m_Icon.GetCount();
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "【ICONDIRENTRY】		： 16bytes\r\n";
	IconInfo = IconInfo + "イメージ幅			： ";
	IconInfo = IconInfo + IDE->bWidth;
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "イメージ高			： ";
	IconInfo = IconInfo + IDE->bHeight;
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "色数			： ";
	IconInfo = IconInfo + IDE->bColorCount;
	IconInfo = IconInfo + " (wBitCount = ";
	IconInfo = IconInfo + IDE->wBitCount;
	IconInfo = IconInfo + ")\r\n";
	IconInfo = IconInfo + "ファイル先頭からのオフセット	： ";
	IconInfo = IconInfo + IDE->dwImageOffset;
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "画像データ部サイズ (Bytes)	： ";
	IconInfo = IconInfo + IDE->dwBytesInRes;
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "【BIMAPINFOHEADER】	： 40bytes\r\n";
	IconInfo = IconInfo + "１画素当たりのビット数		： ";
	IconInfo = IconInfo + Bmi->biBitCount;
	IconInfo = IconInfo + "\r\n";
	IconInfo = IconInfo + "(ＲＧＢＱＵＡＤテーブル)	： ";
	if(Bmi->biBitCount > 8)
		IconInfo = IconInfo + "0";
	else
		IconInfo = IconInfo + 4 * (1 << Bmi->biBitCount);
	IconInfo = IconInfo	 + "bytes (4 x 2 ^";
	IconInfo = IconInfo + Bmi->biBitCount;
	IconInfo = IconInfo	 + ")\r\n";
	IconInfo = IconInfo + "(カラービット hbmColor)	： ";
	IconInfo = IconInfo + ((Bmi->biBitCount * Bmi->biWidth + 31) / 32) * 4 * abs(Bmi->biHeight / 2);
	IconInfo = IconInfo + "bytes\r\n";
	IconInfo = IconInfo + "(マスクビット hbmMask)	： ";
	IconInfo = IconInfo + ((Bmi->biWidth + 31) / 32) * 4 * abs(Bmi->biHeight / 2);
	IconInfo = IconInfo + "bytes\r\n";

	IconInfo = IconInfo + "合計イメージサイズ		： ";
	IconInfo = IconInfo + Bmi->biSizeImage;
	IconInfo = IconInfo + "bytes\r\n";
	//マスクビットのイメージをプリント
	IconInfo = IconInfo + "---------- マスクビットイメージ ----------\r\n";
	IconInfo = IconInfo + "No 01234567 01234567 01234567 01234567\r\n";
	IconInfo = IconInfo + "--------------------------------------\r\n";
	int j, k, l;
	char Dat[4];
	if(Bmi->biHeight > 0) {	//ボトムアップ
		for(j = 31; j >= 0; j--) {
			wsprintf(Dat, "%02d ", j);
			IconInfo = IconInfo + Dat;
			for(k = 0; k < 4; k++) {
				for(l = 0; l < 8; l++) {
					if(m_Icon.m_AND[i][j * 4 + k] & (1 << (7 - l)))
						IconInfo = IconInfo + "1";
					else
						IconInfo = IconInfo + "0";
				}
				IconInfo = IconInfo + " ";
			}
			IconInfo = IconInfo + "\r\n";
		}
	}
	else {					//トップダウン
		for(j = 0; j < 32; j++) {
			wsprintf(Dat, "%02d", j);
			IconInfo = IconInfo + Dat;
			for(k = 0; k < 4; k++) {
				for(l = 0; l < 8; l++) {
					if(m_Icon.m_AND[i][j * 4 + k] & (1 << (7 - l)))
						IconInfo = IconInfo + "1";
					else
						IconInfo = IconInfo + "0";
				}
				IconInfo = IconInfo + " ";
			}
			IconInfo = IconInfo + "\r\n";
		}
	}
	return SendItemMsg(IDC_EDIT, WM_SETTEXT, 0, (LPARAM)IconInfo.ToChar());
}
