/////////////////////////////////////////////////
//
//  filename: CustomButton.jpp
//  author:Chafumi Touji 
//  date: 2020/06/03 ver1.00
//
/////////////////////////////////////////////////

#include "StdAfx.h"
#include "Main.h"
#include "CustomButton.h"
#include "MainWindow.h"
#include "Config.h"
#include "DialogFileSelect.h"

//////////////////////////////////////////////////////////////////////////////////////////

CConfirmDialog::CConfirmDialog(){

	HDC screen = GetDC(0);
	dpiX = (float)GetDeviceCaps(screen, LOGPIXELSX);
	dpiY = (float)GetDeviceCaps(screen, LOGPIXELSY);
	ReleaseDC(0, screen);

	ScaleX = (dpiX / 96.0f);
	ScaleY = (dpiY / 96.0f);

	DisplayWidth = ::GetSystemMetrics(SM_CXSCREEN);
	DisplayHeight = ::GetSystemMetrics(SM_CYSCREEN);
	FrameEdgeX = 8;
	FrameEdgeY = 8;

	TransparentR = COLOR_TRANSPARENT_R;
	TransparentG = COLOR_TRANSPARENT_G;
	TransparentB = COLOR_TRANSPARENT_B;

	CRect	rectDesktop;
	::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktop, 0);

	Width = (int)((double)DisplayWidth / 1.5);
	Height = (int)((double)DisplayHeight / 1.5);
	TitleBarHeight = (int)((double)DisplayHeight / 30.0);

	BKColorA = 255;
	BKColorR = 180;
	BKColorG = 150;
	BKColorB = 150;
	TextColorA = 255;
	TextColorR = 100;
	TextColorG = 70;
	TextColorB = 70;

	PosX = (DisplayWidth - Width) / 2;
	PosY = (DisplayHeight - Height) / 2;

	LButtonDown = false;
	GetCaption = false;
	DownPoint = CPoint(0, 0);
	ConfirmLoop = false;
	Execute = false;
}

CConfirmDialog::~CConfirmDialog(){
}

bool CConfirmDialog::SetParam(CConfig *config){

	BKColorA = config->BKColorA;
	BKColorR = config->BKColorR;
	BKColorG = config->BKColorG;
	BKColorB = config->BKColorB;
	BarColorA = config->BarColorA;
	BarColorR = config->BarColorR;
	BarColorG = config->BarColorG;
	BarColorB = config->BarColorB;
	TextColorA = config->TextColorA;
	TextColorR = config->TextColorR;
	TextColorG = config->TextColorG;
	TextColorB = config->TextColorB;

	return true;
}

bool CConfirmDialog::CreateWnd(HWND ParentWnd, int x, int y, int w, int h){

	SetParam(theApp->MainWindow->Config);

	WNDCLASSEX wcx;
	memset(&wcx, 0, sizeof(WNDCLASSEX));
	wcx.style = CS_HREDRAW | CS_VREDRAW;
	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.hInstance = NULL;
	wcx.hIcon = NULL;
	wcx.lpszMenuName = NULL;
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.lpfnWndProc = &CConfirmDialog::WindowProc;
	wcx.lpszClassName = L"CLASS_CONFIRM_DIALOG";
	RegisterClassEx(&wcx);

	PosX = x;
	PosY = y;
	Width = w;
	Height = h;
	m_hWnd = CreateWindowEx(WS_EX_COMPOSITED, L"CLASS_CONFIRM_DIALOG", _T("confirm"), WS_POPUP | WS_CLIPCHILDREN, PosX, PosY, Width, Height, GetDesktopWindow(), NULL, NULL, NULL);
	::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (UINT_PTR) this);

	BitmapWidth = DisplayWidth;
	BitmapHeight = DisplayHeight;

	BITMAPINFO  bmi = { 0 };
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = BitmapWidth;
	bmi.bmiHeader.biHeight = BitmapHeight;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 32;

	MemBMP = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, (void **)&AlphaBMP, 0, 0);
	::DeleteDC(MemDC);

	HDC hdc = ::GetDC(m_hWnd);
	MemDC = CreateCompatibleDC(hdc);
	::SelectObject(MemDC, MemBMP);
	DeleteDC(hdc);

	int button_size = (int)((double)TitleBarHeight * 0.8f);
	x = Width - button_size - (int)((double)TitleBarHeight * 0.5f);
	y = (int)((double)TitleBarHeight * 0.1f);
	ButtonConfirmClose = new CButtonConfirmClose();
	ButtonConfirmClose->CreateWnd(x, y, button_size, button_size, m_hWnd);
	ButtonConfirmClose->SetImage(L"./pict/ButtonClose.png", L"./pict/ButtonCloseDown.png");

	int button_width = (int)((double)TitleBarHeight * 3.0f);
	int button_height = (int)((double)TitleBarHeight * 1.0f);

	x = Width - button_width * 2 - (int)((double)TitleBarHeight * 1.0f);
	y = Height - button_height - (int)((double)TitleBarHeight * 0.3f);
	ButtonConfirmCancel = new CButtonConfirmCancel();
	ButtonConfirmCancel->CreateWnd(x, y, button_width, button_height, m_hWnd);
	ButtonConfirmCancel->SetImage(L"./pict/ButtonCancel.png", L"./pict/ButtonCancelDown.png");
	ButtonConfirmCancel->SetColor(BKColorA, BKColorR, BKColorG, BKColorB);

	x += button_width + (int)((double)TitleBarHeight * 0.2f);
	ButtonConfirmOK = new CButtonConfirmOK();
	ButtonConfirmOK->CreateWnd(x, y, button_width, button_height, m_hWnd);
	ButtonConfirmOK->SetImage(L"./pict/ButtonOK.png", L"./pict/ButtonOKDown.png");
	ButtonConfirmOK->SetColor(BKColorA, BKColorR, BKColorG, BKColorB);

	::ShowWindow(m_hWnd, SW_HIDE);

	return true;
}

LRESULT CConfirmDialog::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	CConfirmDialog *dialog = (CConfirmDialog *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
	if (dialog != NULL)
		dialog->ConfirmDialogProc(hwnd, message, wParam, lParam);

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CConfirmDialog::ConfirmDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;

	switch (message){
	case WM_PAINT:
		OnPaint();
		break;
	case WM_SIZE:
		width = GET_X_LPARAM(lParam);
		height = GET_Y_LPARAM(lParam);
		OnSize((UINT)wParam, width, height);
		break;
	case WM_LBUTTONDOWN:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonDown((UINT)wParam, CPoint(x, y));
		break;
	case WM_LBUTTONUP:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonUp((UINT)wParam, CPoint(x, y));
		break;
	case WM_MOUSEMOVE:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnMouseMove((UINT)wParam, CPoint(x, y));
		break;
	default:
		break;
	}

	return 0;
}

