
#include	"stdafx.h"
#include	"res/ResExtractData.h"
#include	"Common.h"
#include	"Ctrl/Button.h"
#include	"Ctrl/EditBox.h"
#include	"Ctrl/Label.h"
#include	"Ctrl/GroupBox.h"
#include	"Ctrl/RadioBtn.h"
#include	"Ctrl/UpDown.h"
#include	"Dialog/FolderDialog.h"
#include	"Reg.h"
#include	"Susie.h"
#include	"SusieListView.h"
#include	"Option.h"

typedef int (WINAPI* ConfigurationDlgProc)(HWND, int);

SOption COption::m_option;
SOption COption::m_option_tmp;
std::vector<YCString> COption::m_SearchFiles;
CMainListView* COption::m_pListView;
CSearchToolBar* COption::m_pToolBar;
HWND COption::m_hDlg = NULL;
HWND COption::m_hParentWnd = NULL;

void COption::Init(CSearchToolBar& toolbar, CMainListView& listview)
{
	m_pToolBar = &toolbar;
	m_pListView = &listview;

	std::vector<YCString>& SearchFiles = m_SearchFiles;
	SearchFiles.push_back(_T("AHX"));
	SearchFiles.push_back(_T("BMP"));
	SearchFiles.push_back(_T("JPG"));
	SearchFiles.push_back(_T("MID"));
	SearchFiles.push_back(_T("MPG"));
	SearchFiles.push_back(_T("OGG"));
	SearchFiles.push_back(_T("PNG"));
	SearchFiles.push_back(_T("WAV"));
	SearchFiles.push_back(_T("WMV"));

	LoadIni();

	// Susieプラグイン読み込み
	if( m_option.bSusieUse )
	{
		CSusie susie;
		susie.LoadSpi(m_option.SusieDir);
	}
}

