//Steve Mack

#include <windows.h>

HWND ghWnd_Main;

HINSTANCE ghInst;
HINSTANCE ghInst2;

class graphic
{
public:
	int x;
	int y;
	char filename[50];

	~graphic(){}
	void Paint();
	BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,HPALETTE *phPalette );
	HBITMAP CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent);
	void SetFileName(char file[50]);
};

void graphic::SetFileName(char file[50])
{
	strcat(filename, file);
}
BOOL graphic::LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,HPALETTE *phPalette )
{
   BITMAP  bm;

   *phBitmap = NULL;
   *phPalette = NULL;

   // Use LoadImage() to get the image loaded into a DIBSection
   *phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
               LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
   if( *phBitmap == NULL )
     return FALSE;

   // Get the color depth of the DIBSection
   GetObject(*phBitmap, sizeof(BITMAP), &bm );
   // If the DIBSection is 256 color or less, it has a color table
   if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
   {
   HDC           hMemDC;
   HBITMAP       hOldBitmap;
   RGBQUAD       rgb[256];
   LPLOGPALETTE  pLogPal;
   WORD          i;

   // Create a memory DC and select the DIBSection into it
   hMemDC = CreateCompatibleDC( NULL );
   hOldBitmap = (HBITMAP)SelectObject( hMemDC, *phBitmap );
   // Get the DIBSection's color table
   GetDIBColorTable( hMemDC, 0, 256, rgb );
   // Create a palette from the color tabl
   pLogPal = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY)) );
   pLogPal->palVersion = 0x300;
   pLogPal->palNumEntries = 256;
   for(i=0;i<256;i++)
   {
     pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
     pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
     pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
     pLogPal->palPalEntry[i].peFlags = 0;
   }
   *phPalette = CreatePalette( pLogPal );
   // Clean up
   free( pLogPal );
   SelectObject( hMemDC, hOldBitmap );
   DeleteDC( hMemDC );
   }
   else   // It has no color table, so use a halftone palette
   {
   HDC    hRefDC;

   hRefDC = GetDC( NULL );
   *phPalette = CreateHalftonePalette( hRefDC );
   ReleaseDC( NULL, hRefDC );
   }
   return TRUE;
}

HBITMAP graphic::CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent)
{
	HDC hdcMem, hdcMem2;
	HBITMAP hbmMask;
	BITMAP bm;

	GetObject(hbmColour, sizeof(BITMAP), &bm);
	hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);

	hdcMem = CreateCompatibleDC(0);
	hdcMem2 = CreateCompatibleDC(0);

	SelectObject(hdcMem, hbmColour);
	SelectObject(hdcMem2, hbmMask);

	SetBkColor(hdcMem, crTransparent);

	BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

	BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT);

	DeleteDC(hdcMem);
	DeleteDC(hdcMem2);

	return hbmMask;
}
void graphic::Paint()
{	 
	HBITMAP       hBitmap, hOldBitmap;
	HPALETTE      hPalette, hOldPalette;
	BITMAP        bm;
	HDC hdc;
	HBITMAP g_hbmMask;
		HDC           hDC, hMemDC;
	PAINTSTRUCT   ps;

	hDC = BeginPaint( ghWnd_Main, &ps );
				if( LoadBitmapFromBMPFile( filename, &hBitmap, &hPalette ) )
				{
					hMemDC = CreateCompatibleDC( hDC );
					GetObject( hBitmap, sizeof(BITMAP), &bm );
					g_hbmMask = CreateBitmapMask(hBitmap, RGB(0, 0, 0));
					GetObject( g_hbmMask, sizeof(BITMAP), &bm );
					hOldBitmap = (HBITMAP)SelectObject( hMemDC, g_hbmMask );
					hOldPalette = SelectPalette( hDC, hPalette, FALSE );
//					RECT rcClient;

					BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);


					hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
					hOldPalette = SelectPalette( hDC, hPalette, FALSE );
					RealizePalette( hDC );


					BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight,	hMemDC, 0, 0, SRCPAINT );


					SelectObject( hMemDC, hOldBitmap );
					DeleteObject( hBitmap );
					SelectPalette( hDC, hOldPalette, FALSE );
   			        DeleteObject( hPalette );
				}
				EndPaint( ghWnd_Main, &ps );
}
graphic PIC;
graphic TEST;

