////===========================================================================//
//// File:        rp4lbe4.cc                                                   //
//// Project: MUNGA           Brick: Red Planet LBE Application                //
//// Contents:                                                                 //
////---------------------------------------------------------------------------//
////   Date    Who  Modification                                               //
//// --------  ---  ---------------------------------------------------------- //
////                                                                           //
////---------------------------------------------------------------------------//
//// Copyright (C) 1994, Virtual World Entertainment, Inc.                     //
//// All Rights reserved worldwide                                             //
//// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
////===========================================================================//
//
#define WIN32_LEAN_AND_MEAN
#define	_WIN32_WINNT	0x0500
#define WINVER			0x0500

#include <tchar.h>
#include "rpl4.h"
#pragma hdrstop

#include "rpl4pb.h"
#include "..\munga_l4\l4splr.h"
#include "rpl4ver.h"
#include "..\munga\resver.h"
#include "..\munga\resource.h"
// added for game status drawing support
#include "..\munga\player.h"
#include "..\munga\mission.h"
#include "..\munga_l4\l4ctrl.h"
// end add
#include <DbgHelp.h>
#include <strsafe.h>
#include <direct.h>
#include <shellapi.h>

#define SPOOL_SIZE 0x600000

//#define SCREEN_WIDTH	1024
//#define SCREEN_HEIGHT	768

Byte version[3] = {MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION};

char* names[] = {"InitializingState",
	"WaitingForEgg",
	"LoadingMission",
	"WaitingForLaunch",
	"LaunchingMission",
	"RunningMission",
	"EndingMission",
	"StoppingMission",
	"SuspendingMission",
	"ResumingMission",
	"AbortingMission",
	"CreatingMission",
	"ApplicationStateCount"};

//##########################################################################
//##################    RP4L4Application Globals    ########################
//##########################################################################

extern const char* const ProgName;
const char* const ProgName = "rpl4";
Application *rpl4App;
HWND hWnd;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CLOSE:
		DestroyWindow(hWnd);
	   return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	char filename[50];
	strcpy_s(filename, 50, "rpl4.log");

   std::ofstream logfile;
   logfile.open(filename);
   std::cout.rdbuf(logfile.rdbuf());

   // load up our environment variables
   //controls
   if(getenv("L4CONTROLS") == NULL)
      putenv("L4CONTROLS=KEYBOARD");
   if(getenv("DPLARG") == NULL)
      putenv("DPLARG=1");
   if(getenv("L4DPLCFG") == NULL)
      putenv("L4DPLCFG=RPDPL.INI");
   if(getenv("MULTISAMPLE") == NULL)
      putenv("MULTISAMPLE=0");
   if(getenv("TARGETFPS") == NULL)
	   putenv("TARGETFPS=60");
   if(getenv("MAXPARTICLES") == NULL)
	   putenv("MAXPARTICLES=8192");
   FILE *file;
   char line[1024];
   if (fopen_s(&file, "environ.ini", "r") == 0)
   {
      while (!feof(file))
      {
         if (fgets(line, sizeof(line), file))
         {
            for (int i = strlen(line); i >= 0; i--)
               if (line[i] == '\n' || line[i] == '\r')
                  line[i] = 0;
            putenv(line);
         }
      }
      fclose(file);
   }

   DEBUG_STREAM << "Red Planet v4.10" << std::endl << std::flush;
   DEBUG_STREAM << "L4CONTROLS=" << getenv("L4CONTROLS") << std::endl << std::flush;