void COption::LoadIni()
{
	SOption* pOption = &m_option;

	YCIni				clIni( SBL_STR_INI_EXTRACTDATA );
	CReg				clReg;

	clIni.SetSection( _T("Option") );

	// リストの背景色

	clIni.SetKey( _T("ListBkColor") );
	clIni.ReadStr( pOption->szListBkColor, sizeof(pOption->szListBkColor), _T("FFFFFF") );
	pOption->ListBkColor = _tcstol( pOption->szListBkColor, NULL, 16 );

	// リストの文字色

	clIni.SetKey( _T("ListTextColor") );
	clIni.ReadStr( pOption->szListTextColor, sizeof(pOption->szListTextColor), _T("000000") );
	pOption->ListTextColor = _tcstol( pOption->szListTextColor, NULL, 16 );

	// OGGの検索精度を上げるかどうかの設定

	clIni.SetKey( _T("HighSearchOgg") );
	clIni.ReadDec( &pOption->bHighSearchOgg, TRUE );

	// フォルダごと抽出するかどうかの設定

	clIni.SetKey( _T("ExtFolder") );
	clIni.ReadDec( &pOption->bCreateFolder, TRUE );

	// OGG抽出時にCRCを修正するかどうかの設定

	clIni.SetKey( _T("OggCRC") );
	clIni.ReadDec( &pOption->bFixOgg, FALSE );

	// 簡易復号機能を有効にするかどうかの設定

	clIni.SetKey( _T("EasyDecrypt") );
	clIni.ReadDec( &pOption->bEasyDecrypt, FALSE );

	// スクリプトの拡張子を変更するかどうかの設定

	clIni.SetKey( _T("RenameScriptExt") );
	clIni.ReadDec( &pOption->bRenameScriptExt, TRUE );

	// 出力画像形式の設定

	clIni.SetKey( _T("DstBMP") );
	clIni.ReadDec( &pOption->bDstBMP, TRUE );
	clIni.SetKey( _T("DstPNG") );
	clIni.ReadDec( &pOption->bDstPNG, FALSE );

	// PNG圧縮レベルの設定

	clIni.SetKey( _T("CmplvPng") );
	clIni.ReadDec( &pOption->CmplvPng, (DWORD) 1 );

	// αブレンドを行うかどうかの設定

	clIni.SetKey( _T("AlphaBlend") );
	clIni.ReadDec( &pOption->bAlphaBlend, FALSE );

	// αブレンドの高速化の設定

	clIni.SetKey( _T("FastAlphaBlend") );
	clIni.ReadDec( &pOption->bFastAlphaBlend, FALSE );

	// αブレンドを行うときの背景色

	clIni.SetKey( _T("BG_RGB") );
	clIni.ReadStr( pOption->szBgRGB, sizeof(pOption->szBgRGB), _T("FFFFFF") );
	pOption->BgRGB = _tcstol( pOption->szBgRGB, NULL, 16 );

	// 出力先

	clIni.SetKey( _T("SaveMethodSel") );
	clIni.ReadDec( &pOption->bSaveSel, TRUE );
	clIni.SetKey( _T("SaveMethodSrc") );
	clIni.ReadDec( &pOption->bSaveSrc, FALSE );
	clIni.SetKey( _T("SaveMethodDir") );
	clIni.ReadDec( &pOption->bSaveDir, FALSE );

	// 固定出力フォルダ

	TCHAR				szDesktopPath[_MAX_DIR];

	::SHGetSpecialFolderPath( NULL, szDesktopPath, CSIDL_DESKTOPDIRECTORY, FALSE );

	clIni.SetKey( _T("SaveDir") );
	clIni.ReadStr( pOption->SaveDir, szDesktopPath );

	// バッファサイズ

	clIni.SetKey( _T("BufSize") );
	clIni.ReadDec( &pOption->BufSize, (DWORD) 64 );

	// テンポラリフォルダ

	TCHAR				szTmpDir[_MAX_DIR];
	TCHAR				szTmpDirLong[_MAX_DIR];

	::GetTempPath( _countof(szTmpDir), szTmpDir );
	::GetLongPathName( szTmpDir, szTmpDirLong, 256 );
	PathAppend( szTmpDirLong, _T("ExtractData") );

	clIni.SetKey( _T("TmpDir") );
	clIni.ReadStr( pOption->TmpDir, szTmpDirLong );

	// Susieの設定

	clIni.SetSection( _T("Susie") );

	// Susieプラグインを使用する

	clIni.SetKey( _T("SusieUse") );
	clIni.ReadDec( &pOption->bSusieUse, FALSE );

	// Susieフォルダ

	YCString			clsPathToSusieFolder;

	clReg.GetValue( clsPathToSusieFolder, _T("HKEY_CURRENT_USER\\Software\\Takechin\\Susie\\Plug-in"), _T("Path") );

	clIni.SetKey( _T("SusieDir") );
	clIni.ReadStr( pOption->SusieDir, clsPathToSusieFolder );

	// Susieプラグインを優先する

	clIni.SetKey( _T("SusieFirst") );
	clIni.ReadDec( &pOption->bSusieFirst, FALSE );

	// 検索するファイルの設定

	clIni.SetSection( _T("Search") );

	for( size_t i = 0 ; i < m_SearchFiles.size() ; i++ )
	{
		BOOL				bSearch;

		clIni.SetKey( m_SearchFiles[i] );
		clIni.ReadDec( &bSearch, TRUE );

		pOption->bSearch.push_back( bSearch );
	}
}