void CConfirmDialog::OnSize(UINT nType, int cx, int cy){

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CConfirmDialog::OnPaint(){

	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	OnDraw(hdc);
	::EndPaint(m_hWnd, &ps);
}

bool CConfirmDialog::OnDraw(HDC hdc){

	HBITMAP OldBmp = (HBITMAP)::SelectObject(MemDC, MemBMP);

	int width = Width;
	int height = Height;

	Gdiplus::Graphics *gfc = new Gdiplus::Graphics(MemDC);
	gfc->Clear(Gdiplus::Color(255, BKColorR, BKColorG, BKColorB));

	Gdiplus::SolidBrush *brush1 = new Gdiplus::SolidBrush(Gdiplus::Color(BarColorA, BarColorR, BarColorG, BarColorB));
	gfc->FillRectangle(brush1, 0, 0, width, TitleBarHeight);
	delete brush1;

	Gdiplus::Pen *pen1 = new Gdiplus::Pen(Gdiplus::Color(BarColorA, BarColorR, BarColorG, BarColorB), 8);
	gfc->DrawLine(pen1, 0, 0, Width, 0);
	gfc->DrawLine(pen1, width, 0, width, height);
	gfc->DrawLine(pen1, width, height, 0, height);
	gfc->DrawLine(pen1, 0, height, 0, 0);
	delete pen1;

	gfc->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
	Gdiplus::Font *font = new Gdiplus::Font(L"メイリオ", (REAL)((double)TitleBarHeight * 0.5f / ScaleX));
	Gdiplus::StringFormat *format = new Gdiplus::StringFormat(StringFormatFlagsNoWrap);
	Gdiplus::SolidBrush *brush2 = new Gdiplus::SolidBrush(Gdiplus::Color(255, BKColorR + 30, BKColorG + 30, BKColorB + 30));
	gfc->DrawString(L"確認", -1, font, RectF((double)width / 50.0, (double)TitleBarHeight * 0.1f, (REAL)width, (REAL)TitleBarHeight), format, brush2);

	gfc->DrawString(theApp->MainWindow->FileSelectDialog->SelectList->CurrentFileName, -1, font, RectF((double)Width / 30.0, (double)Height / 3.5, (REAL)Width * 0.9, (REAL)TitleBarHeight), format, brush2);
	gfc->DrawString(L"ファイルは既に存在します。上書きしますか？", -1, font, RectF((double)Width / 30.0, (double)Height / 2.0, (REAL)Width * 0.9, (REAL)TitleBarHeight), format, brush2);

	::BitBlt(hdc, 0, 0, width, height, MemDC, 0, 0, SRCCOPY);

	delete brush2;
	delete font;
	delete format;
	delete gfc;

	return true;
}

void CConfirmDialog::OnLButtonDown(UINT nFlag, CPoint point){

	LButtonDown = true;
	::SetCapture(m_hWnd);

	if (point.y < TitleBarHeight)
		GetCaption = true;
	else
		GetCaption = false;

	int pos_x = point.x;
	int pos_y = point.y + FrameEdgeY * 2 + ::GetSystemMetrics(SM_CYCAPTION);

	/////////////////////////////////////////////////////////

	::ClientToScreen(m_hWnd, &point);
	DownPoint = point;
	LButtonDown = true;
	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CConfirmDialog::OnLButtonUp(UINT nFlag, CPoint point){

	::ReleaseCapture();
	LButtonDown = false;
	GetCaption = false;

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CConfirmDialog::OnMouseMove(UINT nFlag, CPoint point){

	if (LButtonDown == true && GetCaption == true){
		::ClientToScreen(m_hWnd, &point);
		PosX += point.x - DownPoint.x;
		PosY += point.y - DownPoint.y;
		DownPoint = point;
		::SetWindowPos(m_hWnd, HWND_TOP, PosX, PosY, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
		::InvalidateRect(m_hWnd, NULL, false);
		::UpdateWindow(m_hWnd);
	}
}

////////////////////////////////////////////////////////////////////////////////

CEditWindow::CEditWindow(){

	HDC screen = GetDC(0);
	dpiX = (float) GetDeviceCaps(screen, LOGPIXELSX);
	dpiY = (float) GetDeviceCaps(screen, LOGPIXELSY);
	ReleaseDC(0, screen);

	ScaleX = ( dpiX / 96.0f );
	ScaleY = ( dpiY / 96.0f );

	wmemset(IMEText, 0, SIZE_CHAR_MAX);
};

CEditWindow::~CEditWindow(){
}

bool CEditWindow::SetParam(CConfig *config){

	BKColorR = config->BKColorR;
	BKColorG = config->BKColorG;
	BKColorB = config->BKColorB;
	TextColorR = config->TextColorR;
	TextColorG = config->TextColorG;
	TextColorB = config->TextColorB;

	return true;
}

bool CEditWindow::CreateWnd(HWND ParentWnd, int x, int y, int w, int h){

	SetParam(theApp->MainWindow->Config);

	Width = w;
	Height = h;
	PosX = x;
	PosY = y;

	m_hWnd = CreateWindowEx(WS_EX_LEFT, MSFTEDIT_CLASS, NULL, WS_CHILD | ES_AUTOHSCROLL, x, y, w, h, ParentWnd, NULL, NULL, NULL);
	::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR) this);
	OrgProc = (FARPROC) ::GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
	::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);

	LOGFONT	logfont;
	int fontsize = (int) ((float) Height * 0.7f );

	// LOGFONT構造体を設定する
	memset(&logfont, NULL, sizeof(logfont));
	logfont.lfHeight = fontsize;
	logfont.lfWidth = 0;
	logfont.lfWeight = FW_NORMAL;
	logfont.lfCharSet = DEFAULT_CHARSET;	// Shift-JIS
	logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
	logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	logfont.lfQuality = DEFAULT_QUALITY;
	logfont.lfPitchAndFamily = DEFAULT_PITCH;
	wcscpy_s(logfont.lfFaceName, 32, L"メイリオ");

	Font = CreateFontIndirect(&logfont);
	::SendMessage(m_hWnd, WM_SETFONT, (WPARAM) Font, 0);

	HIMC hIMC = ::ImmGetContext(m_hWnd);
	::ImmSetCompositionFont(hIMC, &logfont);
	::ImmReleaseContext(m_hWnd, hIMC);

	CHARFORMAT2 cf;
	cf.cbSize = sizeof(CHARFORMAT2);
	cf.dwMask = CFM_COLOR | CFM_BACKCOLOR | CFM_EFFECTS2 | CFM_SIZE;
	cf.crTextColor = RGB(TextColorR, TextColorG, TextColorB);
	cf.crBackColor = RGB(BKColorR - 20,BKColorG - 20, BKColorB - 20);
	cf.dwEffects = 0;
	cf.yHeight = (int) (((float) fontsize ) * 1440.0f / dpiY );
	wcscpy_s(cf.szFaceName, 32, L"メイリオ");
	::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);

	COLORREF cr = RGB(BKColorR - 20, BKColorG - 20, BKColorB - 20 );
	::SendMessage( m_hWnd, EM_SETBKGNDCOLOR, 0, (LPARAM)cr);

	::ShowWindow(m_hWnd, SW_SHOW);

	return true;
}