//   GetProcessAffinityMask(GetCurrentProcess(), 
   DWORD_PTR res = SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)1);
   if (res == 0)
   {
      DWORD err = GetLastError();
	  DEBUG_STREAM << "Could not set thread affinity. Err Code = " << err << std::endl << std::flush;
   }

   //
   //----------------------------------------------------------------------
   // Parse command line for an egg notation file name
   //----------------------------------------------------------------------
   //
   int argc;
   LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
   Logical run_application = RPL4Application::ParseCommandLine(argc, argv);
   if (!run_application)
   {
      return 1;
   }
   else
   {
      Start_Registering();
   }

   //
   //-------------------------------------------------------------------------
   // Create our window. This is only temporary because this will move after
   // the graphics are moved over.
   //-------------------------------------------------------------------------
   //
   WNDCLASS wc;

   if (!hPrevInstance)
   {
      wc.style = 0; 
      wc.lpfnWndProc = (WNDPROC) WndProc;
      wc.cbClsExtra = 0; 
      wc.cbWndExtra = 0; 
      wc.hInstance = hInstance; 
      wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION); 
      wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); 
      wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
      wc.lpszMenuName =  NULL; 
      wc.lpszClassName = L"MainWndClass"; 

      if (!RegisterClass(&wc)) 
         return FALSE; 
   }


   DWORD wsStyle = WS_OVERLAPPED | WS_SYSMENU;
   if (L4Application::GetFullscreen())
      wsStyle = WS_POPUP;
   hWnd = CreateWindowEx(0, L"MainWndClass", L"RPL4", WS_OVERLAPPEDWINDOW, 0, 0, L4Application::GetScreenWidth(), L4Application::GetScreenHeight(), (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL);
   if (!hWnd)
      return FALSE;

	ShowWindow(hWnd, nShowCmd);
#if !_DEBUG
	ShowCursor(FALSE);
#endif

   //
   //-------------------------------------------------------------------------
   // Open the resource file.  The brace will help correct the scoping problem
   // of destruction the resource file
   //-------------------------------------------------------------------------
   //
   {
      StreamableResourceFile resources("rpl4.res", version);
      Check(&resources);

      //
      //----------------------------------------------
      // Create and initialize the application manager
      //----------------------------------------------
      //
      ApplicationManager* app_manager;
      Application *new_app;
      int review_mode = RPL4Application::GetMissionReviewMode();
      if (review_mode > 0)
      {
         MissionReviewApplicationManager *spool_mgr = new MissionReviewApplicationManager(hInstance, hWnd, atoi(getenv("TARGETFPS")), (review_mode == 2) ? 1 : 2, SPOOL_SIZE);
         app_manager = spool_mgr;
         Register_Object(app_manager);

         //
         //-------------------------------------------------------------------
         // Create and initialize the playback application if there is a spool
         // file
         //-------------------------------------------------------------------
         //
#if 1
		 CString spoolFileName = L4Application::GetSpoolFileName();
		 if (!spoolFileName)
			 spoolFileName = "last.spl";

         SpoolFile *spool = spool_mgr->GetStoredSpoolFile(spoolFileName);
         if (spool)
         {
            new_app = new RPL4PlaybackApplication(hInstance, hWnd, &resources, spool);
         } else
		 {
			 new_app = new RPL4IdleApplication(hInstance, hWnd, &resources);
		 }

        Register_Object(new_app);
        app_manager->StartApplication(new_app);
#else
         new_app = new RPL4PlaybackApplication(hInstance, hWnd, &resources, NULL);
         Register_Object(new_app);
         app_manager->StartApplication(new_app);
#endif

         //
         //------------------------------------
         // Initialize the spooling application
         //------------------------------------
         //
         if (review_mode == 1)
         {
            new_app = new L4SpoolingApplication(hInstance, hWnd, &resources, RPL4);
            Register_Object(new_app);
            app_manager->StartApplication(new_app);
         }
      }
      else
      {
		  app_manager = new ApplicationManager(hInstance, hWnd, atoi(getenv("TARGETFPS")));
         Register_Object(app_manager);

         //
         //--------------------------------------
         // Create and initialize the application
         //--------------------------------------
         //
         Application *new_app = new RPL4Application(hInstance, hWnd, &resources);
         rpl4App = new_app;
         Register_Object(new_app);
         SetCursorPos(1680 / 2, 1050 / 2);
         app_manager->StartApplication(new_app);
      }

      //
      //--------------------------
      // Run missions till we done
      //--------------------------
      //
      app_manager->RunMissions();
      rpl4App = NULL;
      Unregister_Object(app_manager);
      delete app_manager;
   }

	ShowCursor(TRUE);

   Stop_Registering();
   return Exit_Code;
}