void COption::SaveIni()
{
	SOption& pOption = m_option;

	YCIni				clIni( SBL_STR_INI_EXTRACTDATA );

	clIni.SetSection( _T("Option") );

	// リストの背景色

	clIni.SetKey( _T("ListBkColor") );
	clIni.WriteHex( pOption.ListBkColor, 6 );

	// リストの文字色

	clIni.SetKey( _T("ListTextColor") );
	clIni.WriteHex( pOption.ListTextColor, 6 );

	// OGGの検索精度を上げる

	clIni.SetKey( _T("HighSearchOgg") );
	clIni.WriteDec( pOption.bHighSearchOgg );

	// フォルダごと抽出する

	clIni.SetKey( _T("ExtFolder") );
	clIni.WriteDec( pOption.bCreateFolder );

	// OGG抽出時にCRCを修正

	clIni.SetKey( _T("OggCRC") );
	clIni.WriteDec( pOption.bFixOgg );

	// 簡易復号機能を有効にする

	clIni.SetKey( _T("EasyDecrypt") );
	clIni.WriteDec( pOption.bEasyDecrypt );

	// スクリプトの拡張子を変更するかどうかの設定

//	clIni.SetKey( _T("RenameScriptExt") );
//	clIni.WriteDec( pOption.bRenameScriptExt );

	// 出力画像形式

	clIni.SetKey( _T("DstBMP") );
	clIni.WriteDec(pOption.bDstBMP );
	clIni.SetKey( _T("DstPNG") );
	clIni.WriteDec( pOption.bDstPNG );

	// PNG圧縮レベル

	clIni.SetKey( _T("CmplvPng") );
	clIni.WriteDec( pOption.CmplvPng );

	// αブレンドを行う

	clIni.SetKey( _T("AlphaBlend") );
	clIni.WriteDec( pOption.bAlphaBlend );

	// αブレンドの高速化の設定

	clIni.SetKey( _T("FastAlphaBlend") );
	clIni.WriteDec( pOption.bFastAlphaBlend );

	// αブレンドを行うときの背景色

	clIni.SetKey( _T("BG_RGB") );
	clIni.WriteHex( pOption.BgRGB, 6 );

	// 出力先

	clIni.SetKey( _T("SaveMethodSel") );
	clIni.WriteDec( pOption.bSaveSel );
	clIni.SetKey( _T("SaveMethodSrc") );
	clIni.WriteDec( pOption.bSaveSrc );
	clIni.SetKey( _T("SaveMethodDir") );
	clIni.WriteDec( pOption.bSaveDir );

	// 固定出力フォルダ

	clIni.SetKey( _T("SaveDir") );
	clIni.WriteStr( pOption.SaveDir );

	// バッファサイズ

	clIni.SetKey( _T("BufSize") );
	clIni.WriteDec( pOption.BufSize );

	// テンポラリフォルダ

	clIni.SetKey( _T("TmpDir") );
	clIni.WriteStr( pOption.TmpDir );

	// Susieの設定

	clIni.SetSection( _T("Susie") );

	// Susieプラグインを使用する

	clIni.SetKey( _T("SusieUse") );
	clIni.WriteDec( pOption.bSusieUse );

	// Susieフォルダ

	clIni.SetKey( _T("SusieDir") );
	clIni.WriteStr( pOption.SusieDir );

	// Susieプラグインを優先する

	clIni.SetKey( _T("SusieFirst") );
	clIni.WriteDec( pOption.bSusieFirst );

	// 検索するファイルの設定

	clIni.SetSection( _T("Search") );

	for( size_t i = 0 ; i < m_SearchFiles.size() ; i++ )
	{
		clIni.SetKey( m_SearchFiles[i] );
		clIni.WriteDec( pOption.bSearch[i] );
	}

	// SusieプラグインのON/OFF設定保存

	if( m_option.bSusieUse )
	{
		CSusie susie;
		susie.SaveSpi();
	}
}

void COption::DoModal(HWND hWnd)
{
	m_hDlg = CreateProp(hWnd);
}

HWND COption::CreateProp(HWND hWnd)
{
	m_hParentWnd = hWnd;
	HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);

	PROPSHEETPAGE psp;
	HPROPSHEETPAGE hpsp[3];
	psp.dwSize = sizeof(PROPSHEETPAGE);
	psp.dwFlags = PSP_USETITLE;
	psp.hInstance = hInst;
	psp.lParam = (LPARAM)this;
	psp.pszTemplate = _T("OPTION");

	psp.pszTitle = _T("基本設定");
	psp.pfnDlgProc = (DLGPROC)StdProc;
	hpsp[0] = CreatePropertySheetPage(&psp);
	psp.pszTitle = _T("抽出設定");
	psp.pfnDlgProc = (DLGPROC)ExtractProc;
	hpsp[1] = CreatePropertySheetPage(&psp);
	psp.pszTitle = _T("Susieプラグイン");
	psp.pfnDlgProc = (DLGPROC)SusieProc;
	hpsp[2] = CreatePropertySheetPage(&psp);

	PROPSHEETHEADER psh;
	memset(&psh, 0, sizeof(PROPSHEETHEADER));
	psh.dwSize = sizeof(PROPSHEETHEADER);
	psh.dwFlags = PSH_USECALLBACK;
	psh.hInstance = hInst;
	psh.hwndParent = hWnd;
	psh.nPages = 3;
	psh.phpage = hpsp;
	psh.pszCaption = _T("ExtractData");
	psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;

	return (HWND)PropertySheet(&psh);
}

int COption::PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam)
{
	switch (msg) {
		case PSCB_INITIALIZED:
		{
			m_option_tmp = m_option;
			CSusie susie;
			susie.Init();
			LONG style = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
			SetWindowLongPtr(hWnd, GWL_EXSTYLE, style & ~WS_EX_CONTEXTHELP);
			break;
		}
	}

	return FALSE;
}