LRESULT CEditWindow::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	CEditWindow *edit = (CEditWindow *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
	if (edit != NULL){
		edit->EditWindowProc(hwnd, message, wParam, lParam);
		return CallWindowProc((WNDPROC)edit->OrgProc, hwnd, message, wParam, lParam);
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CEditWindow::EditWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	switch (message){
	case WM_LBUTTONDOWN:
		SetFocus(m_hWnd);
		break;
	case WM_MOUSEMOVE:
		SetFocus(m_hWnd);
		break;
	}

	return 0;
}

///////////////////////////////////////////////////////////

CScrollBar::CScrollBar(){

	DisplayWidth = ::GetSystemMetrics(SM_CXSCREEN);
	DisplayHeight = ::GetSystemMetrics(SM_CYSCREEN);

	BarPosY = 0;
	BarHeight = 0;
	LButtonDown = false;
	DownPoint = CPoint(0, 0);
}

CScrollBar::~CScrollBar(){

}

bool CScrollBar::SetParam(CConfig *config){

	BKColorA = config->BKColorA;
	BKColorR = config->BKColorR;
	BKColorG = config->BKColorG;
	BKColorB = config->BKColorB;

	return true;
}

bool CScrollBar::CreateWnd(HWND ParentWnd, int x, int y, int w, int h, HDC memDC, HBITMAP bitmap ){

	SetParam(theApp->MainWindow->Config);

	WNDCLASSEX wcx;
	memset(&wcx, 0, sizeof(WNDCLASSEX));
	wcx.style = CS_HREDRAW | CS_VREDRAW;
	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.hInstance = NULL;
	wcx.hIcon = NULL;
	wcx.lpszMenuName = NULL;
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.lpfnWndProc = &CScrollBar::WindowProc;
	wcx.lpszClassName = L"CLASS_SCROLLBAR";
	RegisterClassEx(&wcx);

	PosX = x;
	PosY = y;
	Width = w;
	Height = h;
	m_hWnd = CreateWindowEx(WS_EX_COMPOSITED, L"CLASS_SCROLLBAR", _T("scroll bar"), WS_CHILD, PosX, PosY, Width, Height, ParentWnd, NULL, NULL, NULL);
	::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (UINT_PTR) this);

	MemDC = memDC;
	MemBMP = bitmap;

	::ShowWindow(m_hWnd, SW_SHOW);

	return true;
}

LRESULT CScrollBar::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	CScrollBar *scroll = (CScrollBar *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
	if (scroll != NULL)
		scroll->ScrollBarProc(hwnd, message, wParam, lParam);

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CScrollBar::ScrollBarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	MOUSEHOOKSTRUCT *ms = NULL;

	switch (message){
	case WM_PAINT:
		OnPaint();
		break;
	case WM_SIZE:
		width = GET_X_LPARAM(lParam);
		height = GET_Y_LPARAM(lParam);
		OnSize((UINT)wParam, width, height);
		break;
	case WM_LBUTTONDOWN:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonDown((UINT)wParam, CPoint(x, y));
		break;
	case WM_LBUTTONUP:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonUp((UINT)wParam, CPoint(x, y));
		break;
	case WM_MOUSEMOVE:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnMouseMove((UINT)wParam, CPoint(x, y));
		break;
	default:
		break;
	}

	return 0;
}

void CScrollBar::OnSize(UINT nType, int cx, int cy){
}

void CScrollBar::OnPaint(){

	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	OnDraw(hdc);
	::EndPaint(m_hWnd, &ps);
}

bool CScrollBar::OnDraw(HDC hdc){

	HBITMAP OldBmp = (HBITMAP)::SelectObject(MemDC, MemBMP);

	Gdiplus::Graphics *gfc = new Gdiplus::Graphics(MemDC);

	Gdiplus::SolidBrush *brush1 = new Gdiplus::SolidBrush(Gdiplus::Color(BKColorA, BKColorR-10, BKColorG-10, BKColorB-10));
	gfc->FillRectangle(brush1, 0, 0, Width, Height);
	delete brush1;

	Gdiplus::SolidBrush *brush = new Gdiplus::SolidBrush(Gdiplus::Color(BKColorA, BKColorR + 20, BKColorG + 20, BKColorB + 20));
	FillRoundRect( gfc, brush, 0, BarPosY, Width, BarHeight, Width / 5);
	delete brush;

	Gdiplus::Pen *pen = new Gdiplus::Pen(Gdiplus::Color(BKColorA, BKColorR - 30, BKColorG - 30, BKColorB - 30), Width / 5);
	DrawRoundRect(gfc, pen, 0, BarPosY, Width, BarHeight, Width / 5);
	delete pen;

	::BitBlt(hdc, 0, 0, Width, Height, MemDC, 0, 0, SRCCOPY);

	delete gfc;

	return true;
}

bool CScrollBar::UpdateScrollBar(){

	int item_count = theApp->MainWindow->FileSelectDialog->SelectList->ItemCount;

	if (item_count <= SELECT_LIST_ITEM_DISP_NUM){
		BarHeight = Height;
		BarPosY = 0;
	}
	else{
		theApp->MainWindow->FileSelectDialog->SelectList->ItemBegin = (int)(((float)BarPosY / (float)( Height - BarHeight )) * (float)( item_count - SELECT_LIST_ITEM_DISP_NUM ));
	}

	return true;
}

bool CScrollBar::DrawRoundRect(Gdiplus::Graphics *gfc, Gdiplus::Pen *pen, int x, int y, int w, int h, int r){

	if (r % 2 != 0)
		r++;

	gfc->DrawArc(pen, x, y, r, r, 180, 90);
	gfc->DrawArc(pen, x + w - r, y, r, r, 270, 90);
	gfc->DrawArc(pen, x, y + h - r, r, r, 90, 90);
	gfc->DrawArc(pen, x + w - r, y + h - r, r, r, 0, 90);
	gfc->DrawLine(pen, x + r / 2, y, x + w + 1 - r / 2, y);
	gfc->DrawLine(pen, x, y + r / 2, x, y + h + 1 - r / 2);
	gfc->DrawLine(pen, x + w, y + r / 2, x + w + 1, y + h + 1 - r / 2);
	gfc->DrawLine(pen, x + r / 2, y + h, x + w + 1 - r / 2, y + h + 1);

	return true;
}

bool CScrollBar::FillRoundRect(Gdiplus::Graphics *gfc, Gdiplus::Brush *brush, int x, int y, int w, int h, int r){

	if (r % 2 != 0)
		r++;

	gfc->FillPie(brush, x, y, r, r, 180, 90);
	gfc->FillPie(brush, x + w - r, y, r, r, 270, 90);
	gfc->FillPie(brush, x, y + h - r, r, r, 90, 90);
	gfc->FillPie(brush, x + w - r, y + h - r, r, r, 0, 90);
	gfc->FillRectangle(brush, x + r / 2, y, w - r, r / 2);
	gfc->FillRectangle(brush, x, y + r / 2, r / 2, h - r);
	gfc->FillRectangle(brush, x + r / 2, y + h - r / 2, w - r, r / 2);
	gfc->FillRectangle(brush, x + w - r / 2, y + r / 2, r / 2, h - r);
	gfc->FillRectangle(brush, x + r / 2, y + r / 2, w - r, h - r);

	return true;
}

