// ****************************************************************************
// ****************************************************************************
// ****************************************************************************
// ****************************************************************************
//             T H E         U R G E N T         D E C I S S I O N 
//                   
//             S P I E L S E R V E R :-)
// ****************************************************************************
// ****************************************************************************
// ****************************************************************************
// ****************************************************************************

// spaeter : per define einen read verbieten, dass man alle read nach
// read_check umwandeln kann


// Welche Includes debuggen ? *************************************************
//#define DEBUG
//#define DEBUG_iotype_H
//#define DEBUG_sprite_H
//#define DEBUG_listen_H
//#define DEBUG_listen_H_low
//#define DEBUG_communic_H
// Welche Includes debuggen ? *************************************************
#include <sys/time.h>
#include <unistd.h> // for usleep()
#include <iostream.h>
//#include <sys/resource.h>
#include "allgtypedef.H"
#include "terminal.H"
#include "datei.H"                                     
#include "listen2.H"                                   
#include "sprite01.H"
#include "vektor.H"
#include "communic.H"
#include "iotype.H"

#include "tudinc_server.H"

void parameterhelp()
{
  cout <<"\nAllowed Parameters:\n"
       <<"tudserver [levelfilename [setupfilename]] or [ --help ]\n"
       <<"Default:\n"
       <<"tudserver level/test.lev setups/setup_server.set\n\n";
  exit(1);
}

void help()
{
  cout << 
    "SERVER COMMAND SET:\n"
    "Command      Arguments                 Description\n"
    "====================================================================\n"
    "create       x y dir player vehicle    Create a vehicle at x,y dir \n"
    "                        (tiger|ship)   owner player of type vehicle\n"
    "give         no anz object             Give vehicle no. anz objects\n"
    "                    (object/fuel.obj)\n"
    "save         filename (level/XX.lev)   Save game\n"
    "wantedti     float                     Set the wanted Timeinterval\n"
    "showti                                 Show Timeinterval (sec.)\n"
    "showsleep                              Show time available (sec.)\n"
    "help                                   This Message\n"
    "exit                                   Exit  Game\n";
}


// *************************************** MAIN ****************************
// *************************************** MAIN ****************************
// *************************************** MAIN ****************************
// *************************************** MAIN ****************************
// *************************************** MAIN ****************************
// *************************************** MAIN ****************************

