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

                                                                     
#include <windows.h>
#include <gdi.h>
#include <leveleng.h>
#include "maingui.h"
#include "gameres.h"
#include "game.h"



/* Timer Events */
#define TITLE_SCREEN_FADE_EVENT   100


 /***********************************************************************
  * 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 CALLBACK MainGUI_TitleFade(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
 void MainGUI_PaintScreenForce(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;
	 HGAME hGame;
	 BOOL MessageRecieved;

	 hGame = (HGAME)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 = Game_MessageLoop(hGame);
		}
     }

     return Msg.wParam;
 }


 /***********************************************************************
  * MainGUI_TitleFade
  *  
  *    Handles Window Messages Send to the window
  *
  * Parameters
  *     Standard Windows Proc Handler
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 void CALLBACK MainGUI_TitleFade(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 {
   BOOL SetFadeTimer = FALSE;
   HGAME hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);

   KillTimer(hWnd, idEvent);

   SetFadeTimer = Game_FadeTitleScreen(hGame);

   if(SetFadeTimer)
   {
	   SetTimer(hWnd, TITLE_SCREEN_FADE_EVENT, 1000/30, (TIMERPROC)MainGUI_TitleFade);
   }
   
   MainGUI_PaintScreenForce(hWnd);
 }

 

 /***********************************************************************
  * 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)
 {
	 HGAME hGame;

	 hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);

     Game_HandleMenuCommands(hGame, 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;
     HGAME hGame;
     HDC hGameDC;

	 hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);
	 hGameDC = Game_GetGameDc(hGame);

     hDC = BeginPaint(hWnd, &ps);

     GetClientRect(hWnd, &Rect);
     BitBlt(hDC, 0, 0, GAME_WIDTH, GAME_HEIGHT, hGameDC, 0, 0, SRCCOPY);

     Game_ReleaseGameDc(hGame, hGameDC);

     EndPaint(hWnd, &ps);
 }


 /***********************************************************************
  * MainGUI_PaintScreen
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
 void MainGUI_PaintScreenForce(HWND hWnd)
 {
     HDC hDC;
     HGAME hGame;
     HDC hGameDC;

     hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);
     hGameDC = Game_GetGameDc(hGame);
     
     hDC = GetDC(hWnd);
     BitBlt(hDC, 0, 0, GAME_WIDTH, GAME_HEIGHT, hGameDC, 0, 0, SRCCOPY);

     Game_ReleaseGameDc(hGame, hGameDC);
	 
     ReleaseDC(hWnd, hDC);
 }


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

	hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);
    Game_HandleKeyPress(hGame, vKey);
 }

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

	hGame = (HGAME)GetWindowLong(hWnd, GWL_USERDATA);
    Game_HandleKeyRelease(hGame, vKey);
 }


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

   if(hGame)
   {
	    SetWindowLong(hWnd, GWL_USERDATA, (ULONG)hGame);
        InvalidateRect(hWnd, NULL, FALSE);
        SetTimer(hWnd, TITLE_SCREEN_FADE_EVENT, 1000/30, (TIMERPROC)MainGUI_TitleFade);
   }
   else
   {
	   DestroyWindow(hWnd);
   }
}