void CScrollBar::OnLButtonDown(UINT nFlag, CPoint point){

	LButtonDown = true;

	int pos_x = point.x;
	int pos_y = point.y;

	/////////////////////////////////////////////////////////

	::ClientToScreen(m_hWnd, &point);
	DownPoint = point;
	LButtonDown = true;

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CScrollBar::OnLButtonUp(UINT nFlag, CPoint point){

	LButtonDown = false;

	UpdateScrollBar();

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CScrollBar::OnMouseMove(UINT nFlag, CPoint point){

	if (LButtonDown == true){
		::ClientToScreen(m_hWnd, &point);
		BarPosY += point.y - DownPoint.y;
		if (BarPosY < 0)
			BarPosY = 0;
		if (BarPosY > Height - BarHeight)
			BarPosY = Height - BarHeight;

		UpdateScrollBar();

		::InvalidateRect(theApp->MainWindow->FileSelectDialog->SelectList->m_hWnd, NULL, false);
		::UpdateWindow(theApp->MainWindow->FileSelectDialog->SelectList->m_hWnd);

		DownPoint = point;
	}
}

///////////////////////////////////////////////////////////////////////////

CSelectList::CSelectList(){

	HDC screen = GetDC(0);
	dpiX = (float)GetDeviceCaps(screen, LOGPIXELSX);
	dpiY = (float)GetDeviceCaps(screen, LOGPIXELSY);
	ReleaseDC(0, screen);

	ScaleX = (dpiX / 96.0f);
	ScaleY = (dpiY / 96.0f);

	DisplayWidth = ::GetSystemMetrics(SM_CXSCREEN);
	DisplayHeight = ::GetSystemMetrics(SM_CYSCREEN);

	wmemset(CurrentPath, 0, SIZE_CHAR_MAX);
	wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
	wmemset(SelectedFile, 0, SIZE_CHAR_MAX);
	wmemset(ExtModel, 0, SIZE_CHAR_MAX);
	wmemset(ExtAnim, 0, SIZE_CHAR_MAX);
	wmemset(ExtDae, 0, SIZE_CHAR_MAX);

	LButtonDown = false;
	DownPoint = CPoint(0, 0);
	ItemCount = 0;
	SelectedNum = -1;
	FileType = FILE_TYPE_UNKNOWN;
	SelectDriveMode = false;
}

CSelectList::~CSelectList(){
}

bool CSelectList::SetParam(CConfig *config){

	BKColorA = config->BKColorA;
	BKColorR = config->BKColorR;
	BKColorG = config->BKColorG;
	BKColorB = config->BKColorB;
	TextColorA = config->TextColorA;
	TextColorR = config->TextColorR;
	TextColorG = config->TextColorG;
	TextColorB = config->TextColorB;
	wcscpy_s(ExtModel, SIZE_CHAR_MAX, config->ExtModel);
	wcscpy_s(ExtAnim, SIZE_CHAR_MAX, config->ExtAnim);
	wcscpy_s(ExtDae, SIZE_CHAR_MAX, config->ExtDae);

	return true;
}

bool CSelectList::CreateWnd(HWND ParentWnd, int x, int y, int w, int h, HDC memDC, HBITMAP bitmap ){

	SetParam(theApp->MainWindow->Config);

	WNDCLASSEX wcx;
	memset(&wcx, 0, sizeof(WNDCLASSEX));
	wcx.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.hInstance = NULL;
	wcx.hIcon = NULL;
	wcx.lpszMenuName = NULL;
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.lpfnWndProc = &CSelectList::WindowProc;
	wcx.lpszClassName = L"CLASS_SELECTLIST";
	RegisterClassEx(&wcx);

	PosX = x;
	PosY = y;
	Width = w;
	Height = h;
	m_hWnd = CreateWindowEx(WS_EX_COMPOSITED, L"CLASS_SELECTLIST", _T("select list"), WS_CHILD | WS_CLIPCHILDREN, PosX, PosY, Width, Height, ParentWnd, NULL, NULL, NULL);
	::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (UINT_PTR) this);

	int scroll_width = Width * 0.05f;
	int scroll_height = Height;
	int scroll_pos_x = Width - scroll_width;
	int scroll_pos_y = 0;
	ItemHeight = (int) ( (float) Height / (float) SELECT_LIST_ITEM_DISP_NUM );
	ItemCountMax = SELECT_LIST_ITEM_DISP_NUM;
	ItemBegin = 0;

	ScrollV = new CScrollBar();
	ScrollV->CreateWnd(m_hWnd, scroll_pos_x, scroll_pos_y, scroll_width, scroll_height, memDC, bitmap );

	Img_Model = new Gdiplus::Image(L"./pict/IconModel.png");
	Img_Anim = new Gdiplus::Image(L"./pict/IconAnim.png");
	Img_Dae = new Gdiplus::Image(L"./pict/IconDae.png");
	Img_Dir = new Gdiplus::Image(L"./pict/IconDir.png");

	MemDC = memDC;
	MemBMP = bitmap;

	::ShowWindow(m_hWnd, SW_SHOW);

	return true;
}

LRESULT CSelectList::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	CSelectList *select_list = (CSelectList *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
	if (select_list != NULL)
		select_list->SelectListProc(hwnd, message, wParam, lParam);

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CSelectList::SelectListProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	int delta = 0;
	int key = 0;

	switch (message){
	case WM_PAINT:
		OnPaint();
		break;
	case WM_SIZE:
		width = GET_X_LPARAM(lParam);
		height = GET_Y_LPARAM(lParam);
		OnSize((UINT)wParam, width, height);
		break;
	case WM_LBUTTONDOWN:
		SetFocus(m_hWnd);
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonDown((UINT)wParam, CPoint(x, y));
		break;
	case WM_LBUTTONDBLCLK:
		SetFocus(m_hWnd);
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonDBLCLK((UINT)wParam, CPoint(x, y));
		break;
	case WM_LBUTTONUP:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonUp((UINT)wParam, CPoint(x, y));
		break;
	case WM_MOUSEMOVE:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnMouseMove((UINT)wParam, CPoint(x, y));
		break;
	case WM_MOUSEWHEEL:
		SetFocus(m_hWnd);
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		key = GET_KEYSTATE_WPARAM(wParam);
		delta = GET_WHEEL_DELTA_WPARAM(wParam);
		OnMouseWheel(key, delta, CPoint(x, y));
		break;
	default:
		break;
	}

	return 0;
}

void CSelectList::OnSize(UINT nType, int cx, int cy){

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CSelectList::OnPaint(){

	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	OnDraw(hdc);
	::EndPaint(m_hWnd, &ps);
}

bool CSelectList::OnDraw(HDC hdc){

	HBITMAP OldBmp = (HBITMAP)::SelectObject(MemDC, MemBMP);

	Gdiplus::Graphics *gfc = new Gdiplus::Graphics(MemDC);
	gfc->Clear(Gdiplus::Color(BKColorA, BKColorR-20, BKColorG-20, BKColorB-20));

	DrawItem(gfc);

	::BitBlt(hdc, 0, 0, Width, Height, MemDC, 0, 0, SRCCOPY);

	delete gfc;

	return true;
}

bool CSelectList::GetItem(){

	::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, L"");
	if (theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_WRITE_MODEL){
		wchar_t file_name[SIZE_CHAR_MAX];
		wmemset(file_name, 0, SIZE_CHAR_MAX);
		wcscpy_s(file_name, UNDEFINED_FILE_NAME);
		wcscat_s(file_name, EXT_MODEL);
		::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, file_name);
	}
	if (theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_WRITE_ANIMATION){
		wchar_t file_name[SIZE_CHAR_MAX];
		wmemset(file_name, 0, SIZE_CHAR_MAX);
		wcscpy_s(file_name, UNDEFINED_FILE_NAME);
		wcscat_s(file_name, EXT_ANIM);
		::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, file_name);
	}

	if (SelectDriveMode == true){
		//ドライブ取得

		int flag = 1;
		DWORD drive = GetLogicalDrives();
		wchar_t path[SIZE_CHAR_MAX];
		wmemset(path, 0, SIZE_CHAR_MAX);

		int item_count = 0;
		for (int i = 0; i<25; i++, flag <<= 1){
			if (drive&flag){
				if (item_count == SelectedNum){
					wmemset(path, 0, SIZE_CHAR_MAX);
					wsprintf(path, L"%c:\\", 'A' + i);
					wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
					wmemset(CurrentPath, 0, SIZE_CHAR_MAX);
					wcscpy_s(CurrentPath, SIZE_CHAR_MAX, path);
				}
				item_count++;
			}
		}
		GetFileType();

		return true;
	}

	GetCurrentDirectory(SIZE_CHAR_MAX, CurrentPath);

	WIN32_FIND_DATA data;
	int item_count = 0;

	wchar_t path[SIZE_CHAR_MAX];
	wmemset(path, 0, SIZE_CHAR_MAX);
	wcscpy_s(path, SIZE_CHAR_MAX, CurrentPath);
	wcscat_s(path, L"/*.*");

	HANDLE hFile = FindFirstFile(path, &data);
	if (hFile != NULL){
		do{
			if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
				if (wcscmp(data.cFileName, L".") != 0 && wcscmp(data.cFileName, L"..") != 0){
					if (item_count >= ItemBegin){
						if (item_count == SelectedNum){
							wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
							wcscpy_s(CurrentFileName, SIZE_CHAR_MAX, data.cFileName);

							if (theApp->MainWindow->FileSelectDialog->OpenType != OPEN_TYPE_WRITE_MODEL && theApp->MainWindow->FileSelectDialog->OpenType != OPEN_TYPE_WRITE_ANIMATION)
								::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, L"");
						}
					}
					item_count++;
				}
			}
		} while (FindNextFile(hFile, &data));
	}

	hFile = FindFirstFile(path, &data);
	if (hFile != NULL){
		do{
			if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
				if (wcslen(data.cFileName) <= 4)
					continue;

				wchar_t ext[SIZE_CHAR_MAX];
				wmemset(ext, 0, SIZE_CHAR_MAX);
				wcscpy_s(ext, SIZE_CHAR_MAX, &data.cFileName[wcslen(data.cFileName) - 4]);
				if (wcscmp(ext, ExtModel) == 0 || wcscmp(ext, ExtAnim) == 0 || wcscmp(ext, ExtDae) == 0){
					if (item_count >= ItemBegin){
						if (item_count == SelectedNum){
							wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
							wcscpy_s(CurrentFileName, SIZE_CHAR_MAX, data.cFileName);

							if ((wcscmp(ext, ExtModel) == 0 || wcscmp(ext, ExtDae) == 0) && theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_MODEL)
								::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, CurrentFileName);
							if (wcscmp(ext, ExtModel) == 0 && (theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_MODEL || theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_WRITE_MODEL))
								::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, CurrentFileName);
							if (wcscmp(ext, ExtAnim) == 0 && (theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_ANIMATION || theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_WRITE_ANIMATION))
								::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, CurrentFileName);
						}
					}
					item_count++;
				}
			}
		} while (FindNextFile(hFile, &data));
	}
	ItemCount = item_count;
	GetFileType();
	FindClose(hFile);

	return true;
}

