/***********************************************************************
 * MainGUI.CPP
 *  
 *    Main GUI code
 *
 *
 * Toby Opferman Copyright (c) 2003
 *
 ***********************************************************************/
 

                                                                     
#include <windows.h>
#include <gdi.h>
#include <tile.h>
#include "leveleditorgui.h"
#include "leveleditor.h"
#include "leveleditorres.h"




 /***********************************************************************
  * Internal APIs
  ***********************************************************************/
 LRESULT CALLBACK MainGUI_WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
 void MainGUI_ProcessVirtualKeyPress(HWND hWnd, UINT vKey);
 void MainGUI_ProcessVirtualKeyRelease(HWND hWnd, UINT vKey);
 void MainGUI_CreateHandler(HWND hWnd);
 void MainGUI_PaintScreen(HWND hWnd);
  void MainGui_ProcessCommand(HWND hWnd, USHORT Command, LPARAM lParam);


 /***********************************************************************
  * MainGUI_RegisterClass
  *  
  *    Registers the Test Window Proc Class
  *
  * Parameters
  *     instance Handle
  * 
  * Return Value
  *     TRUE on Success, FALSE on Failure
  *
  ***********************************************************************/
 BOOL WINAPI MainGUI_RegisterClass(HINSTANCE hInstance)
 {
     WNDCLASSEX WndClassEx = {0};

     WndClassEx.cbSize        = sizeof(WndClassEx);
     WndClassEx.style         = 0;
     WndClassEx.lpfnWndProc   = MainGUI_WindowProc;
     WndClassEx.cbWndExtra    = 0;
     WndClassEx.hInstance     = hInstance;
     WndClassEx.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TITLE));
     WndClassEx.hCursor       = LoadCursor(hInstance, IDC_ARROW);
     WndClassEx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
     WndClassEx.lpszMenuName  = MAKEINTRESOURCE(GAME_MENU);
     WndClassEx.lpszClassName = GAME_CLASS_NAME;
     WndClassEx.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TITLE));
     
     return RegisterClassEx(&WndClassEx);
 }



 /***********************************************************************
  * MainGUI_CreateWindow
  *  
  *    Creates The Test Window
  *
  * Parameters
  *     instance Handle
  * 
  * Return Value
  *     Window Handle on Success, NULL on Failure
  *
  ***********************************************************************/
 HWND WINAPI MainGUI_CreateWindow(HINSTANCE hInstance)
 {
     HWND hWnd = NULL;

     if(!FindWindow(GAME_CLASS_NAME, NULL))
     {
        if(hWnd = CreateWindowEx(0, GAME_CLASS_NAME, GAME_TITLE, WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_OVERLAPPED, 0,  0, GAME_WINDOW_WIDTH, GAME_WINDOW_HEIGHT, HWND_DESKTOP, NULL,  hInstance, NULL))
        {
            ShowWindow(hWnd, SW_SHOWNORMAL);
            UpdateWindow(hWnd);
        }
     }

     return hWnd;
 }



 /***********************************************************************
  * MainGUI_MessageLoop
  *  
  *    Handles Window Messages to be dispatched to the Cubix Window
  *
  * Parameters
  *     instance Handle, Window Handle
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 int WINAPI MainGUI_MessageLoop(HINSTANCE hInstance, HWND hWnd)
 {
     MSG Msg = {0};
     BOOL bMessageLoop = TRUE;
	 HLEVELEDITOR hLevelEditor;
	 BOOL MessageRecieved;

	 hLevelEditor = (HLEVELEDITOR)GetWindowLong(hWnd, GWL_USERDATA);

     while(bMessageLoop)
     {
		MessageRecieved = PeekMessage(&Msg, 0, 0, 0, PM_REMOVE);

	    if(MessageRecieved)
		{
			if(Msg.message == WM_QUIT)
			{
				bMessageLoop = FALSE;
			}
			else
			{
                TranslateMessage(&Msg);
                DispatchMessage(&Msg);
			}
		}
		else
		{
			bMessageLoop = LevelEditor_MessageLoop(hLevelEditor);
		}
     }

     return Msg.wParam;
 }


 

 /***********************************************************************
  * MainGUI_WindowProc
  *  
  *    Handles Window Messages Send to the window
  *
  * Parameters
  *     Standard Windows Proc Handler
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 LRESULT CALLBACK MainGUI_WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
     LRESULT dwRetValue = 0;

     switch(wMsg)
     {
         case WM_CREATE:
              MainGUI_CreateHandler(hWnd);
              break;

         case WM_PAINT:
              MainGUI_PaintScreen(hWnd);
              break;

	     case WM_KEYDOWN:
              MainGUI_ProcessVirtualKeyPress(hWnd, wParam);
			  break;

         case WM_KEYUP:
              MainGUI_ProcessVirtualKeyRelease(hWnd, wParam);
              break;
	     
		 case WM_COMMAND:
			  MainGui_ProcessCommand(hWnd, LOWORD(wParam), lParam);
			  break;
            
         case WM_CLOSE:
         case WM_DESTROY:
              ShowCursor(TRUE);
              PostQuitMessage(0);
              break;

         default:
              dwRetValue = DefWindowProc(hWnd, wMsg, wParam, lParam);
     }

     return dwRetValue;
 }

 /***********************************************************************
  * MainGui_ProcessCommand
  *  
  *    Handles Window Messages Send to the window
  *
  * Parameters
  *     Standard Windows Proc Handler
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 void MainGui_ProcessCommand(HWND hWnd, USHORT Command, LPARAM lParam)
 {
	 HLEVELEDITOR hLevelEditor;

	 hLevelEditor = (HLEVELEDITOR)GetWindowLong(hWnd, GWL_USERDATA);

     LevelEditor_HandleMenuCommands(hLevelEditor, Command, lParam);
 }


 /***********************************************************************
  * MainGUI_PaintScreen
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
 void MainGUI_PaintScreen(HWND hWnd)
 {
     HDC hDC;
     PAINTSTRUCT ps;
     RECT Rect;
     HLEVELEDITOR hLevelEditor;
     HDC hLevelDC;

	 hLevelEditor = (HLEVELEDITOR)GetWindowLong(hWnd, GWL_USERDATA);
	 hLevelDC = LevelEditor_GetLevelDc(hLevelEditor);

     hDC = BeginPaint(hWnd, &ps);

     GetClientRect(hWnd, &Rect);
     BitBlt(hDC, 0, 0, GAME_WIDTH, GAME_HEIGHT + GAME_HEIGHT_BOTTOM, hLevelDC, 0, 0, SRCCOPY);

     LevelEditor_ReleaseLevelDc(hLevelEditor, hLevelDC);

     EndPaint(hWnd, &ps);
 }



 /***********************************************************************
  * MainGUI_ProcessVirtualKeyPress
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
 void MainGUI_ProcessVirtualKeyPress(HWND hWnd, UINT vKey)
 {
    HLEVELEDITOR hLevelEditor;

	hLevelEditor = (HLEVELEDITOR)GetWindowLong(hWnd, GWL_USERDATA);
    LevelEditor_HandleKeyPress(hLevelEditor, vKey);
 }

  /***********************************************************************
  * MainGUI_ProcessVirtualKeyPress
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
 void MainGUI_ProcessVirtualKeyRelease(HWND hWnd, UINT vKey)
 {
    HLEVELEDITOR hLevelEditor;

	hLevelEditor = (HLEVELEDITOR)GetWindowLong(hWnd, GWL_USERDATA);
    LevelEditor_HandleKeyRelease(hLevelEditor, vKey);
 }


 /***********************************************************************
  * MainGUI_CreateHandler
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
void MainGUI_CreateHandler(HWND hWnd)
{
   HLEVELEDITOR hLevelEditor;
   hLevelEditor = LevelEditor_Init(hWnd, GetModuleHandle(NULL));

   if(hLevelEditor)
   {
	    SetWindowLong(hWnd, GWL_USERDATA, (ULONG)hLevelEditor);
        InvalidateRect(hWnd, NULL, FALSE);
   }
   else
   {
	   DestroyWindow(hWnd);
   }
}

