﻿private import win32.windows;
private import win32.commctrl;
private import std.string;

void process_messages()
{
	for( MSG msg; PeekMessageA( &msg, null, 0, 0, PM_REMOVE ); )
	{
		TranslateMessage( &msg );
		DispatchMessageA( &msg );
	}
}

class Dialog
{
public:
	HWND hwnd()
	{
		return handle;
	}

protected:
	void on_init()   {}
	bool on_ok()     { return false; }
	bool on_cancel() { return false; }
	bool on_command( UINT cmd ) { return false; }
	bool on_message( UINT msg, WPARAM wp, LPARAM lp ) { return false; }

	extern(Windows) private static BOOL
		static_dlg_proc( HWND dlg, UINT msg, WPARAM wp, LPARAM lp )
	{
		if( msg == WM_INITDIALOG )
		{
			SetWindowLong( dlg, GWL_USERDATA, lp );

			Dialog ptr = cast(Dialog) cast(Dialog*) lp;
			ptr.handle = dlg;
			ptr.on_init();
			return FALSE;
		}

		Dialog ptr = cast(Dialog) cast(Dialog*) GetWindowLong(dlg,GWL_USERDATA);
		if( ptr is null )
			return FALSE;

		if( msg == WM_COMMAND )
			if( LOWORD(wp) == IDOK )
				return ptr.on_ok();
			else if( LOWORD(wp) == IDCANCEL )
				return ptr.on_cancel();
			else
				return ptr.on_command( LOWORD(wp) );
		return ptr.on_message(msg,wp,lp);
	}

protected:
	HWND handle;
	void BeginModeless( DLGTEMPLATE* dlg_template, HWND parent )
	{
		CreateDialogIndirectParam(
			GetModuleHandle(null),
			dlg_template,
			parent,
			&static_dlg_proc,
			cast(LPARAM) cast(Dialog*) this
		);
	}

	int BeginModal( DLGTEMPLATE* dlg_template, HWND parent )
	{
		return DialogBoxIndirectParam(
			GetModuleHandle(null),
			dlg_template,
			parent,
			&static_dlg_proc,
			cast(LPARAM) cast(Dialog*) this
		);
	}

	void set_item_text( int ID, string str )
	{
		SetDlgItemTextA( handle, ID, toStringz(str) );
	}

	int send_item_msg( int ID, UINT msg, WPARAM wp=0, LPARAM lp=0 )
	{
		return SendDlgItemMessage( handle, ID, msg, wp, lp );
	}
}

//------------------------------------------------------------
// #2025 [ファイルを操作中]
//   2006 : 書庫名
//   2007 : ファイル名（パス無し）
//   2024 : プログレスバー
//      2 : キャンセルボタン
//------------------------------------------------------------

class ProgressDlg : Dialog
{
	this( DLGTEMPLATE* dlg_template, HWND parent )
	{
		BeginModeless( dlg_template, parent );
	}

	void set_arcname ( string str ){ set_item_text( 2006, str ); }
	void set_filename( string str ){ set_item_text( 2007, str ); }
	void set_max( real m ) { max = m; }
	void set_pos( real p ) { send_item_msg(2024,PBM_SETPOS,cast(int)(p/max*65535),0); }

	bool closed()
	{
		return !alive;
	}

	void close()
	{
		if( !closed )
			on_cancel();
	}

protected:
	bool alive = false;
	real max = 1.0;

	override void on_init()
	{
		alive = true;
		send_item_msg( 2024, PBM_SETRANGE, 0, MAKELPARAM(0,65535) );

		// センタリング
		RECT rc,pr;
		GetWindowRect( handle, &rc );
		HWND par = GetParent(handle);
		if( par )
			GetWindowRect( par, &pr );
		else
			SystemParametersInfo( SPI_GETWORKAREA, 0, &pr, 0 );
		SetWindowPos( handle, null,
			pr.left + ( (pr.right-pr.left)-(rc.right-rc.left) )/2,
			pr.top  + ( (pr.bottom-pr.top)-(rc.bottom-rc.top) )/2,
			0, 0, SWP_NOSIZE|SWP_NOZORDER );

		// 表示
		ShowWindow(handle,SW_SHOW);
		UpdateWindow(handle);
	}

	override bool on_cancel()
	{
		alive = false;
		DestroyWindow(handle);
		return true;
	}
}

//------------------------------------------------------------
// #2000  [ファイルの上書き確認]
//   2006 書庫内ファイル名
//   2009 ファイルサイズ   564,590 Byte
//   2010 更新日時         2004\08\27 03:57:18
//   2007 外部ファイル名
//   2011 ファイルサイズ
//   2012 更新日時
//
//   2002:上書き  2004:日付が新しければ上書き 2003:上書きしない
//
//      1: OKボタン
//   2005: 以降全てに適用ボタン
//      2: キャンセルボタン
//------------------------------------------------------------