bool CSelectList::DrawItem(Gdiplus::Graphics *gfc){

	if (SelectDriveMode == true){
		//ドライブ取得

		Gdiplus::SolidBrush *brush = new Gdiplus::SolidBrush(Gdiplus::Color(TextColorA, TextColorR, TextColorG, TextColorB));
		Gdiplus::SolidBrush *brush1 = new Gdiplus::SolidBrush(Gdiplus::Color(BKColorA, BKColorR - 40, BKColorG - 40, BKColorB - 40));
		Gdiplus::Font *font = new Gdiplus::Font(L"メイリオ", (REAL)((double)ItemHeight * 0.6f / ScaleX));
		Gdiplus::StringFormat *format = new Gdiplus::StringFormat(StringFormatFlagsNoWrap);

		int flag = 1;
		DWORD drive = GetLogicalDrives();
		wchar_t path[SIZE_CHAR_MAX];
		wmemset(path, 0, SIZE_CHAR_MAX);

		int item_count = 0;
		for (int i = 0; i<25; i++, flag <<= 1){
			if (drive&flag){

				int pos_x = ItemHeight * 2;
				int pos_y = ItemHeight * (item_count - ItemBegin);
				int width = Width;
				int height = ItemHeight;

				if (item_count == SelectedNum){
					wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
					wmemset(CurrentPath, 0, SIZE_CHAR_MAX);
					wcscpy_s(CurrentPath, SIZE_CHAR_MAX, path);
					gfc->FillRectangle(brush1, 0, ItemHeight * (SelectedNum - ItemBegin), width, height);
					::SetWindowTextW(theApp->MainWindow->FileSelectDialog->EditWnd->m_hWnd, L"");
				}

				wsprintf(path, L"%c:\\", 'A' + i);
				gfc->DrawString(path, -1, font, RectF(pos_x, pos_y, width, height), format, brush);
				gfc->DrawImage(Img_Dir, ItemHeight * 0.5, ItemHeight * (item_count - ItemBegin), height, height);

				item_count++;
			}
		}
		ScrollV->BarHeight = (int)(Height * (float)SELECT_LIST_ITEM_DISP_NUM / (float)item_count);

		if (item_count > SELECT_LIST_ITEM_DISP_NUM)
			::ShowWindow(ScrollV->m_hWnd, SW_SHOW);
		else
			::ShowWindow(ScrollV->m_hWnd, SW_HIDE);

		delete font;
		delete format;
		delete brush1;
		delete brush;

		return true;
	}
	GetFileType();

	GetCurrentDirectory(SIZE_CHAR_MAX, CurrentPath);

	Gdiplus::SolidBrush *brush = new Gdiplus::SolidBrush(Gdiplus::Color(TextColorA, TextColorR, TextColorG, TextColorB));
	Gdiplus::SolidBrush *brush1 = new Gdiplus::SolidBrush(Gdiplus::Color(BKColorA, BKColorR - 40, BKColorG - 40, BKColorB - 40));
	Gdiplus::Font *font = new Gdiplus::Font(L"メイリオ", (REAL)((double)ItemHeight * 0.6f / ScaleX));
	Gdiplus::StringFormat *format = new Gdiplus::StringFormat(StringFormatFlagsNoWrap);

	WIN32_FIND_DATA data;
	memset(&data, 0, sizeof(WIN32_FIND_DATA));

	int item_count = 0;

	wchar_t path[SIZE_CHAR_MAX];
	wmemset(path, 0, SIZE_CHAR_MAX);
	wcscpy_s(path, SIZE_CHAR_MAX, CurrentPath);
	wcscat_s(path, L"\\*.*");

	HANDLE hFile = FindFirstFile(path, &data);
	if (hFile != NULL){
		do{
			if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
				if (wcscmp(data.cFileName, L".") != 0 && wcscmp(data.cFileName, L"..") != 0){
					if (item_count >= ItemBegin){
						int pos_x = ItemHeight * 2;
						int pos_y = ItemHeight * (item_count - ItemBegin);
						int width = Width;
						int height = ItemHeight;

						if (item_count == SelectedNum){
							gfc->FillRectangle(brush1, 0, ItemHeight * (SelectedNum - ItemBegin), width, height);
							wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
							wcscpy_s(CurrentFileName, SIZE_CHAR_MAX, data.cFileName);
						}

						gfc->DrawString(data.cFileName, -1, font, RectF(pos_x, pos_y, width, height), format, brush);
						gfc->DrawImage(Img_Dir, ItemHeight * 0.5, ItemHeight * (item_count - ItemBegin), height, height);
					}
					item_count++;
				}
			}
		}while(FindNextFile(hFile, &data));
	}

	memset(&data, 0, sizeof(WIN32_FIND_DATA));
	hFile = FindFirstFile(path, &data);
	if (hFile != NULL){
		do{
			if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
				if (wcslen(data.cFileName) <= 4)
					continue;

				wchar_t ext[SIZE_CHAR_MAX];
				wmemset(ext, 0, SIZE_CHAR_MAX);
				wcscpy_s(ext, SIZE_CHAR_MAX, &data.cFileName[wcslen(data.cFileName) - 4]);
				if (wcscmp(ext, ExtModel) == 0 || wcscmp(ext, ExtAnim) == 0 || wcscmp(ext, ExtDae) == 0){
					if (item_count >= ItemBegin){
						int pos_x = ItemHeight * 2;
						int pos_y = ItemHeight * (item_count - ItemBegin);
						int width = Width;
						int height = ItemHeight;

						if (item_count == SelectedNum){
							wmemset(CurrentFileName, 0, SIZE_CHAR_MAX);
							wcscpy_s(CurrentFileName, SIZE_CHAR_MAX, data.cFileName);
							gfc->FillRectangle(brush1, 0, ItemHeight * (SelectedNum - ItemBegin), width, height);
						}

						gfc->DrawString(data.cFileName, -1, font, RectF(pos_x, pos_y, width, height), format, brush);

						if (wcscmp(ext, ExtModel) == 0 )
							gfc->DrawImage(Img_Model, ItemHeight * 0.5, ItemHeight * (item_count - ItemBegin), height, height);
						if (wcscmp(ext, ExtAnim) == 0)
							gfc->DrawImage(Img_Anim, ItemHeight * 0.5, ItemHeight * (item_count - ItemBegin), height, height);
						if (wcscmp(ext, ExtDae) == 0)
							gfc->DrawImage(Img_Dae, ItemHeight * 0.5, ItemHeight * (item_count - ItemBegin), height, height);
					}
					item_count++;
				}
			}
		} while (FindNextFile(hFile, &data));
	}
	ItemCount = item_count;
	GetFileType();

	ScrollV->BarHeight = (int)(Height * (float) SELECT_LIST_ITEM_DISP_NUM / (float)item_count);

	if (item_count > SELECT_LIST_ITEM_DISP_NUM)
		::ShowWindow(ScrollV->m_hWnd, SW_SHOW);
	else
		::ShowWindow(ScrollV->m_hWnd, SW_HIDE);


	FindClose(hFile);

	delete brush;
	delete brush1;
	delete font;
	delete format;

	return true;
}

