#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include <dinput.h>
#include <time.h>
#include "main.h"
#include "video.h"
#include "map.h"
#include "input.h"
#include "objects.h"
//#include "logging.h"

//Children objects
#include "child.h"

videoEngineClass videoEngine(800, 600, 16);
mapEngineClass mapEngine(&videoEngine);
inputEngineClass inputEngine(&videoEngine);
objectEngineClass objectEngine(&videoEngine, &mapEngine);
gameEngineClass gameEngine;

//loggingEngineClass logger("C:\\temp\\pointer.log");

long FAR PASCAL
WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int x, y;
	int x2, y2;
//	int tileX, tileY;

	switch (message)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0L;
	
		case WM_KEYDOWN:  //Replace this later with keyboard engine
			if (wParam == VK_ESCAPE)
			{
				videoEngine.fade(0);
				inputEngine.setMouseAcquire(0);
				gameEngine.quit();
			}

			if (wParam == VK_DOWN)
			{
				x = inputEngine.getMouseX()+videoEngine.getCameraX();
				y = inputEngine.getMouseY()+videoEngine.getCameraY();

				mapEngine.getGLCoords(x, y, &x2, &y2,1);

				mapEngine.createObjectPath(x2, y2, (void *) objectEngine.getObject(0));

			/*	logger.logEntry("Mouse Coords: ",0);
				logger.logNumber(x, 0);
				logger.logEntry(",",0);
				logger.logNumber(y,1);
				
				logger.logEntry("Ground level coords: ", 0);
				logger.logNumber(x2, 0);
				logger.logEntry(",",0);
				logger.logNumber(y2, 1);

				//mapEngine.getTile(x2, y2, &tileX, &tileY);
				tileX = mapEngine.getGLTileX(x2, y2);
				tileY = mapEngine.getGLTileY(x2, y2);
				logger.logEntry("Ground level tile: ", 0);
				logger.logNumber(tileX, 0);
				logger.logEntry(",", 0);
				logger.logNumber(tileY, 1);

				tileX = mapEngine.getGLRemainderX(x2, y2);
				tileY = mapEngine.getGLRemainderY(x2, y2);
				logger.logEntry("Remainder is: ", 0);
				logger.logNumber(tileX, 0);
				logger.logEntry(",", 0);
				logger.logNumber(tileY, 1);

				mapEngine.getRelativeCoords(x2, y2, &x, &y);
				logger.logEntry("Draw Coords: ",0);
				logger.logNumber(x, 0);
				logger.logEntry(",",0);
				logger.logNumber(y,1);
				
*/
			}

			if (wParam == VK_F1)
			{
				mapEngine.saveMap("Test Map", 9);
			}
				
			break;

		case WM_TIMER:
			x = mapEngine.getGLTileX(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
			y = mapEngine.getGLTileY(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
			
			mapEngine.shadeCursorArea(x, y, 23, 1);
			mapEngine.update();
			//objectEngine.drawAll();
			videoEngine.update();
			mapEngine.unshadeCursorArea(x,y, 23, 1);
			break;

	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

int PASCAL 
WinMain(HINSTANCE hInstance,
		HINSTANCE hPrevInstance,
		LPSTR lpCmdLine,
		int nCmdShow)
{
	MSG msg;
	DWORD dwResult;


	// Init video, mouse, and then the game.
	videoEngine.initVideo(hInstance, nCmdShow);	
	inputEngine.initMouse();
	inputEngine.setMouseAcquire(1);
	mapEngine.setOEPtr(&objectEngine);
	gameEngine.init();
	
	
	//Loop until game is quit.
	while (gameEngine.isRunning())
	{
		dwResult = MsgWaitForMultipleObjectsEx(1, inputEngine.getMouseEvent(), INFINITE, QS_ALLEVENTS, MWMO_INPUTAVAILABLE);
		switch (dwResult)
		{
			case WAIT_OBJECT_0:  //Just mouse intercepted
				inputEngine.processMouse();
				break;

			case WAIT_OBJECT_0 + 1:  //Mouse and/or some other event.
				inputEngine.processMouse();
				gameEngine.process();
				if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				else
				{
					WaitMessage();
				}
				break;

			default:
				// This shouldnt get called
				//gameEngine.update();
				break;
		}

	}

	return 0;
}


// *******************************
// Start Game Engine Definition
// *******************************

gameEngineClass ::gameEngineClass()
{
	running = true;
}

gameEngineClass ::~gameEngineClass()
{
}

void gameEngineClass ::process()
{
	int temp1, temp2;
	if (inputEngine.getButton0())
	{
		temp1 = mapEngine.getGLTileX(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
		temp2 = mapEngine.getGLTileY(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
		mapEngine.alterSurfaceSquare(temp1, temp2, 0, 23);

	}
	if (inputEngine.getButton1())
	{
		temp1 = mapEngine.getGLTileX(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
		temp2 = mapEngine.getGLTileY(inputEngine.getMouseX()+videoEngine.getCameraX(), inputEngine.getMouseY()+videoEngine.getCameraY());
		mapEngine.alterSurfaceSquare(temp1, temp2, 1, 23);

	}

		if (inputEngine.getMouseX() > 797)
		{
			videoEngine.setCamera(videoEngine.getCameraX() + 15, videoEngine.getCameraY());
		}
		if (inputEngine.getMouseX() < 1)
		{
			videoEngine.setCamera(videoEngine.getCameraX() - 15, videoEngine.getCameraY());
		}
		if (inputEngine.getMouseY() > 597)
		{
			videoEngine.setCamera(videoEngine.getCameraX(), videoEngine.getCameraY() + 15);
		}
		if (inputEngine.getMouseY() < 1)
		{
			videoEngine.setCamera(videoEngine.getCameraX(),videoEngine.getCameraY() - 15);
		}

		objectEngine.processAll();
}

void gameEngineClass ::quit()
{
	running = false;
}

void gameEngineClass ::init()
{
	RECT tempRect;

	videoEngine.loadCursorset();
	videoEngine.loadTileset();
	videoEngine.loadObjectset();

	tempRect.top = 20;
	tempRect.bottom = 1300;
	tempRect.left = 20;
	tempRect.right = 4000;

	videoEngine.setViewBorder(tempRect);
	videoEngine.setCamera(20,20);
	mapEngine.setTileWidth(23);
	mapEngine.setTileHeight(18);
	mapEngine.setTileMid(6);
	
	mapEngine.loadMap(1);

	//Fade In
	mapEngine.update();
	videoEngine.update();
	videoEngine.fade(2);

	objectEngine.createObject(1);
	objectEngine.createObject(2);

	//for (int lcv1 = 0 ; lcv1 < 300 ; lcv1++)
	//	for (int lcv2 = 0 ; lcv2 < 300 ; lcv2++)
	//		if (rand()%2)
	//			mapEngine.placeTile(lcv1, lcv2, 0, 0, 0);
	//		else
	//			mapEngine.placeTile(lcv1, lcv2, 0, 6, 0);
}

int gameEngineClass ::isRunning()
{
	return running;
}