LRESULT COption::StdProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	COption* pThis = (COption*)lp;

	static SOption* pOption = &m_option_tmp;

	// リストビュー設定
	static CGroupBox ListGroup;
	static CLabel ListLabelBk, ListLabelText;
	static CEditBox ListEditBk, ListEditText;
	// 検索設定
	static std::vector<YCString>& SearchCheckText = m_SearchFiles;
	static std::vector<CCheckBox> SearchCheck(SearchCheckText.size());
	static int SearchCheckNum = SearchCheckText.size();
	static CButton SearchBtn[2];
	static CGroupBox SearchGroup;
	// 検索精度
	static CGroupBox HighSearchGroup;
	static CCheckBox HighSearchCheckOgg;

	switch (msg) {
		case WM_INITDIALOG:
		{
			CWindowBase::Init(::GetParent(hWnd));

			UINT ID = 10000;
			int x = 10, y = 0, xx = 15;

			// リストビュー設定
			ListGroup.Create(hWnd, _T("リストの設定"), ID++, x, y += 20, 470, 75);
			ListLabelBk.Create(hWnd, _T("背景色"), ID++, x + xx, y += 24, 50, 20);
			ListEditBk.Create(hWnd, pOption->szListBkColor, ID++, x + xx + 50, y - 4, 70, 22);
			ListEditBk.SetLimit(6);
			ListLabelText.Create(hWnd, _T("文字色"), ID++, x + xx, y += 24, 50, 20);
			ListEditText.Create(hWnd, pOption->szListTextColor, ID++, x + xx + 50, y - 4, 70, 22);
			ListEditText.SetLimit(6);

			// 検索設定
			SearchGroup.Create(hWnd, _T("検索するファイル"), ID++, x, y += 40, 470, 100);
			//y += 20;
			for (int i = 0, xxx = 0; i < SearchCheckNum; i++, xxx += 55) {
				if ((i % 8) == 0)
					xxx = 0, y += 20;
				SearchCheck[i].Create(hWnd, SearchCheckText[i], ID++, x + xx + xxx, y, 50, 20);
				SearchCheck[i].SetCheck(pOption->bSearch[i]);
			}
			SearchBtn[0].Create(hWnd, _T("すべて選択"), ID++, 305, y += 30, 80, 20);
			SearchBtn[1].Create(hWnd, _T("選択解除"),   ID++, 385, y, 80, 20);

			// 検索精度設定
			HighSearchGroup.Create(hWnd, _T("検索精度"), ID++, x, y += 40, 470, 50);
			HighSearchCheckOgg.Create(hWnd, _T("OGGの検索精度を上げる"), ID++, x + xx, y += 20, 160, 20);
			HighSearchCheckOgg.SetCheck(pOption->bHighSearchOgg);

			break;
		}

		case WM_COMMAND:
			// 検索ファイルチェックボックス
			if (LOWORD(wp) >= SearchCheck[0].GetID() && LOWORD(wp) <= SearchCheck[SearchCheckNum-1].GetID()) {
				int nNumber = LOWORD(wp) - SearchCheck[0].GetID();
				pOption->bSearch[nNumber] ^= 1;
				SearchCheck[nNumber].SetCheck(pOption->bSearch[nNumber]);
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// すべて選択
			if (LOWORD(wp) == SearchBtn[0].GetID()) {
				for (int i = 0; i < SearchCheckNum; i++) {
					pOption->bSearch[i] = TRUE;
					SearchCheck[i].SetCheck(pOption->bSearch[i]);
				}
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 選択解除
			if (LOWORD(wp) == SearchBtn[1].GetID()) {
				for (int i = 0; i < SearchCheckNum; i++) {
					pOption->bSearch[i] = FALSE;
					SearchCheck[i].SetCheck(pOption->bSearch[i]);
				}
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			if (LOWORD(wp) == HighSearchCheckOgg.GetID()) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// エディットボックスの内容が変更された
			if (HIWORD(wp) == EN_CHANGE) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			break;

		case WM_NOTIFY:
		{
			LPNMHDR pHdr = (LPNMHDR)lp;
			switch (pHdr->code) {
				// OK/適用, タブ移動
				case PSN_APPLY:
				case PSN_KILLACTIVE:
					ListEditBk.GetText(&pOption->ListBkColor, TRUE);
					_stprintf(pOption->szListBkColor, _T("%06x"), pOption->ListBkColor);
					ListEditText.GetText(&pOption->ListTextColor, TRUE);
					_stprintf(pOption->szListTextColor, _T("%06x"), pOption->ListTextColor);

					pOption->bHighSearchOgg = HighSearchCheckOgg.GetCheck();
					// OK/適用
					if (pHdr->code == PSN_APPLY)
						Apply();
					return TRUE;
			}
			break;
		}
	}

	return FALSE;
}

LRESULT COption::ExtractProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	COption* pThis = (COption*)lp;

	static CError error;
	static CFolderDialog FolderDlg;
	static SOption* pOption = &m_option_tmp;

	// 抽出設定

	static YCString ExtractCheckText[] =
	{
		_T("フォルダごと抽出する"), _T("OGGファイルのCRCを修正する"), _T("簡易復号機能を有効にする")
	};

	static BOOL* ExtractCheckFlag[] =
	{
		&pOption->bCreateFolder, &pOption->bFixOgg, &pOption->bEasyDecrypt, &pOption->bRenameScriptExt
	};

	static int ExtractCheckNum = _countof( ExtractCheckText );
	static std::vector<CCheckBox> ExtractCheck( ExtractCheckNum );
	static CCheckBox ExtractCheckAlpha, ExtractCheckFastAlpha;
	static CLabel ExtractLabelImage, ExtractLabelPng, ExtractLabelAlpha, ExtractLabelSave, ExtractLabelBuf, ExtractLabelTmp;
	static CRadioBtn ExtractRadioImage, ExtractRadioSave;
	static CUpDown ExtractUpDownPng;
	static CEditBox ExtractEditSusie, ExtractEditPng, ExtractEditAlpha, ExtractEditSave, ExtractEditBuf, ExtractEditTmp;
	static CButton ExtractBtnSusie, ExtractBtnSave, ExtractBtnTmp;
	static CGroupBox ExtractGroupImage, ExtractGroupSave;

	switch (msg) {
		case WM_INITDIALOG:
		{
			UINT ID = 10000;
			int x = 10, y = 0, xx = 15;

			// 抽出設定

			for( int i = 0 ; i < ExtractCheckNum ; i++ )
			{
				ExtractCheck[i].Create( hWnd, ExtractCheckText[i], ID++, x, y += 20, 200, 20 );
				ExtractCheck[i].SetCheck( *ExtractCheckFlag[i] );
			}

			//

			int y_Image = y;
			ExtractGroupImage.Create(hWnd, _T("出力画像形式"), ID++, x, y_Image += 34, 190, 130);
			ExtractRadioImage.Close(); // staticにしてるせいかデストラクタが呼ばれず前回のが消えないのでクローズ
			ExtractRadioImage.Create(hWnd, _T("BMP"), ID++, x + xx, y_Image += 18, 50, 20);
			ExtractRadioImage.Create(hWnd, _T("PNG"), ID++, x + xx, y_Image += 20, 50, 20);
			ExtractRadioImage.SetCheck(0, pOption->bDstBMP);
			ExtractRadioImage.SetCheck(1, pOption->bDstPNG);
			ExtractLabelPng.Create(hWnd, _T("圧縮レベル"), ID++, x + xx + 50, y_Image + 3, 60, 20);
			ExtractEditPng.Create(hWnd, _T(""), ID++, x + xx + 110, y_Image, 40, 22);
			ExtractEditPng.SetLimit(1);
			ExtractUpDownPng.Create(hWnd, ExtractEditPng.GetCtrlHandle(), pOption->CmplvPng, ID++, 9, 0);

			//

			ExtractCheckAlpha.Create(hWnd, _T("αブレンドを行う"), ID++, x + xx, y_Image += 22, 100, 20);
			ExtractCheckAlpha.SetCheck(pOption->bAlphaBlend);
			ExtractLabelAlpha.Create(hWnd, _T("背景色"), ID++, x + xx * 2, y_Image += 24, 40, 20);
			ExtractEditAlpha.Create(hWnd, pOption->szBgRGB, ID++, x + xx * 2 + 50, y_Image - 4, 100, 22);
			ExtractEditAlpha.SetLimit(6);
			ExtractEditAlpha.Enable(pOption->bAlphaBlend);

			ExtractCheckFastAlpha.Create( hWnd, _T("高速に処理する"), ID++, x + xx * 2, y_Image += 20, 120, 20);
			ExtractCheckFastAlpha.SetCheck( pOption->bFastAlphaBlend );
			ExtractCheckFastAlpha.Enable( pOption->bAlphaBlend );

			//

			int x_Save = x + 200;
			int y_Save = y;

			ExtractGroupSave.Create(hWnd, _T("出力先"), ID++, x_Save, y_Save += 34, 280, 110);
			ExtractRadioSave.Close(); // staticにしてるせいかデストラクタが呼ばれず前回のが消えないのでクローズ
			ExtractRadioSave.Create(hWnd, _T("毎回指定する"), ID++, x_Save + xx, y_Save += 18, 200, 20);
			ExtractRadioSave.Create(hWnd, _T("入力先と同じフォルダ"), ID++, x_Save + xx, y_Save += 20, 200, 20);
			ExtractRadioSave.Create(hWnd, _T("下記のフォルダ"), ID++, x_Save + xx, y_Save += 20, 200, 20);
			ExtractRadioSave.SetCheck(0, pOption->bSaveSel);
			ExtractRadioSave.SetCheck(1, pOption->bSaveSrc);
			ExtractRadioSave.SetCheck(2, pOption->bSaveDir);
			ExtractEditSave.Create(hWnd, pOption->SaveDir, ID++, x_Save + xx * 2, y_Save += 20, 200, 22);
			ExtractEditSave.Enable(pOption->bSaveDir);
			ExtractBtnSave.Create(hWnd, _T("参照"), ID++, x_Save + xx * 2 + 200, y_Save + 1, 40, 20);
			ExtractBtnSave.Enable(pOption->bSaveDir);

			//

			y = (y_Image > y_Save) ? y_Image : y_Save;
			ExtractLabelBuf.Create(hWnd, _T("バッファサイズ(KB)"), ID++, x, y += 44, 100, 20);
			ExtractEditBuf.Create(hWnd, pOption->BufSize, ID++, x + 100, y - 4, 110, 22);

			//

			ExtractLabelTmp.Create(hWnd, _T("テンポラリフォルダ"), ID++, x, y += 24, 100, 20);
			ExtractEditTmp.Create(hWnd, pOption->TmpDir, ID++, x + 100, y - 4, 200, 22);
			ExtractBtnTmp.Create(hWnd, _T("参照"), ID++, x + 300, y - 3, 40, 20);

			break;
		}

		case WM_COMMAND:
			// 上のチェックボックス
			if (LOWORD(wp) >= ExtractCheck[0].GetID() && LOWORD(wp) <= ExtractCheck[ExtractCheckNum-1].GetID()) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// αブレンドチェックボックス
			if (LOWORD(wp) == ExtractCheckAlpha.GetID()) {
				ExtractEditAlpha.Enable(ExtractCheckAlpha.GetCheck());
				ExtractCheckFastAlpha.Enable( ExtractCheckAlpha.GetCheck() );
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 出力画像形式ラジオボタン
			if (LOWORD(wp) >= ExtractRadioImage.GetID(0) && LOWORD(wp) <= ExtractRadioImage.GetID(1)) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 出力先ラジオボタン
			if (LOWORD(wp) >= ExtractRadioSave.GetID(0) && LOWORD(wp) <= ExtractRadioSave.GetID(2)) {
				ExtractEditSave.Enable(ExtractRadioSave.GetCheck(2));
				ExtractBtnSave.Enable(ExtractRadioSave.GetCheck(2));
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 出力フォルダ参照
			if (LOWORD(wp) == ExtractBtnSave.GetID()) {
				TCHAR szSaveDir[_MAX_DIR];
				ExtractEditSave.GetText(szSaveDir, sizeof(szSaveDir));
				if (FolderDlg.DoModal(hWnd, _T("出力フォルダ選択"), szSaveDir) == TRUE)
					ExtractEditSave.SetText(szSaveDir);
				break;
			}
			// テンポラリフォルダ参照
			if (LOWORD(wp) == ExtractBtnTmp.GetID()) {
				TCHAR szTmpDir[_MAX_DIR];
				ExtractEditTmp.GetText(szTmpDir, sizeof(szTmpDir));
				if (FolderDlg.DoModal(hWnd, _T("テンポラリフォルダ選択"), szTmpDir) == TRUE)
					ExtractEditTmp.SetText(szTmpDir);
				break;
			}
			// エディットボックスの内容が変更された
			if (HIWORD(wp) == EN_CHANGE) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			break;

		case WM_NOTIFY:
		{
			LPNMHDR pHdr = (LPNMHDR)lp;
			switch (pHdr->code) {
				// OK/適用, タブ移動
				case PSN_APPLY:
				case PSN_KILLACTIVE:
					// 抽出設定
					for (int i = 0; i < (int)ExtractCheck.size(); i++)
						*ExtractCheckFlag[i] = ExtractCheck[i].GetCheck();
					//
					pOption->bDstBMP = ExtractRadioImage.GetCheck(0);
					pOption->bDstPNG = ExtractRadioImage.GetCheck(1);
					ExtractEditPng.GetText(&pOption->CmplvPng, FALSE);
					//
					pOption->bAlphaBlend = ExtractCheckAlpha.GetCheck();
					pOption->bFastAlphaBlend = ExtractCheckFastAlpha.GetCheck();
					ExtractEditAlpha.GetText(&pOption->BgRGB, TRUE);
					_stprintf(pOption->szBgRGB, _T("%06x"), pOption->BgRGB);
					//
					pOption->bSaveSel = ExtractRadioSave.GetCheck(0);
					pOption->bSaveSrc = ExtractRadioSave.GetCheck(1);
					pOption->bSaveDir = ExtractRadioSave.GetCheck(2);
					ExtractEditSave.GetText(pOption->SaveDir);
					//
					ExtractEditBuf.GetText(&pOption->BufSize, FALSE);
					//
					ExtractEditTmp.GetText(pOption->TmpDir);
					// OK/適用
					if (pHdr->code == PSN_APPLY)
						Apply();
					return TRUE;
			}
			break;
		}
	}

	return FALSE;
}

LRESULT COption::SusieProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	COption* pThis = (COption*)lp;

	static CError error;
	static CFolderDialog FolderDlg;
	static SOption* pOption = &m_option_tmp;

	static CCheckBox SusieCheckUse, SusieCheckFirst;
	static CLabel SusieLabelDir;
	static CEditBox SusieEditDir;
	static CButton SusieBtnDir, SusieBtnUpdate, SusieBtn[2];
	static CSusieListView SusieListView;
	static CSusie susie;

	switch (msg) {
		case WM_INITDIALOG:
		{
			UINT ID = 10000;
			int x = 10, y = 0, xx = 15;

			SusieCheckUse.Create(hWnd, _T("Susieプラグインを使用する"), ID++, x, y += 20, 200, 20);
			SusieCheckUse.SetCheck(pOption->bSusieUse);

			SusieLabelDir.Create(hWnd, _T("Susieフォルダ"), ID++, x + xx, y += 24, 75, 20);
			SusieEditDir.Create(hWnd, pOption->SusieDir, ID++, x + xx + 75, y - 4, 200, 22);
			SusieEditDir.Enable(pOption->bSusieUse);
			SusieBtnDir.Create(hWnd, _T("参照"), ID++, x + xx + 275, y - 3, 40, 20);
			SusieBtnDir.Enable(pOption->bSusieUse);

			SusieCheckFirst.Create(hWnd, _T("Susieプラグインを優先する"), ID++, x + xx, y += 20, 200, 20);
			SusieCheckFirst.SetCheck(pOption->bSusieFirst);
			SusieCheckFirst.Enable(pOption->bSusieUse);

			SusieListView.Create(hWnd, *pOption, x + xx, y += 30, 445, 190);
			SusieListView.Close();
			SusieListView.Enable(pOption->bSusieUse);
			SusieListView.Show();

			SusieBtnUpdate.Create(hWnd, _T("更新"), ID++, x + 240, y += 200, 50, 20);
			SusieBtnUpdate.Enable(pOption->bSusieUse);
			SusieBtn[0].Create(hWnd, _T("すべてON"), ID++, x + 300, y, 80, 20);
			SusieBtn[0].Enable(pOption->bSusieUse);
			SusieBtn[1].Create(hWnd, _T("すべてOFF"), ID++, x + 380, y, 80, 20);
			SusieBtn[1].Enable(pOption->bSusieUse);

			break;
		}

		case WM_COMMAND:
			// Susieプラグインを使用する
			if (LOWORD(wp) == SusieCheckUse.GetID()) {
				BOOL flag = SusieCheckUse.GetCheck();
				SusieEditDir.Enable(flag);
				SusieBtnDir.Enable(flag);
				SusieCheckFirst.Enable(flag);
				SusieListView.Enable(flag);
				SusieBtnUpdate.Enable(flag);
				SusieBtn[0].Enable(flag);
				SusieBtn[1].Enable(flag);
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				// チェックボックスの表示/非表示切り替え、選択状態解除
				pOption->bSusieUse = flag;
				SusieListView.SetItemSelAll(0);
				break;
			}
			// Susieフォルダ参照
			if (LOWORD(wp) == SusieBtnDir.GetID()) {
				TCHAR szSusieDir[_MAX_DIR];
				SusieEditDir.GetText(szSusieDir, sizeof(szSusieDir));
				if (FolderDlg.DoModal(hWnd, _T("Susieフォルダ選択"), szSusieDir) == TRUE)
					SusieEditDir.SetText(szSusieDir);
			}
			// Susieプラグインを優先する
			if (LOWORD(wp) == SusieCheckFirst.GetID()) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 更新
			if (LOWORD(wp) == SusieBtnUpdate.GetID()) {
				susie.LoadSpi(pOption->SusieDir);
				susie.Init();
				SusieListView.Show();
				SusieListView.Update();
				break;
			}
			// すべてON
			if (LOWORD(wp) == SusieBtn[0].GetID()) {
				SusieListView.SetCheckAll(1);
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// すべてOFF
			if (LOWORD(wp) == SusieBtn[1].GetID()) {
				SusieListView.SetCheckAll(0);
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			// 設定
			if (LOWORD(wp) == IDM_SUSIE_SET) {
				SSusieInfo* pstSusieInfo = SusieListView.GetFocusSusieInfo();

				// ConfigurationDlg()取得
				ConfigurationDlgProc	ConfigurationDlg = (ConfigurationDlgProc) pstSusieInfo->cllPlugin.GetProcAddress( _T("ConfigurationDlg") );

				if( ConfigurationDlg == NULL )
				{
					break;
				}

				// 設定呼び出し
				ConfigurationDlg( hWnd, 1 );

				break;
			}
			// エディットボックスの内容が変更された
			if (HIWORD(wp) == EN_CHANGE) {
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			break;

		case WM_NOTIFY:
		{
			LPNMHDR pHdr = (LPNMHDR)lp;

			switch (pHdr->code) {
				// OK/適用, タブ移動
				case PSN_APPLY:
				case PSN_KILLACTIVE:
					pOption->bSusieUse = SusieCheckUse.GetCheck();
					pOption->bSusieFirst = SusieCheckFirst.GetCheck();
					SusieEditDir.GetText(pOption->SusieDir);
					SusieListView.SaveIni();
					// OK/適用
					if (pHdr->code == PSN_APPLY) {
						BOOL bUpdate = (m_option.SusieDir == pOption->SusieDir) ? FALSE : TRUE;
						Apply();
						// Susieフォルダが変更されていたときのみプラグイン再取得
						if (pOption->bSusieUse == TRUE && bUpdate == TRUE) {
							susie.LoadSpi(pOption->SusieDir);
							susie.Init();
							SusieListView.Show();
							SusieListView.Update();
						}
					}
					return TRUE;
				// チェック処理
				case NM_CLICK:
				case NM_DBLCLK:
					if (pHdr->idFrom == idsSusieList) {
						if (SusieListView.SetCheck() == TRUE)
							PropSheet_Changed(::GetParent(hWnd), hWnd);
						break;
					}
			}
			// リストビュー
			if (wp == idsSusieList) {
				LPNMLISTVIEW plv = (LPNMLISTVIEW)lp;
				switch (plv->hdr.code) {
					// カスタムドロー
					case NM_CUSTOMDRAW:
						return SusieListView.CustomDraw((LPNMLVCUSTOMDRAW)lp);
					// ツールチップ表示
					case LVN_GETINFOTIP:
						SusieListView.ShowTip((LPNMLVGETINFOTIP)lp);
						break;
					// 表示
					case LVN_GETDISPINFO:
						SusieListView.Show((NMLVDISPINFO*)lp);
						break;
				}
			}

			break;
		}

		case WM_MOUSEWHEEL:
		{
			POINT pos;
			GetCursorPos(&pos);
			HWND pWnd = WindowFromPoint(pos);
			if (pWnd == SusieListView.GetHandle())
				SendMessage(pWnd, WM_MOUSEWHEEL, wp, lp);
			break;
		}

		// 右クリックメニュー
		case WM_CONTEXTMENU:
		{
			if (wp == (WPARAM)SusieListView.GetHandle())
				SusieListView.CreateMenu(lp);
			break;
		}
	}

	return FALSE;
}

void COption::Apply()
{
	// 変更結果に反映
	CSusie susie;
	susie.Apply();

	// iniに保存
	m_option = m_option_tmp;
	SaveIni();

	m_pListView->SetBkColor();
	m_pListView->SetTextColor();
	m_pListView->Update();

	m_pToolBar->SetCheckSearch();
}