#pragma once
#include <map>
#include <string>
#include "libs.h"
#include "gui.h"
#include "view.h"
#include "mtrand.h"

class Player;
class SectorView;
class SystemView;
class WorldView;
class SystemInfoView;
class ShipCpanel;
class StarSystem;
class SpaceStationView;
class InfoView;

class IniConfig: private std::map<std::string, std::string> {
public:
  IniConfig(const char* filename);
  int Int(const char* key) {
    return atoi((*this)[key].c_str());
  }
  float Float(const char* key) {
    float val;
    if(sscanf((*this)[key].c_str(), "%f", &val)==1) return val;
    else return 0;
  }
  std::string String(const char* key) {
    return (*this)[key];
  }
};

/* Implementation is done in main.cpp, just to confuse you. :D */
class L3D {
public:
  static void   Init(IniConfig& config);
  static void   MainLoop(void);
  static void   Quit(void);
  static float  GetFrameTime(void)            { return frameTime; }
  static double GetGameTime(void)             { return gameTime; }
  static void   SetTimeStep(float s)          { timeStep = s; }
  static float  GetTimeStep(void)             { return timeStep; }
  static int    GetScrWidth(void)             { return scrWidth; }
  static int    GetScrHeight(void)            { return scrHeight; }
  static int    GetScrAspect(void)            { return scrAspect; }
  static int    KeyState(SDLKey k)            { return keyState[k]; }
  static int    MouseButtonState(int button)  { return mouseButton[button]; }
  static void   GetMouseMotion(int motion[2]) {
    memcpy(motion, mouseMotion, sizeof(int)*2);
  }

  static sigc::signal<void, SDL_keysym*> onKeyPress;
  static sigc::signal<void, SDL_keysym*> onKeyRelease;
  static sigc::signal<void, int, int, int> onMouseButtonUp;
  static sigc::signal<void, int, int, int> onMouseButtonDown;

  static MTRand rng;

  static void HyperspaceTo(StarSystem* destination);
  enum CamType { CAM_FRONT, CAM_REAR, CAM_EXTERNAL };
  enum MapView { MAP_NOMAP, MAP_SECTOR, MAP_SYSTEM };
  static void SetCamType(enum CamType);
  static void SetMapView(enum MapView);
  static enum CamType GetCamType(void)  { return cam_type; }
  static enum MapView GetMapView(void)  { return map_view; }
  static void SetView(View* v);
  static View* GetView(void)            { return current_view; }
  static StarSystem* GetSelectedSystem(void);

  static Player*            player;
  static SectorView*        sector_view;
  static SystemInfoView*    system_info_view;
  static WorldView*         world_view;
  static SpaceStationView*  spaceStationView;
  static InfoView*          infoView;
  static ShipCpanel*        cpan;
  static GLUquadric*        gluQuadric;

private:
  static void InitOpenGL(void);
  static void HandleEvents(void);

  static View* current_view;
  static SystemView* system_view;

  static double       gameTime;
  static StarSystem*  selected_system;
  static enum CamType cam_type;
  static enum MapView map_view;
  static float        timeStep;
  static float        frameTime;
  static int          scrWidth, scrHeight;
  static float        scrAspect;
  static SDL_Surface* scrSurface;
  static char         keyState[SDLK_LAST];
  static char         mouseButton[5];
  static int          mouseMotion[2];
};