#include <windows.h>

#define JMENOTRIDYOKNA "WinAPI_TestWindow"

#define EDIT_NAZEVSOUBORU	1
#define BTN_UKAZOBRAZEK		2
#define BTN_KONEC			3

HBITMAP hObrazek;

LRESULT CALLBACK ProceduraHlavnihoOkna(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

int WINAPI WinMain(
  HINSTANCE hInstance,      // handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,          // command line
  int nCmdShow              // show state
)
{
	MSG msg;
	WNDCLASS tridaOkna;
	HWND hlavniOkno;
	hObrazek = NULL;
	tridaOkna.cbClsExtra = 0;
	tridaOkna.cbWndExtra = 0;
	tridaOkna.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	tridaOkna.hCursor = LoadCursor(NULL, IDC_ARROW);
	tridaOkna.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	tridaOkna.lpfnWndProc = ProceduraHlavnihoOkna;
	tridaOkna.lpszClassName = JMENOTRIDYOKNA;
	tridaOkna.lpszMenuName = NULL;
	tridaOkna.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	tridaOkna.hInstance = hInstance;
	if (RegisterClass(&tridaOkna)==0) {
		MessageBox(NULL, "Nepodarilo se zaregistrovat tridu okna","Error", MB_OK | MB_ICONERROR);
		return 1;
	}

	hlavniOkno = CreateWindow(JMENOTRIDYOKNA	// jmeno tridy okna
			, "Titulek okna"	// jmeno okna (titulek)
			, WS_OVERLAPPEDWINDOW  // WS_HSCROLL | WS_VSCROLL // styl okna
			, 50	// x pozice
			, 50	// y pozice
			, 700	// sirka
			, 600	// vyska
			, NULL	// rodicovske okno
			, NULL	// menu
			, hInstance	// instance aplikace, ktera vlastni toto okno
			, 0	// zadne dodatecne parametry
			);
	if (hlavniOkno == NULL) {
		MessageBox(NULL, "Nepodarilo se vytvorit okno aplikace","Error", MB_ICONERROR|MB_OK);
		return 1;
	}
	ShowWindow(hlavniOkno, nCmdShow); // zobrazime okno, tak jak jsme to dostali v parametru
									// funkce WinMain

	// smycka zprav
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	if (hObrazek) DeleteObject(hObrazek);
	return (int) msg.wParam;
}

void VlozOvladaciPrvky(HWND hwndKam)
{
	HWND prvek;
	HINSTANCE hInstance;
	// zjistime instanci aplikace z handlu okna
	hInstance = (HINSTANCE) GetWindowLong(hwndKam, GWL_HINSTANCE);
	// vytvorime edit box
	prvek = CreateWindow("EDIT"
		, ""
		, ES_AUTOHSCROLL | WS_CHILD /*nutny pro ovladaci prvky*/ | WS_VISIBLE| WS_BORDER
		, 10	// x
		, 10	// y
		, 300	// sirka
		, 25	// vyska
		, hwndKam
		, (HMENU) EDIT_NAZEVSOUBORU	// id ovladaciho prvku 
		, hInstance	// instance aplikace
		,0);
	// vytvorime tlacitko Zobraz obrazek
	prvek = CreateWindow("BUTTON"
		, "Zobraz obrazek"
		, BS_PUSHBUTTON |WS_CHILD |WS_VISIBLE
		, 10
		, 40
		, 150
		, 25
		, hwndKam
		, (HMENU) BTN_UKAZOBRAZEK
		, hInstance
		, 0);
	// vytvorime tlacitko pro zavreni aplikace
	prvek = CreateWindow("BUTTON"
		, "Ukonci aplikaci"
		, BS_PUSHBUTTON |WS_CHILD |WS_VISIBLE
		, 160
		, 40
		, 150
		, 25
		, hwndKam
		, (HMENU) BTN_KONEC
		, hInstance
		, 0);
}

void Kresli(HWND hwndKam)
{
	HDC platno;
	PAINTSTRUCT ps;
	BITMAP info;
	platno = BeginPaint(hwndKam, &ps);
	if (platno) {
		if (hObrazek) {
			GetObject(hObrazek, sizeof(BITMAP), &info);
			HDC platnoObraz;
			platnoObraz = CreateCompatibleDC(platno); // vytvorime kompatibilni platno s nasim
			SelectObject(platnoObraz, hObrazek);	// vybereme na platne obrazku obrazek
			// provedeme kopirovani obrazku z platna obrazu do naseho platna
			StretchBlt(platno, 10,100,500,400	// kam
				,platnoObraz, 0,0, info.bmWidth, info.bmHeight // odkud
				, SRCCOPY // jak
				);
			DeleteDC(platnoObraz);
		}
		EndPaint(hwndKam, &ps);
	}
}

void NactiObrazek(LPCSTR jmenoSouboru)
{
	if (hObrazek) {
		DeleteObject(hObrazek);
		hObrazek = NULL;
	}
	hObrazek = (HBITMAP) LoadImage(NULL	// v jake aplikaci se nachazi
		,jmenoSouboru
		,IMAGE_BITMAP	// chceme nacist bitmapu
		,0	// ocekavana sirka
		,0	// ocekavana vyska
		, LR_LOADFROMFILE
		);
}

LRESULT CALLBACK ProceduraHlavnihoOkna(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
	LRESULT rVal = 0;
	TCHAR jmenoSouboru[500+1];	// pamet pro retezec 500 znaku
	switch(uMsg) {
		case WM_COMMAND:
			switch (LOWORD(wParam))
			{
				case BTN_KONEC:
					PostMessage(hwnd,WM_DESTROY,0,0);// PostQuitMessage(0);
					break;
				case BTN_UKAZOBRAZEK:
					GetDlgItemText(hwnd, EDIT_NAZEVSOUBORU, jmenoSouboru,500);
					//MessageBox(hwnd, jmenoSouboru, "Jmeno souboru je:", MB_OK |MB_ICONINFORMATION);
					NactiObrazek(jmenoSouboru);
					InvalidateRect(hwnd, NULL, true);
					UpdateWindow(hwnd);
					break;
				default:
					rVal = DefWindowProc(hwnd, uMsg, wParam, lParam);
					break;
			}
			break;
		case WM_PAINT:
			Kresli(hwnd);
			break;
		case WM_CREATE:
			VlozOvladaciPrvky(hwnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			rVal = DefWindowProc(hwnd, uMsg, wParam, lParam);
			break;
	}
	return rVal;
}
