#include <windows.h>

#define JMENOTRIDYOKNA "BitmapViewer"

// id ovladacich prvku
#define EDIT_JMENOSOUBORU	1
#define BUTTON_ZOBRAZ		2


LRESULT CALLBACK ProceduraOkna(
  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;
	HWND hlavniOkno;
	WNDCLASS tridaOkna;

	// zaregistrovani tridy okna
	tridaOkna.cbClsExtra = 0;
	tridaOkna.cbWndExtra = sizeof(LONG_PTR);	// HBITMAP
	tridaOkna.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	tridaOkna.hCursor = LoadCursor(NULL, IDC_ARROW);
	tridaOkna.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	tridaOkna.hInstance = hInstance;
	tridaOkna.lpfnWndProc = ProceduraOkna;
	tridaOkna.lpszClassName = JMENOTRIDYOKNA;
	tridaOkna.lpszMenuName = NULL;
	tridaOkna.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	if (RegisterClass(&tridaOkna)==0) 
	{
		MessageBox(NULL, "Nepovedlo se zaregistrovat tridu okna","Error", MB_OK |MB_ICONERROR);
		return 1;
	}
	
	// vytvoreni hlavniho okna aplikace
	hlavniOkno = CreateWindow(JMENOTRIDYOKNA
		,"Bitmap Viewer"
		, WS_OVERLAPPEDWINDOW
		, 10
		, 10
		, 700
		, 600
		, NULL
		, NULL
		, hInstance
		, 0);
	if (hlavniOkno == NULL) 
	{
		MessageBox(NULL, "Nepovedlo se vytvorit okno aplikace", "Error", MB_ICONERROR | MB_OK);
		return 1;
	}
	ShowWindow(hlavniOkno, nCmdShow);

	// smycka zprav
	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return (int) msg.wParam;
	
	/*
	// jina smycka zprav -pouzit misto cyklu getmessage
	BOOL pokracovat = true;
	while(pokracovat) 
	{
		// tady by byl nejaky vykonny kod
			// TO DO
		while(PeekMessage(&msg, NULL, 0,0,PM_REMOVE))
		{
			if (msg.message == WM_QUIT) 
			{
				pokracovat = false;
				break;	// ukonci se cyklus peekmessage
			}	
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return (int) msg.wParam;
	*/
}

void VlozOvladaciPrvky(HWND oknoKam)
{
	HINSTANCE hInstance;
	HWND prvek;
	hInstance = (HINSTANCE) GetWindowLong(oknoKam, GWL_HINSTANCE);
	prvek = CreateWindow("EDIT"
		, "zde vlozte cestu k souboru"
		, ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER// WS_CHILD je dulezity
		, 10
		, 10
		, 400
		, 25
		, oknoKam
		, (HMENU) EDIT_JMENOSOUBORU // id ovladaciho prvku
		, hInstance
		, 0);
	prvek = CreateWindow("BUTTON"
		, "Nacti a zobraz obrazek"
		, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE
		, 10
		, 40
		, 200
		, 25
		, oknoKam
		, (HMENU) BUTTON_ZOBRAZ
		, hInstance
		, 0);
}

void Vykresli(HWND oknoKam)
{
	PAINTSTRUCT ps;
	BITMAP info;
	HBITMAP obrazek;
	HDC platno;
	HDC platnoBitmap;

	platno = BeginPaint(oknoKam, &ps);
	if (platno) 
	{
		Rectangle(platno, 10,100,500,400); // vykresli obdelnik
		obrazek = (HBITMAP) GetWindowLongPtr(oknoKam, GWL_USERDATA);
		if (obrazek) 
		{
			GetObject(obrazek,sizeof(BITMAP), &info);
			platnoBitmap = CreateCompatibleDC(platno);
			if (platnoBitmap)
			{
				SelectObject(platnoBitmap, obrazek);
				StretchBlt(platno, 10, 100, 500, 400, // kam
					platnoBitmap,0,0,info.bmWidth, info.bmHeight,// odkud
					SRCCOPY);	// jak
				DeleteDC(platnoBitmap);
			}
		}
		EndPaint(oknoKam, &ps);
	}
}


void NactiObrazek(HWND dialogoveOkno)
{
	TCHAR jmenoSouboru[1000+1];
	HBITMAP obrazek;
	HBITMAP staryObrazek;
	GetDlgItemText(dialogoveOkno, EDIT_JMENOSOUBORU, jmenoSouboru, 1000);
	obrazek = (HBITMAP) LoadImage(NULL, jmenoSouboru, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	staryObrazek =(HBITMAP) SetWindowLongPtrA(dialogoveOkno, GWL_USERDATA, (LONG_PTR) obrazek);
	if (staryObrazek)
	{
		DeleteObject(staryObrazek);
	}
	// zaridime prekresleni zneplatnenim oblasti a aktualizovanim okna
	InvalidateRect(dialogoveOkno,NULL, true);
	UpdateWindow(dialogoveOkno);
}


LRESULT CALLBACK ProceduraOkna(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
	HBITMAP hbmp;
	LRESULT rVal = 0;
	switch (uMsg)
	{
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case BUTTON_ZOBRAZ:
			NactiObrazek(hwnd);
			break;
		default:
			rVal = DefWindowProc(hwnd, uMsg, wParam, lParam);
			break;
		}
		break;
	case WM_PAINT:
		Vykresli(hwnd);
		break;
	case WM_CREATE:
		VlozOvladaciPrvky(hwnd);
		break;
	case WM_DESTROY:
		// uvolnime pamet pro bitmapu a posleme WM_QUIT
		hbmp = (HBITMAP) SetWindowLongPtr(hwnd, GWL_USERDATA,NULL); // vrati puvodni hodnotu
		if (hbmp) DeleteObject(hbmp);	
		PostQuitMessage(0);
		break;
	default:
		rVal = DefWindowProc(hwnd, uMsg, wParam, lParam);
		break;
	}
	return rVal;
}
