
struct menu *setmenu;

char backsel[] = "Back";

#define MAINMENU_ITEMCOUNT 2

#if defined(SDLFUNCS) || defined(DOS)
char startgamestr[] = "Start game";
char quitgamestr[] = "Quit game";
char settingsstr[] = "Game settings";
char depth1str[] = "Depth 1";
char depth2str[] = "Depth 2";
char blunderstr[] = "Blunders";
char whitestr[] = "White player";
char blackstr[] = "Black player";
char clippystr[] = "Clippy";
char humanstr[] = "Human";
char yesstr[] = "Yes";
char nostr[] = "No";
char bookopeningstr[] = "Use opening book";
char slidepiecesstr[] = "Slide pieces";
unsigned char maxdepth2 = 128;
unsigned char mindepth = 1;
unsigned char blunderset = 0;
unsigned char minblunders = 0;
unsigned char maxblunders = 15;
#endif

unsigned char white_ai = 0;
unsigned char black_ai = 1;

void game(void);

void start_game(void)
{
  if(graphics)
  {
    mainmenu->prev = 1;
    mainmenu->menuitems[0].passive = 1;
  }

  do
  {
    memset(&game_status, 0, sizeof(game_status));
    game_status.turn = 0;
    turn_count = 0;
    init_board(&board);
    game();
  }
  while(dontstop);

  if(graphics)
  {
    mainmenu->prev = 0;
    mainmenu->menuitems[0].passive = 0;
  }
}

#if defined(SDLFUNCS) || defined(DOS)
void quit_game(void)
{
  exit(0);
}

#define MENU_X 20
#define MENU_Y 20

void set_blunders(void)
{
  if(!blunderset)
    blunders = 0;
  else
    blunders = 16 - blunderset;
}

void show_menu(struct menu *menu)
{
  signed char sel;
  unsigned char i;
  unsigned char color;
  char *str;
  char buf[16];

  if(menu->prev) sel = -1;
  else sel = 0;

  while(1)
  {
    fill_screen(1);

    if(menu->prev)
    {
      if(sel == -1)
        color = 0xF;
      else
        color = 0x7;
      print_text(MENU_X, MENU_Y, color, backsel);
    }

    for(i=0;i<menu->menuitem_count;i++)
    {
      if(i == sel)
        color = 0xF;
      else if(menu->menuitems[i].passive)
        color = 0x8;
      else
        color = 0x7;

      print_text(MENU_X, MENU_Y+12+i*12, color, menu->menuitems[i].str);
      if(menu->menuitems[i].value)
      {
        if(menu->menuitems[i].choices)
          str = menu->menuitems[i].choices[*menu->menuitems[i].value];
        else
        {
          sprintf(buf, "%u", *menu->menuitems[i].value);
          str = buf;
        }
        print_text(MENU_X+200, MENU_Y+12+i*12, 2, str);
      }
    }

    update_screen();

    switch(poll_keypress())
    {
      case KEY_UP:
        if(menu->prev ? sel>-1 : sel > 0) sel--;
        break;
      case KEY_DOWN:
        if(sel < menu->menuitem_count-1) sel++;
        break;
      case KEY_RIGHT:
        if(sel >= 0)
        {
          if(menu->menuitems[sel].value)
            if(*menu->menuitems[sel].value < *menu->menuitems[sel].maxvalue)
              ++*menu->menuitems[sel].value;
          goto fn;
        }
      case KEY_LEFT:
        if(sel >= 0)
        {
          if(menu->menuitems[sel].value)
            if(*menu->menuitems[sel].value > *menu->menuitems[sel].minvalue)
              --*menu->menuitems[sel].value;
          goto fn;
        }
      case KEY_ENTER:
        if(sel == -1)
          return;
        else if(menu->menuitems[sel].passive)
          break;
        else fn:if(menu->menuitems[sel].fnptr)
          (menu->menuitems[sel].fnptr)();
        else if(menu->menuitems[sel].submenu)
          show_menu(menu->menuitems[sel].submenu);
        break;
    }
  }
}