bool CSelectList::GetFileType(){

	FileType = FILE_TYPE_UNKNOWN;
	if (SelectedNum >= 0){
		if (wcslen(CurrentFileName) <= 4)
			FileType = FILE_TYPE_DIRECTORY;
		else{
			wchar_t ext[SIZE_CHAR_MAX];
			wmemset(ext, 0, SIZE_CHAR_MAX);
			wcscpy_s(ext, SIZE_CHAR_MAX, &CurrentFileName[wcslen(CurrentFileName) - 4]);
			if (wcscmp(ext, EXT_MODEL) == 0)
				FileType = FILE_TYPE_MODEL;
			else if (wcscmp(ext, EXT_ANIM) == 0)
				FileType = FILE_TYPE_ANIMATION;
			else if (wcscmp(ext, EXT_DAE) == 0)
				FileType = FILE_TYPE_COLLADA;
			else
				FileType = FILE_TYPE_DIRECTORY;
		}
	}

	return true;
}

void CSelectList::OnLButtonDBLCLK(UINT nFlag, CPoint point){

	LButtonDown = true;

	int pos_x = point.x;
	int pos_y = point.y;

	/////////////////////////////////////////////////////////

	SelectedNum = SelectItem(point);
	GetItem();
	DBLCLKAction();

	::ClientToScreen(m_hWnd, &point);
	DownPoint = point;
	LButtonDown = true;

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

bool CSelectList::DBLCLKAction(){

	if (FileType == FILE_TYPE_DIRECTORY){

		ItemCount = 0;
		ItemBegin = 0;
		SelectedNum = -1;
		ScrollV->BarHeight = 0;
		ScrollV->BarPosY = 0;

		if (SelectDriveMode == true)
			SelectDriveMode = false;

		wcscat_s(CurrentPath, SIZE_CHAR_MAX, L"\\");
		wcscat_s(CurrentPath, SIZE_CHAR_MAX, CurrentFileName);
		SetCurrentDirectory(CurrentPath);

		::InvalidateRect(theApp->MainWindow->FileSelectDialog->m_hWnd, NULL, false);
		::UpdateWindow(theApp->MainWindow->FileSelectDialog->m_hWnd);
	}
	if (FileType == FILE_TYPE_COLLADA && theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_MODEL){
		theApp->MainWindow->FileSelectDialog->ButtonOK->Action();
	}
	if (FileType == FILE_TYPE_MODEL && theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_MODEL){
		theApp->MainWindow->FileSelectDialog->ButtonOK->Action();
	}
	if (FileType == FILE_TYPE_ANIMATION && theApp->MainWindow->FileSelectDialog->OpenType == OPEN_TYPE_LOAD_ANIMATION){
		theApp->MainWindow->FileSelectDialog->ButtonOK->Action();
	}

	return true;
}

void CSelectList::OnLButtonDown(UINT nFlag, CPoint point){

	LButtonDown = true;

	int pos_x = point.x;
	int pos_y = point.y;

	/////////////////////////////////////////////////////////

	SelectedNum = SelectItem(point);
	GetItem();

	::ClientToScreen(m_hWnd, &point);
	DownPoint = point;
	LButtonDown = true;
	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

int CSelectList::SelectItem(CPoint point){

	int selected_count = ItemBegin + point.y / ItemHeight;

	return selected_count;
}

void CSelectList::OnLButtonUp(UINT nFlag, CPoint point){

	LButtonDown = false;

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CSelectList::OnMouseMove(UINT nFlag, CPoint point){

	if (LButtonDown == true){
		::ClientToScreen(m_hWnd, &point);
		int pos_x = point.x - DownPoint.x;
		int pos_y = point.y - DownPoint.y;
		DownPoint = point;

		::InvalidateRect(m_hWnd, NULL, false);
		::UpdateWindow(m_hWnd);
	}
}

void CSelectList::OnMouseWheel(UINT nFlag, int zDelta, CPoint point){

	if (ScrollV->BarHeight < ScrollV->Height){

		ScrollV->BarPosY -= zDelta * 0.1f;
		if (ScrollV->BarPosY < 0)
			ScrollV->BarPosY = 0;
		if (ScrollV->BarPosY > ScrollV->Height - ScrollV->BarHeight)
			ScrollV->BarPosY = ScrollV->Height - ScrollV->BarHeight;

		ScrollV->UpdateScrollBar();
	}

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

//////////////////////////////////////////////////////////////////////////////////////////

CFileSelectDialog::CFileSelectDialog(){

	HDC screen = GetDC(0);
	dpiX = (float)GetDeviceCaps(screen, LOGPIXELSX);
	dpiY = (float)GetDeviceCaps(screen, LOGPIXELSY);
	ReleaseDC(0, screen);

	ScaleX = (dpiX / 96.0f);
	ScaleY = (dpiY / 96.0f);

	DisplayWidth = ::GetSystemMetrics(SM_CXSCREEN);
	DisplayHeight = ::GetSystemMetrics(SM_CYSCREEN);
	FrameEdgeX = 8;
	FrameEdgeY = 8;

	TransparentR = COLOR_TRANSPARENT_R;
	TransparentG = COLOR_TRANSPARENT_G;
	TransparentB = COLOR_TRANSPARENT_B;

	CRect	rectDesktop;
	::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktop, 0);

	Width = (int)((double)DisplayWidth / 1.5);
	Height = (int)((double)DisplayHeight / 1.5);
	TitleBarHeight = (int)((double)DisplayHeight / 30.0);
	TaskBarHeight = DisplayHeight - rectDesktop.bottom;

	BKColorA = 255;
	BKColorR = 180;
	BKColorG = 150;
	BKColorB = 150;
	TextColorA = 255;
	TextColorR = 100;
	TextColorG = 70;
	TextColorB = 70;

	PosX = (DisplayWidth - Width) / 2;
	PosY = (DisplayHeight - Height) / 2;

	LButtonDown = false;
	GetCaption = false;
	DownPoint = CPoint(0, 0);

	OpenType = OPEN_TYPE_UNKNOWN;
}

CFileSelectDialog::~CFileSelectDialog(){
}

bool CFileSelectDialog::SetParam(CConfig *config){

	BKColorA = config->BKColorA;
	BKColorR = config->BKColorR;
	BKColorG = config->BKColorG;
	BKColorB = config->BKColorB;
	BarColorA = config->BarColorA;
	BarColorR = config->BarColorR;
	BarColorG = config->BarColorG;
	BarColorB = config->BarColorB;
	TextColorA = config->TextColorA;
	TextColorR = config->TextColorR;
	TextColorG = config->TextColorG;
	TextColorB = config->TextColorB;

	return true;
}

bool CFileSelectDialog::CreateWnd( HWND ParentWnd, int x, int y, int w, int h ){

	SetParam(theApp->MainWindow->Config);

	WNDCLASSEX wcx;
	memset(&wcx, 0, sizeof(WNDCLASSEX));
	wcx.style = CS_HREDRAW | CS_VREDRAW;
	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.hInstance = NULL;
	wcx.hIcon = NULL;
	wcx.lpszMenuName = NULL;
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.lpfnWndProc = &CFileSelectDialog::WindowProc;
	wcx.lpszClassName = L"CLASS_DIALOG";
	RegisterClassEx(&wcx);

	PosX = x;
	PosY = y;
	Width = w;
	Height = h;
	m_hWnd = CreateWindowEx(WS_EX_COMPOSITED, L"CLASS_DIALOG", _T("Select File"), WS_POPUP | WS_CLIPCHILDREN, PosX, PosY, Width, Height, GetDesktopWindow(), NULL, NULL, NULL);
	::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (UINT_PTR) this);

	BitmapWidth = DisplayWidth;
	BitmapHeight = DisplayHeight;

	BITMAPINFO  bmi = { 0 };
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = BitmapWidth;
	bmi.bmiHeader.biHeight = BitmapHeight;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 32;

	MemBMP = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, (void **)&AlphaBMP, 0, 0);
	::DeleteDC(MemDC);

	HDC hdc = ::GetDC(m_hWnd);
	MemDC = CreateCompatibleDC(hdc);
	::SelectObject(MemDC, MemBMP);
	DeleteDC(hdc);

	int box_pos_x = (int) ( Width * 0.05f );
	int box_pos_y = (int)(Height * 0.25f);
	int box_width = (Width - box_pos_x * 2);
	int box_height = (Height * 0.45f);

	SelectList = new CSelectList();
	SelectList->CreateWnd( m_hWnd, box_pos_x, box_pos_y, box_width, box_height, MemDC, MemBMP );

	EditWnd = new CEditWindow();
	EditWnd->CreateWnd(m_hWnd, box_pos_x, box_pos_y + box_height + TitleBarHeight * 0.5f, box_width, TitleBarHeight);

	int confirm_width = DisplayWidth * 0.4f;
	int confirm_height = DisplayHeight * 0.2f;
	int confirm_pos_x = (int) ((float) DisplayWidth - (float) confirm_width ) / 2.0f;
	int confirm_pos_y = (int)((float)DisplayHeight - (float)confirm_height) / 2.0f;
	ConfirmDialog = new CConfirmDialog();
	ConfirmDialog->CreateWnd(m_hWnd, confirm_pos_x, confirm_pos_y, confirm_width, confirm_height );

	int button_size = (int)((double)TitleBarHeight * 1.2f);
	x = Width * 0.05f;
	y = Height * 0.1f;
	ButtonDir = new CButtonDir();
	ButtonDir->CreateWnd(x, y, button_size, button_size, m_hWnd);
	ButtonDir->SetImage(L"./pict/ButtonDir.png", L"./pict/ButtonDirDown.png");
	ButtonDir->SetColor(BKColorA, BKColorR, BKColorG, BKColorB);

	button_size = (int)((double)TitleBarHeight * 0.8f);
	x = Width - button_size - (int)((double)TitleBarHeight * 0.5f);
	y = (int)((double)TitleBarHeight * 0.1f);
	ButtonDialogClose = new CButtonDialogClose();
	ButtonDialogClose->CreateWnd(x, y, button_size, button_size, m_hWnd);
	ButtonDialogClose->SetImage(L"./pict/ButtonClose.png", L"./pict/ButtonCloseDown.png");

	int button_width = (int)((double)TitleBarHeight * 3.0f);
	int button_height = (int)((double)TitleBarHeight * 1.0f);

	x = Width - button_width * 2 - (int)((double)TitleBarHeight * 1.0f);
	y = Height - button_height - (int)((double)TitleBarHeight * 0.3f);
	ButtonCancel = new CButtonCancel();
	ButtonCancel->CreateWnd(x, y, button_width, button_height, m_hWnd);
	ButtonCancel->SetImage(L"./pict/ButtonCancel.png", L"./pict/ButtonCancelDown.png");
	ButtonCancel->SetColor(BKColorA, BKColorR, BKColorG, BKColorB);

	x += button_width + (int)((double)TitleBarHeight * 0.2f);
	ButtonOK = new CButtonOK();
	ButtonOK->CreateWnd(x, y, button_width, button_height, m_hWnd);
	ButtonOK->SetImage(L"./pict/ButtonOK.png", L"./pict/ButtonOKDown.png");
	ButtonOK->SetColor(BKColorA, BKColorR, BKColorG, BKColorB);

	::ShowWindow(m_hWnd, SW_HIDE);

	return true;
}

LRESULT CFileSelectDialog::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	CFileSelectDialog *dialog = (CFileSelectDialog *) ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
	if (dialog != NULL)
		dialog->FileSelectDialogProc(hwnd, message, wParam, lParam);

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CFileSelectDialog::FileSelectDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;

	switch (message){
	case WM_PAINT:
		OnPaint();
		break;
	case WM_SIZE:
		width = GET_X_LPARAM(lParam);
		height = GET_Y_LPARAM(lParam);
		OnSize((UINT)wParam, width, height);
		break;
	case WM_LBUTTONDOWN:
		if (theApp->MainWindow->FileSelectDialog->ConfirmDialog->ConfirmLoop != true)
			SetFocus(m_hWnd);
		else
			SetFocus(theApp->MainWindow->FileSelectDialog->ConfirmDialog->m_hWnd);
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonDown((UINT)wParam, CPoint(x, y));
		break;
	case WM_LBUTTONUP:
		if (theApp->MainWindow->FileSelectDialog->ConfirmDialog->ConfirmLoop != true)
			SetFocus(m_hWnd);
		else
			SetFocus(theApp->MainWindow->FileSelectDialog->ConfirmDialog->m_hWnd);
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnLButtonUp((UINT)wParam, CPoint(x, y));
		break;
	case WM_MOUSEMOVE:
		x = GET_X_LPARAM(lParam);
		y = GET_Y_LPARAM(lParam);
		OnMouseMove((UINT)wParam, CPoint(x, y));
		break;
	default:
		break;
	}

	return 0;
}

