#pragma comment (lib, "advapi32.lib")

#include "common.h"

#include <iostream>

#include "fortress_skelet.h"
#include "cache_data.h"
#include "context.h"
#include "time_mapping.h"
#include "log.h"

#include <windows.h>

#ifdef _DEBUG
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endif

#ifdef DEBUG_URZA
ofstream debugOut("D:\\Urza\\desk\\debug.info.txt");
#endif

int main (int argc, char ** argv)
{
#ifdef _DEBUG
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG);
#endif

    if (argc == 6)
    {
        std :: cerr << "Divergent Teritory, last compilation: " << __DATE__ << ", " << __TIME__ << std :: endl;
        try
        {
            sockets :: socketsStart();
        }
        catch (std :: exception e)
        {
            std :: cerr << "Could not initialize WinSocks ver. 2.0";
            return 1;
        }

        if (gctx.createUniverse(argv[1], argv[2], argv[3], argv[4], atof(argv[5])))
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }

    if (argc == 7)
    {
        std :: cerr << "Divergent Teritory, last compilation: " << __DATE__ << ", " << __TIME__ << std :: endl;

        try
        {
            sockets :: socketsStart();
        }
        catch (std :: exception e)
        {
            std :: cerr << "Could not initialize WinSocks ver. 2.0";
            return 1;
        }

		startingGameResult sgr = gctx.startGame(argv[1], argv[2], argv[3], argv[4], atoi(argv[5]), atoi(argv[6]));
        if (SGR_OK == sgr)
        {
			// kdyz neexistuje admin, server jej zalozi (pokud existuje, nepujde pridat)			
			// chce-li nekdo admina s poradnym heslem, lze jej zalozit v db, server ho pak pridavat nebude
			realmClass * admin = new realmClass;
			admin->setPlayersNewName(string("Divergent Administrator"));
			admin->setNewLogin(string("admin"));
			admin->setNewPassword(string("admin"));
			if (NOT_VALID_ID == actx->cacheRealmsList.insertItem(admin))
			{
				delete admin;
			}
#ifdef CREATOR_URZA
			realmClass::createNewPlayer("Urza"    , "Urza"    , "Urza"    , 2, 1  , 1, 1  , 1  );
			realmClass::createNewPlayer("Yawgmoth", "Yawgmoth", "Yawgmoth", 1, 0.8, 1, 0.8, 0.8);
			realmClass::createNewPlayer("Mishra"  , "Mishra"  , "Mishra"  , 1, 0.6, 1, 0.6, 0.5);
			realmClass::createNewPlayer("Gerrard" , "Gerrard" , "Gerrard" , 2, 0.4, 1, 0.4, 0.2);
			realmClass::createNewPlayer("Karn"    , "Karn"    , "Karn"    , 2, 0.2, 1, 0.2, 0.1);
			realmClass::createNewPlayer("Squee"   , "Squee"   , "Squee"   , 1, 0  , 2, 0  , 0  );
#endif
#ifdef DEBUG_URZA
			debugOut << "DEBUG STARTED AT " << dv_time::now().toString() << endl;
			realmClass::createNewPlayer("Urza","Urza","12345=bezpecne heslo",8,1,8,1,1);
			realmClass::createNewPlayer("Mishra","Mishra","12345",8,0.88,8,0.88,0.88);
			realmClass::createNewPlayer("Yawgmoth","Yawgmoth","12345",8,1,8,1,1);
			realmClass::createNewPlayer("Squee","Squee","12345",8,0,8,0,0);
			realmClass::createNewPlayer("Starke","Starke","12345",8,0,8,0,0);
			realmClass::createNewPlayer("Xantcha","Xantcha","12345",8,0.5,8,0.5,0.5);
			realmClass::createNewPlayer("X","X","X",8,0.5,8,0.5,0.5);
			realmClass::createNewPlayer("XX","XX","XX",8,0.5,8,0.5,0.5);
			realmClass::createNewPlayer("XXX","XXX","XXX",8,0.5,8,0.5,0.5);
			realmClass::createNewPlayer("XXXX","XXXX","XXXX",8,0.5,8,0.5,0.5);
#endif
            std :: getline(std :: cin, std :: string());
            gctx.stopGame();
#ifdef DEBUG_URZA
			debugOut << "DEBUG FINISHED AT " << dv_time::now().toString() << endl;
			debugOut.close();
#endif
            std :: getline(std :: cin, std :: string());
        }
        else 
        {
			if (SGR_SPACE)
			{
				gctx.stopGame();
				LOG("Server wasn't able to start because there were no space; new space was created instead of game start.");
				std :: getline(std :: cin, std :: string());
			}
			else
			{
				errExceptionError("Start server failed!");
				std :: cerr << "Start game failed!" << std :: endl;
				std :: getline(std :: cin, std :: string());
			}
        }

        WSACleanup();

        return 0;
    }
    else
    {
        std :: cerr << "USAGE: server DBserver DBdatabase DBlogin DBpassword TCPport TCPmaxconnections" << std :: endl;
        return 1;
    }


	return 0;
}

/*
KONVENCE PSANÍ KÓDU
- proměnné velká malá písmena ( příklad helloWorld )
- pokud je proměnná v databázi , bude mít na konci DB ( příklad helloWorldBD )
- konstanty kapitálkama s podtržítkama ( příklad HELLO_WORLD )
- enumerátory jako konstanty
- odsazení o 4 ( tabulátorem )
- formát psaní podmínek a cyklů ( funkce vypadají stejně )
if ( podminka )
{
      prikazy
}
- jména funkcí mají stejnou konvenci jako proměnné
- privátní proměnné mají za sebou podtržítko ( helloWorldDB_ )
- oddělování funkcí : // --------------------------------
- oddělování skupin funkcí : // ================================
- oddělování tříd : // ################################
- do jednoho souboru třídy pouze v případě , že se využívají jen striktně mezi sebou , tedy pokud třídu využívá víc jiných tříd , patří do zvláštního souboru
- za KAŽDOU funkci
- komentáře česky , kód anglicky
- komentáře tříd pro doxygen začítná /** , každá řádka začíná * , končí */           /*
- komentáře funkcí pro doxygen na jednu řádku /// , jinak jako pro třídy
- atributy třídy ( tedy proměnné ) komentovat ///
- komentáře se píší buď ZA kód , nebo NAD kód , nikoliv POD
- kódy ( ve funkcích ) oddělovat prázdnou řádkou
- mezi KAŽDÝMA dvěma definicema funkcí bude MINIMÁLNĚ prázdný řádek , pak oddělítko ( viz výše ) , pak zas prázdný řádek
- funkce nebude mít více než čtyři parametry ( pokud více , dá se do struktur )
*/