/*
 * Atom-4 main program
 * ---------------------------------------------------------------------------
 * $Id: atom4.cc,v 1.10 2003/03/12 15:35:50 hsteoh Exp hsteoh $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>			// for time()
#include <unistd.h>			// for getopt()

#include "ai.h"
#include "event.h"
#include "exception.h"
#include "game.h"
#include "interface.h"
#include "textui.h"
#include "xatom4.h"
#include "xutil.h"

#define BOARD_WIDTH	16
#define BOARD_HEIGHT	16


enum game_mode { AUTO_MODE=0, NCURSES_MODE, X11_MODE };


void seed_rand() {
  srand((unsigned int)time(NULL));
}

interface *init_ui(game_mode mode, int iface_opts, atom4 *engine,
                   eventloop *loop, int *exitflag) { // [O]([R],[R])
  switch (mode) {
  case X11_MODE:
    // NULL = use $env{DISPLAY}
    return new x11ui(NULL, engine, loop, exitflag);
  case NCURSES_MODE:
    return new ncurses_ui(engine, loop, exitflag, iface_opts);
  default:
    fprintf(stderr, "Internal error: unknown interface mode\n");
    exit(-1);
  }
}

void display_help() {
  fprintf(stderr,
    "Syntax: atom4 [options]\n"
    "Options:\n"
    " -a<n>  Enable AI player as player <n>\n"
    " -c     [NCURSES] Enable color (if your terminal supports it)\n"
    " -d<n>  [AI] Set difficulty level (0=easiest, 2=default (harder), ...)\n"
    " -h     Show this help\n"
    " -mt    Use text mode (NCURSES)\n"
    " -mx    Use X11 mode\n"
  );
  exit(1);
}

int main(int argc, char *argv[]) {
  game_mode mode=AUTO_MODE;
  int iface_opts=0, ai_player=0, ai_level=2;
  int ch;

  while ((ch=getopt(argc, argv, "a:cd:hm:")) != -1) {
    switch (ch) {
    case 'a':
      if (*optarg=='1') ai_player=1;
      else if (*optarg=='2') ai_player=2;
      else {
        fprintf(stderr, "Bad AI player spec: %s\n", optarg);
        exit(1);
      }
      break;
    case 'c':	iface_opts |= ncurses_ui::ENABLE_COLOR;	break;
    case 'd':	ai_level = atoi(optarg); break;
    case 'm':
      if (!strcmp(optarg, "t")) {
        mode = NCURSES_MODE;
      } else if (!strcmp(optarg, "x")) {
        mode = X11_MODE;
      } else {
        fprintf(stderr, "Unknown mode spec: %s\n", optarg);
        exit(1);
      }
      break;
    case '?':	case 'h':	default:
      display_help();			// never returns
    }
  }

  // Auto mode: run X11 interface if $DISPLAY is set, otherwise run ncurses
  // interface.
  if (mode == AUTO_MODE) {
    char *xdisplay = getenv("DISPLAY");
    mode = (xdisplay) ? X11_MODE : NCURSES_MODE;
  }

  // Initialize game engine & event loop
  try {
    eventloop mainloop;
    atom4 *game_engine;

    seed_rand();
    if (ai_player) {
      fprintf(stderr, "Initializing AI as player %d\n", ai_player);
      game_engine = new atom4ai(&mainloop, BOARD_WIDTH, BOARD_HEIGHT,
                                ai_player);
      fprintf(stderr, "Setting AI difficulty as %d\n", ai_level);
      ((atom4ai*)game_engine)->set_search_depth(ai_level);
    } else {
      game_engine = new atom4local(BOARD_WIDTH, BOARD_HEIGHT);
    }
    int exitflag=0;
    interface *ui = init_ui(mode, iface_opts, game_engine, &mainloop,
                            &exitflag);

    // Main loop
    try {
      mainloop.run(&exitflag);
    } catch(...) {
      delete ui;
      throw;
    }
    delete ui;
  } catch(exception &e) {
    fprintf(stderr, "Exception: %s\n", e.message());
    exit(1);
  }

  fprintf(stderr, "Exiting normally\n");
  return 0;
}