void CFileSelectDialog::OnSize(UINT nType, int cx, int cy){

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CFileSelectDialog::OnPaint(){

	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	OnDraw(hdc);
	::EndPaint(m_hWnd, &ps);
}

bool CFileSelectDialog::OnDraw(HDC hdc){

	HBITMAP OldBmp = (HBITMAP)::SelectObject(MemDC, MemBMP);

	int width = Width;
	int height = Height;

	Gdiplus::Graphics *gfc = new Gdiplus::Graphics(MemDC);
	gfc->Clear(Gdiplus::Color(255, BKColorR, BKColorG, BKColorB));

	Gdiplus::SolidBrush *brush1 = new Gdiplus::SolidBrush(Gdiplus::Color(BarColorA, BarColorR, BarColorG, BarColorB));
	gfc->FillRectangle(brush1, 0, 0, width, TitleBarHeight);
	delete brush1;

	Gdiplus::Pen *pen1 = new Gdiplus::Pen(Gdiplus::Color(BarColorA, BarColorR, BarColorG, BarColorB), 8);
	gfc->DrawLine(pen1, 0, 0, Width, 0);
	gfc->DrawLine(pen1, width, 0, width, height);
	gfc->DrawLine(pen1, width, height, 0, height);
	gfc->DrawLine(pen1, 0, height, 0, 0);
	delete pen1;

	gfc->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
	Gdiplus::Font *font = new Gdiplus::Font(L"メイリオ", (REAL)((double)TitleBarHeight * 0.5f / ScaleX));

	size_t size;
	Gdiplus::SolidBrush *brush3 = new Gdiplus::SolidBrush(Gdiplus::Color(BKColorA, BKColorR + 50, BKColorG + 50, BKColorB + 50));
	Gdiplus::StringFormat *format = new Gdiplus::StringFormat(StringFormatFlagsNoWrap);

	wchar_t wstr[SIZE_CHAR_MAX];
	wmemset(wstr, 0, SIZE_CHAR_MAX );
	if (OpenType == OPEN_TYPE_LOAD_MODEL){
		wcscpy_s(wstr, SIZE_CHAR_MAX, L"モデルファイル(");
		wcscat_s(wstr, SIZE_CHAR_MAX, EXT_MODEL);
		wcscat_s(wstr, SIZE_CHAR_MAX, L" ");
		wcscat_s(wstr, SIZE_CHAR_MAX, EXT_DAE);
		wcscat_s(wstr, SIZE_CHAR_MAX, L")を開く");
	}
	else if (OpenType == OPEN_TYPE_WRITE_MODEL){
		wcscpy_s(wstr, SIZE_CHAR_MAX, L"モデルファイル(");
		wcscat_s(wstr, SIZE_CHAR_MAX, EXT_MODEL);
		wcscat_s(wstr, SIZE_CHAR_MAX, L")を書き出し");
	}
	else if (OpenType == OPEN_TYPE_LOAD_ANIMATION){
		wcscpy_s(wstr, SIZE_CHAR_MAX, L"アニメーションファイル(");
		wcscat_s(wstr, SIZE_CHAR_MAX, EXT_ANIM);
		wcscat_s(wstr, SIZE_CHAR_MAX, L")を開く");
	}
	else if (OpenType == OPEN_TYPE_WRITE_ANIMATION){
		wcscpy_s(wstr, SIZE_CHAR_MAX, L"アニメーションファイル(");
		wcscat_s(wstr, SIZE_CHAR_MAX, EXT_ANIM);
		wcscat_s(wstr, SIZE_CHAR_MAX, L")を書き出し");
	}
	gfc->DrawString(wstr, -1, font, RectF((double)width / 50.0, (double)TitleBarHeight * 0.1f, (REAL)width, (REAL)TitleBarHeight), format, brush3);


	//現在のパスを表示
	GetCurrentDirectory(SIZE_CHAR_MAX, SelectList->CurrentPath);

	gfc->DrawString( SelectList->CurrentPath, -1, font, RectF(Width * 0.12f, Height * 0.12f, Width * 0.8f, Height * 0.8f), format, brush3);

	ButtonDialogClose->OnDraw(MemDC, ButtonDialogClose->PosX, ButtonDialogClose->PosY, ButtonDialogClose->Width, ButtonDialogClose->Height);
	ButtonDir->OnDraw(MemDC, ButtonDir->PosX, ButtonDir->PosY, ButtonDir->Width, ButtonDir->Height);
	ButtonOK->OnDraw(MemDC, ButtonOK->PosX, ButtonOK->PosY, ButtonOK->Width, ButtonOK->Height);
	ButtonCancel->OnDraw(MemDC, ButtonCancel->PosX, ButtonCancel->PosY, ButtonCancel->Width, ButtonCancel->Height);

	::BitBlt(hdc, 0, 0, width, height, MemDC, 0, 0, SRCCOPY);

	delete brush3;
	delete font;
	delete format;
	delete gfc;

	return true;
}

void CFileSelectDialog::OnLButtonDown(UINT nFlag, CPoint point){

	LButtonDown = true;
	::SetCapture(m_hWnd);

	if (point.y < TitleBarHeight)
		GetCaption = true;
	else
		GetCaption = false;

	int pos_x = point.x;
	int pos_y = point.y + FrameEdgeY * 2 + ::GetSystemMetrics(SM_CYCAPTION);

	/////////////////////////////////////////////////////////

	::ClientToScreen(m_hWnd, &point);
	DownPoint = point;
	LButtonDown = true;
	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CFileSelectDialog::OnLButtonUp(UINT nFlag, CPoint point){

	::ReleaseCapture();
	LButtonDown = false;
	GetCaption = false;

	::InvalidateRect(m_hWnd, NULL, false);
	::UpdateWindow(m_hWnd);
}

void CFileSelectDialog::OnMouseMove(UINT nFlag, CPoint point){

	if (LButtonDown == true && GetCaption == true){
		::ClientToScreen(m_hWnd, &point);
		PosX += point.x - DownPoint.x;
		PosY += point.y - DownPoint.y;
		DownPoint = point;
		::SetWindowPos(m_hWnd, HWND_TOP, PosX, PosY, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
		::InvalidateRect(m_hWnd, NULL, false);
		::UpdateWindow(m_hWnd);
	}
}