signed char add_menuitem(struct menu *menu, struct menuitem *menuitem)
{
  void *ptr;

  if(!menu->menuitem_count)
  {
    menu->menuitems = malloc(sizeof(struct menuitem));
    if(!menu->menuitems) return -1;
  }
  else
  {
    ptr = realloc(menu->menuitems, (menu->menuitem_count+1)*sizeof(struct menuitem));
    if(!ptr) return -1;
    menu->menuitems = ptr;
  }

  menu->menuitems[menu->menuitem_count] = *menuitem;

  return menu->menuitem_count++;
}

int init_menus(void)
{
  struct menuitem menuitem = { 0 };
  signed char r1, r2;
  void *ptr;

  mainmenu = calloc(1, sizeof(struct menu));
  if(!mainmenu) return 1;

  // start game
  menuitem.str = startgamestr;
  menuitem.fnptr = start_game;
  if(add_menuitem(mainmenu, &menuitem) == -1)
    return 1;

  // settings
  setmenu = calloc(1, sizeof(struct menu));
  if(!setmenu) return 1;

  setmenu->prev = 1;

  memset(&menuitem, 0, sizeof(menuitem));
  menuitem.str = settingsstr;
  menuitem.submenu = setmenu;
  if(add_menuitem(mainmenu, &menuitem) == -1)
    return 1;

  memset(&menuitem, 0, sizeof(menuitem));

  menuitem.str = whitestr;
  menuitem.value = &white_ai;
  menuitem.minvalue = &minblunders;
  menuitem.maxvalue = &mindepth;
  menuitem.choices = malloc(2*sizeof(char**));
  if(!menuitem.choices)
    return 1;
  menuitem.choices[0] = humanstr;
  menuitem.choices[1] = clippystr;
  if(add_menuitem(setmenu, &menuitem) == -1)
    return 1;

  menuitem.str = blackstr;
  menuitem.value = &black_ai;
  if(add_menuitem(setmenu, &menuitem) == -1)
    return 1;

  memset(&menuitem, 0, sizeof(menuitem));

  menuitem.str = depth1str;
  menuitem.value = &depth1;
  menuitem.minvalue = &mindepth;
  if((r1 = add_menuitem(setmenu, &menuitem)) == -1)
    return 1;

  menuitem.str = depth2str;
  menuitem.value = &depth2;
  menuitem.minvalue = setmenu->menuitems[r1].value;
  menuitem.maxvalue = &maxdepth2;
  if((r2 = add_menuitem(setmenu, &menuitem)) == -1)
    return 1;

  menuitem.str = blunderstr;
  menuitem.value = &blunderset;
  menuitem.minvalue = &minblunders;
  menuitem.maxvalue = &maxblunders;
  menuitem.fnptr = set_blunders;
  if(add_menuitem(setmenu, &menuitem) == -1)
    return 1;

  memset(&menuitem, 0, sizeof(menuitem));
  menuitem.str = bookopeningstr;
  menuitem.value = &book_openings;
  menuitem.minvalue = &minblunders;
  menuitem.maxvalue = &mindepth;
  menuitem.choices = malloc(2*sizeof(char**));
  if(!menuitem.choices)
    return 1;
  menuitem.choices[0] = nostr;
  menuitem.choices[1] = yesstr;
  if(add_menuitem(setmenu, &menuitem) == -1)
    return 1;

  menuitem.str = slidepiecesstr;
  menuitem.value = &slide_pieces;
  if(add_menuitem(setmenu, &menuitem) == -1)
    return 1;

  setmenu->menuitems[r1].maxvalue = setmenu->menuitems[r2].value;

  // quit game
  memset(&menuitem, 0, sizeof(menuitem));
  menuitem.str = quitgamestr;
  menuitem.fnptr = quit_game;
  if(add_menuitem(mainmenu, &menuitem) == -1)
    return 1;

  return 0;
}

#endif