//function prototypes
void SetFont(HWND hWnd, int iPointSize, const char *pcFontName);  //(obviously) sets fonts of controls

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch(uMsg) {
		case WM_CLOSE:
			DestroyWindow(ghWnd_Main); // Destroy the main window
			return 0;

		case WM_DESTROY:
			PostQuitMessage(0); // Quit the application
			return 0;

		case WM_CREATE:
			
			
			return 0;

		case WM_PAINT:  //updates the pic everytime needed
			{
				//TEST.Paint();
				//PIC.Paint();
				
			}
			return 0;
		case WM_COMMAND:
			//if(LOWORD(wParam) == BN_CLICKED && (HWND)lParam == OPENABOUT) {

			return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam); // Not handled - let the system deal with it
}

//==================WINDOW CODE=========================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	ghInst = hInstance;
	ghInst2 = hInstance;
	
	WNDCLASSEX wcxMyClass;

	wcxMyClass.cbSize = sizeof(WNDCLASSEX); // Size of structure in bytes
	wcxMyClass.style = 0; // Extra style information
	wcxMyClass.lpfnWndProc = WndProc; // Pointer to window procedure
	wcxMyClass.cbClsExtra = 0; // Extra bytes in class definition
	wcxMyClass.cbWndExtra = 0; // Extra bytes for each window
	wcxMyClass.hInstance = hInstance; // Instance handle for the class
	wcxMyClass.hIcon = NULL; // Default icon - use system
	wcxMyClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the system arrow
	wcxMyClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); // Background brush
	wcxMyClass.lpszMenuName = NULL; // Menu name [MAKEINTRESOURCE(IDM_MAINMENU)] - none here
	wcxMyClass.lpszClassName = "TESTCLASS"; // Class name
	wcxMyClass.hIconSm = NULL; // Small icon

	RegisterClassEx(&wcxMyClass);  // Register the class

	ghWnd_Main = CreateWindow("TESTCLASS", "Graphics Working", \
		                      WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 423, 347, \
							  NULL, NULL, hInstance, NULL);
	if(ghWnd_Main) {
//		ADDITEM = CreateWindowEx(WS_EX_CLIENTEDGE, "Button", "Add", WS_CHILD | /*WS_DLGFRAME |*/ WS_VISIBLE, 209, 1, 66, 40, ghWnd_Main, NULL, hInstance, NULL);
		 

				PIC.x = 100;
				PIC.y = 100;
				PIC.SetFileName("test.bmp");
				TEST.x = 50;
				TEST.y = 10;
				TEST.SetFileName("car.bmp");

		ShowWindow(ghWnd_Main, nCmdShow); // Show using the specific show style
	}
	for(int i=0; i<=200; i++)
	{
		TEST.Paint();
		TEST.x = i;
	}

	//=================== Handle message loop ==================================================
	MSG msg;
	while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg); // Translate keycode messages
		DispatchMessage(&msg); // Send to the window
	}

	UnregisterClass("TESTCLASS", hInstance); // Unregister our window class
	return msg.wParam; // msg.wParam contains the code passed to PostQuitMessage()
}

//=========================FUNCTIONS===============================
void SetFont(HWND hWnd, int iPointSize, const char *pcFontName) {  //(obviously) sets fonts of controls
    
    HFONT hTheFont;
    HDC hDC = GetDC(hWnd);
    int nHeight = -MulDiv(iPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

    hTheFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, pcFontName);

    ReleaseDC(hWnd, hDC);

    SendMessage(hWnd, WM_SETFONT, (WPARAM)hTheFont, TRUE);
}
