﻿module Win32SDK;

import std.c.windows.windows;
import std.string;

const int IDC_BTNCLICK = 101;
const int IDC_BTNDONTCLICK = 102;

extern(Windows)
int WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	    case WM_COMMAND:
	    {
		switch (LOWORD(wParam))
		{
		    case IDC_BTNCLICK:
			if (HIWORD(wParam) == BN_CLICKED)
				MessageBoxW(hWnd,"Well done","欢迎Welcome",MB_OK|MB_ICONINFORMATION);
                        
			break;
		    case IDC_BTNDONTCLICK:
			if (HIWORD(wParam) == BN_CLICKED)
			{
			    MessageBoxW(hWnd,"Told you don't touch me!","Prepare to GP error",MB_OK|MB_ICONEXCLAMATION);
			    *cast(int*) null = 666;
             
			}
			break;
		}
		break;
	    }

	    case WM_PAINT:
	    {
		
		static const wchar[] text="你看我漂亮不Don't u think I'am cool?";
		PAINTSTRUCT ps;
		HDC dc = BeginPaint(hWnd, &ps);		
		RECT r;
		GetClientRect(hWnd, &r);
		HFONT font = CreateFontW(80, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE,
			FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
			DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
		HGDIOBJ old = SelectObject(dc, cast(HGDIOBJ) font);
		SetTextAlign(dc, TA_CENTER | TA_BASELINE);
		TextOutW(dc, r.right / 2, r.bottom / 2, text, text.length);
		SelectObject(dc, old);
		EndPaint(hWnd, &ps);
		break;
	    }
	    case WM_DESTROY:
		PostQuitMessage(0);
		break;

	    default:
		break;
	}
	return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}

extern(Windows)
{
	int MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT);
    HWND CreateWindowExW(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
    
}



class WinClass
{
	public:
	this(HINSTANCE hInst)
	{
		_hInst=hInst;
		Init;
		Register;
	}
	HINSTANCE getHINSTANCE()
	{
		return _class.hInstance;
	}
	void setHINSTANCE(HINSTANCE hInst)
	{
		_class.hInstance=hInst;
	}
	void setClassName(string className)
	{
		_class.lpszClassName=toStringz(className);
	}
	LPCSTR getClassName()
	{
		return _class.lpszClassName;
	}


	private:
	void Init()
	{
		
		_class.lpfnWndProc=&WindowProc;
		_class.hInstance=_hInst;
		_class.lpszClassName="Default";
		//_class.cbSize=WNDCLASSA.sizeof;
		_class.hCursor=LoadCursorA(cast(HINSTANCE)null,IDC_ARROW);
		_class.hbrBackground=cast(HBRUSH)(COLOR_WINDOW+1);
		_class.style=0;
		_class.cbClsExtra=0;
		_class.cbWndExtra=0;
		_class.hIcon=LoadIconA(cast(HINSTANCE)null,IDI_APPLICATION);
		//_class.hIconSm=null;
		_class.lpszMenuName=null;
	}
	
	void Register()
	{
		if(RegisterClassA(&_class)==0)
		MessageBoxA(null,"RegisterClass failed!","Error",MB_OK|MB_ICONEXCLAMATION);
	}
	private:
	WNDCLASSA _class;
	HINSTANCE _hInst;
	
}
class WinFrame
{
	this(WinClass classMaker,string title="Default WinApp")
	{
		Init(_classMaker,title);
		Create;
	}
	HWND Create()
	{
		HWND hwnd=CreateWindowExA(
				_exStyle,
				_className,
				toStringz(_title),
				_style,
				_x,
				_y,
				_width,
				_height,
				_hWndParent,
				_hMenu,
				_hInst,
				_data);
		if(hwnd is null)
			MessageBoxA(null,"WinApp Creation Failed","Error",MB_OK|MB_ICONEXCLAMATION);
		return hwnd;
	}
	HWND getHWND()
	{
		return _hWndParent;
	}
	void setTitle(string title)
	{
		_title=title;
		
	}
	string getTitle()
	{
		return _title;
	}
	HINSTANCE getHINSTANCE()
	{
		return _hInst;
	}
	private:
	void Init(WinClass classMaker,string title)
	{
		if(classMaker!is null)
			_classMaker=classMaker;
		_hInst=_classMaker.getHINSTANCE;
		_style=WS_OVERLAPPEDWINDOW;
		_exStyle=0;
		_className=_classMaker.getClassName;
		_x=CW_USEDEFAULT;
		_y=0;
		_width=CW_USEDEFAULT;
		_height=0;
		_hWndParent=null;
		_hMenu=null;
		_data=null;
		_title=title;
		
	}
	
	private:
	HINSTANCE	_hInst;
	LPCSTR		_className;
	DWORD		_style;
	DWORD		_exStyle;
	int			_x;
	int			_y;
	int			_width;
	int			_height;
	HWND		_hWndParent;
	HMENU		_hMenu;
	void*		_data;
	string		_title;
	WinClass _classMaker;
}
class WinApp
{
	public:
	this(HINSTANCE hInst=null,HWND h=null,int cmdShow=1)
	{
		_hInst=hInst;
		_hWnd=h;
		_cmdShow=cmdShow;
		
		CreateControls;
		Display;
		
	}
	void Display()
	{
		assert(_hWnd !is null);
		ShowWindow(_hWnd,_cmdShow);
		UpdateWindow(_hInst);
	}
	void CreateControls()
	{
		HWND btnClick, btnDontClick;
	
	
	
		btnClick=CreateWindowExW(0,"BUTTON","&Click Me!",
			WS_CHILD|WS_VISIBLE,0,0,100,25,_hWnd,cast(HMENU)IDC_BTNCLICK,_hInst,null);
    
	
		btnDontClick=CreateWindowExW(0,"BUTTON","&Don't touch me!",
			WS_CHILD|WS_VISIBLE,110,0,100,25,_hWnd,cast(HMENU)IDC_BTNDONTCLICK,_hInst,null);
    
	}
	int MessageLoop()
	{
		MSG msg;
		while (GetMessageA(&msg, cast(HWND) null, 0, 0))
		{
			TranslateMessage(&msg);
			DispatchMessageA(&msg);
		}
	
		return msg.wParam;
	}
	alias MessageLoop Run;
	private:
	HINSTANCE _hInst;
	HWND _hWnd;
	int _cmdShow;
	
}
