#include "stdafx.h"
#include <windows.h>
#include "resource.h"

#include <vector>

#include "Tile.h"
#include "Camera.h"
#include "EngineIO.h"
#include "Engine.h"

#include "Canvas3D.h"
#include "MaterialManager.h"

#include "Animation.h"
#include "AnimationManager.h"

#pragma warning( disable : 4996 )

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static int m_count;

static Canvas3D* m_canvas3D;
static bool m_init;
static bool m_renderFlag;

/****************************************************************************/
/** \brief WinMain Executable entry
*****************************************************************************/
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       iCmdShow )
{
m_count = 0;
char buf[512];
char datFile[512];

if ((lpCmdLine != NULL) && (lpCmdLine[0] != 0))
   {
   sprintf(datFile, "%s", lpCmdLine); // Pfad+Dateiname aus lpCmdLine
   }
else
   {
   GetModuleFileName(NULL, buf, 511); // Pfad ist Ablageort des Executable
   char *p = strrchr(buf, '\\');      // Mapname ist 'Map.dat'
   if (p != NULL)
      *p = 0;
   sprintf(datFile, "%s\\%s", buf, "Map.dat");
	}

FILE *p = fopen (datFile, "r");
if (p == NULL)
   return (-1); // FILE NOT FOUND
fclose (p);

m_init = false;
m_renderFlag = true;
m_canvas3D = Canvas3D::getInstance();
if (m_canvas3D->init(datFile) == false)
   {
   delete (m_canvas3D);
   return (-2); // NOT A MAPFILE
   }

static char appName[] = "Engine-3D";

HWND hwnd;
MSG msg;
WNDCLASS wndClass;

wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON_ENGINE));
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = appName;

if (!RegisterClass (&wndClass))
   {
   MessageBox(NULL, "RegisterClass failed!", "Error", MB_ICONERROR);
   return 0;
   }

hwnd = CreateWindow(appName,
                    "engine3D_win32",
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    NULL,
                    NULL,
                    hInstance,
                    NULL);

MoveWindow(hwnd, 100, 100, 640, 436, TRUE);

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage (&msg, NULL, 0,0))
   {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
   }

delete (m_canvas3D);

return (msg.wParam);
}

/****************************************************************************/
/** \brief 
*****************************************************************************/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;

switch(message)
   {
   case WM_CREATE:
   SetTimer(hwnd, ID_TIMER, 10, NULL);
   return 0;
   break;

   case WM_TIMER:
   m_renderFlag = true;
   InvalidateRect(hwnd, NULL, FALSE);
   return 0;
   break;

   case WM_PAINT:
   hdc = BeginPaint(hwnd, &ps);
   RECT rect;
   GetClientRect(hwnd, &rect ) ;

   if (m_init == false)
      {
      m_init = true;
      int winWidth  = rect.right;
      int winHeight = rect.bottom; // - m_CanvasYOffset;
      m_canvas3D->initialize(winWidth, winHeight, 640, 400);
      }

   if (m_renderFlag == true)
      {
      m_canvas3D->renderFrame();
      m_renderFlag = false;
      }
   
   m_canvas3D->paint(hdc);

   EndPaint(hwnd, &ps);
   return 0;
   break;

   case WM_KEYDOWN:
   if (m_canvas3D->inputKey(true, wParam) == true)
      {
      m_renderFlag = true;
      InvalidateRect(hwnd, NULL, FALSE);
      }
   break;   

   case WM_KEYUP:
   if (m_canvas3D->inputKey(false, wParam) == true)
      {
      m_renderFlag = true;
      InvalidateRect(hwnd, NULL, FALSE);
      }
   break;   

   case WM_LBUTTONUP:
   InvalidateRect(hwnd, NULL, FALSE);
   break;

   case WM_LBUTTONDOWN:
   InvalidateRect(hwnd, NULL, FALSE);
   break;

   case WM_DESTROY:
   KillTimer(hwnd, ID_TIMER);
   PostQuitMessage(0);
   break;
   }

return DefWindowProc(hwnd, message, wParam, lParam);
}