int main(int argc,char **argv)
{
  init_allsprites_kette("palette.ppm");
  untergrundtabptr=new untergrundtabtype("untergrund.tab");
  einheit_daten_ketteptr=new einheit_daten_kette_iqtype;
  objekt_daten_ketteptr=new objekt_daten_kette_iqtype;
  cout << "\n*-*-*-*-*-*  T-H-E  *-*-*-*  U-R-G-E-N-T  *-*-*-* D-E-C-I-S-I-O-N *-*-*-*-*-*\n"
       << "Gameserver Ver. 0.8.0\n"
       << "Contact:                EMAIL: karme@unforgettable.com\n"
       << "Newest Version at:      http://www.geocities.com/TimesSquare/Castle/9663\n"
       << "This info may be out of date => read tud/doc/tud.html\n";

  // Setup laden ************************************************************
  string setup;
  string levelname;
  if (argc<2)
    {

      levelname="level/test.lev";
    }
  else
    {
      levelname=argv[1];
      if (!strcmp("--help",levelname.c_str()))
	parameterhelp();
    }
  if (argc<3)
    setup="setups/setup_server.set";
  else if (argc==3)
    setup=argv[2];
  else if (argc>3)
    parameterhelp();

  cout <<"\nLoad setup...\n";
  iotype *ioptr=make_file_to_io_check(setup.c_str());
  cfgtype *cfgptr=choose_cfgtype(ioptr,CFG_TEXT_MODE);
  cfgptr->change_float_check(&wunschti);
  cfgptr->change_float_check(&muehmineexplosion);
  cfgptr->change_float_check(&mineexplosionsradius);
  cfgptr->change_marke_check("ende");
  delete cfgptr;
  delete ioptr;

  // Spiel laden ************************************************************
  levelptr=new leveltype;
  levelptr->ladelevel(levelname.c_str());
  // Die Spieler
  spieler_ketteptr=new spieler_kettetype;
  
  timeval zeit;
  gettimeofday(&zeit,NULL);
  timeval oldzeit;    
  float minti=100;
  float maxti=0;
  float avgti=0;
  float anztakte=0;
  float timeavailable;
  
  uint32 takt=0;
  char ende=0;
  cout <<"The Server is now running...\n";
  help();
  do
	{
	    oldzeit=zeit;
	    gettimeofday(&zeit,NULL);
	    deltati=getdeltatime(&oldzeit,&zeit);
	    if (deltati<wunschti) 
		{
		  timeavailable=wunschti-deltati;
		  usleep( (ulong)(timeavailable*1000000) );
		  /* Abbrechen wenn msg von einem client
		  timeval deltatime;
		  deltatime.tv_sec=0;
		  deltatime.tv_usec=(long)(timeavailable*1000000);
		  servermsg_ketteptr->msgavail(&deltatime);*/
		  gettimeofday(&zeit,NULL);
		  deltati=getdeltatime(&oldzeit,&zeit);
		}
	    else
	      timeavailable=0;

	    if (!deltati)
		{
		    printf("Deltati war 0 !!!\n");
		    deltati=0.000001;
		}
	    if ((deltati<minti)&&takt)
		minti=deltati;
	    if ((deltati>maxti)&&takt)
		maxti=deltati;
	    // todo is bad ...
	    avgti*=anztakte;
	    anztakte+=1.0;
	    avgti+=deltati;
	    avgti/=anztakte;

	    // spaeter
	    //	    printf("ti: %f\n",deltati);

	    takt++;
//	    printf("********************************************** Taktnr. : %i\n",takt);

	    levelptr->calc();

	    // Ende Taste ?
	    string befehl;
	    if (kbhit())
	      {
		cin >>befehl;
		if (befehl=="exit")
		  ende=1;
		else if (befehl=="showti")
		  printf("Deltati is: %f\n",deltati);
		else if (befehl=="wantedti")
		  cin >> wunschti;
		else if (befehl=="showsleep")
		  cout <<"Available time: "<<timeavailable<<endl;
		else if (befehl=="save")
		  {
		    string filename;
		    cin >> filename;
		    levelptr->savelevel(filename.c_str());
		  }
		else if (befehl=="help")
		    help();
		else if (befehl=="create")
		  {
		    vektor2_koordtype newpos;
		    float dir;
		    int32 spieler;
		    string name;
		    cin >>newpos.x>>newpos.y>>dir>>spieler>>name;
		    name="vehicle/"+name+".veh";
		    einheit_server_ketteptr->create(name.c_str(),&newpos,spieler,dir);
		  }
		else if (befehl=="send")
		  {
		    // todo !!
		    char z[1001];
		    cin.getline(z,1000);
		    cout <<"Sorry .. this doesn't work yet !!\n";
		  }
		else if (befehl=="give")
		  {
		    uint32 nr;
		    cin >>nr;
		    float anz;
		    cin >>anz;
		    string object;
		    cin >>object;
		    if (cin.good())
		      {
			einheit_server_zeigerelemtype *akt;
			if (kette_search(einheit_server_ketteptr,nr,akt))
			  {
			    akt->objekt_kette.add(object.c_str(),anz);
			  }
			else
			  cout <<"Vehicle No. "<<nr<<" does not exist.\n";
		      }
		  }
		else 
		  cout <<"Unknown Command -> type 'help'\n";
	      }
	}
    while(!ende);   
    printf("Normal End !!!\n");
    allsprites_ketteptr->test();
    delete spieler_ketteptr;
    delete levelptr;
    delete objekt_daten_ketteptr;
    delete einheit_daten_ketteptr;
    delete untergrundtabptr;
    deinit_allsprites_kette();
    printf("Min Deltati: %f\n",minti);
    printf("Max Deltati: %f\n",maxti);
    printf("Avg Deltati: %f\n",avgti);
    exit(0);
//    speicherusage();
};


