// Necklace of the Eye v3.0
// roguelike frontend
// Copyright (C) 2010-2011 Zeno Rogue, see 'noteye.h' for details

static GFX gfx;

static SDL_Surface *exsurface;

static bool sdlerror = false;

void initMode() {

  if(sdlerror) return;
  
  if(SDL_Init(SDL_INIT_VIDEO) < 0) {
    fprintf(errfile, "Failed to initialize SDL: '%s'\n", SDL_GetError());
    sdlerror = true;
    return;
    }

  if(exsurface) return;
  exsurface=SDL_CreateRGBSurface(SDL_SWSURFACE,16,16,32,0,0,0,0);
  if(exsurface == NULL) {
    fprintf(errfile, "CreateRGBSurface failed: %s\n", SDL_GetError());
    sdlerror = true;
    return;
    }

  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  SDL_EnableUNICODE(1);
  }

#ifdef USELUA
int lh_findvideomode(lua_State *L) {
  int sx = luaInt(1);
  int sy = luaInt(2);
  
  initMode();
  
  SDL_Rect **modes;
  modes=SDL_ListModes(exsurface->format, SDL_FULLSCREEN);
  
  int nsx = 99999, nsy = 99999;

  if(modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1) {
    nsx = sx; nsy = sy;
    }
  else for(int i=0;modes[i];i++) {
    if (modes[i]->w >= sx && modes[i]->h >= sy) {
      if(modes[i]->w > nsx || modes[i]->h > nsy) continue;
      nsx = modes[i]->w;
      nsy = modes[i]->h;
      }
    }
  lua_newtable(L);
  setfield(L, "x", nsx);
  setfield(L, "y", nsy);
  return 1;
  }

int lh_setvideomode(lua_State *L) {
  checkArg(L, 3, "setvideomode");

  int sx = luaInt(1);
  int sy = luaInt(2);
  bool full = luaBool(3);

  SDL_Surface *s = SDL_SetVideoMode(sx, sy, 32, full ? SDL_FULLSCREEN : 0);
  if(!s) return retBool(L, false);
  
  gfx.full = full;
  gfx.s = s;

  return retBool(L, true);
  }

int lh_closevideomode(lua_State *L) {
  checkArg(L, 1, "closevideomode");
  gfx.s = NULL;
  return 0;
  }

int lh_setwindowtitle(lua_State *L) {
  checkArg(L, 1, "setwindowtitle");
  const char *s = luaStr(1);
  SDL_WM_SetCaption(s, s);
  return 0;
  }

bool GFX::checkEvent(lua_State *L) {
  initMode();
  if(sdlerror) return false;
  fflush(logfile);
  SDL_Event ev;
  if(SDL_PollEvent(&ev)) {
    if(ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP) {
      SDL_KeyboardEvent& kev(ev.key);
      lua_newtable(L);
      setfield(L, "type", ev.type == SDL_KEYDOWN ? evKeyDown : evKeyUp);
      setfield(L, "symbol", kev.keysym.sym);
      setfield(L, "mod", kev.keysym.mod);
      setfield(L, "chr", kev.keysym.unicode);
      return true;
      }

    if(ev.type == SDL_MOUSEMOTION) {
      SDL_MouseMotionEvent& mev(ev.motion);
      lua_newtable(L);
      setfield(L, "type", evMouseMotion);
      setfield(L, "x", mev.x);
      setfield(L, "y", mev.y);
      setfield(L, "state", mev.state);
      return true;
      }

    if(ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP) {
      SDL_MouseButtonEvent& mev(ev.button);
      lua_newtable(L);
      setfield(L, "type", ev.type == SDL_MOUSEBUTTONDOWN ? evMouseDown : evMouseUp);
      setfield(L, "x", mev.x);
      setfield(L, "y", mev.y);
      setfield(L, "state", SDL_GetMouseState(NULL, NULL));
      setfield(L, "button", mev.button);
      return true;
      }

    if(ev.type == SDL_QUIT) {
      lua_newtable(L);
      setfield(L, "type", evQuit);
      return true;
      }
    }
  return false;
  }

int lh_updaterect(lua_State *L) {
  gfx.setLock(false);
  if(gfx.s == NULL) return 0;
  checkArg(L, 4, "updaterect");
  SDL_Rect rect;
  rect.x = luaInt(1);
  rect.y = luaInt(2);
  rect.w = luaInt(3);
  rect.h = luaInt(4);
  SDL_UpdateRects(gfx.s, 1, &rect);
  return 0;
  }
#endif

void halt() {
  // tty_fix();
  logfile && fclose(logfile);
  extern void closeAudio();
  closeAudio();
  SDL_Quit(); gfx.s = NULL;
  for(int i=2; i<size(objs); i++) delete objs[i];
  exit(0);
  }

