//------------------------------------------------------------------------
//  COOKIE : Save/Load user settings
//------------------------------------------------------------------------
//
//  Oblige Level Maker (C) 2006,2007 Andrew Apted
//  Changes (C) 2007-2017 Sam Trenholme and Fritz
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//------------------------------------------------------------------------

#include "headers.h"
#include "hdr_fltk.h"

#include "g_cookie.h"

#include "lib_util.h"
#include "ui_chooser.h"
#include "ui_dialog.h"
#include "ui_window.h"
#include "main.h"


static FILE *cookie_fp;


static bool Cookie_SetValue(const char *name, const char *value)
{
  DebugPrintf("CONFIG: Name: [%s] Value: [%s]\n", name, value);

  // We don't store the seed
  if (StrCaseCmp(name, "seed") == 0)	
    //return main_win->setup_box->set_Seed("1987");
    return 0;

  // Settings...

  if (StrCaseCmp(name, "game") == 0)
    return main_win->setup_box->set_Game(value);
  if (StrCaseCmp(name, "port") == 0)
    return main_win->setup_box->set_Port(value);
  if (StrCaseCmp(name, "length") == 0)
    return main_win->setup_box->set_Length(value);
  if (StrCaseCmp(name, "mode") == 0)
    return main_win->setup_box->set_Mode(value);

  // Adjustments...

  
  if (StrCaseCmp(name, "size") == 0)
    return main_win->adjust_box->set_Size(value);
  if (StrCaseCmp(name, "maxsize") == 0)
    return main_win->adjust_box->set_maxSize(value);
  if (StrCaseCmp(name, "steep") == 0)
    return main_win->adjust_box->set_Steep(value);
  if (StrCaseCmp(name, "puzzles") == 0)
    return main_win->adjust_box->set_Puzzles(value);
  if (StrCaseCmp(name, "traps") == 0)
    return main_win->adjust_box->set_Traps(value);
  if (StrCaseCmp(name, "outdoors") == 0)
    return main_win->adjust_box->set_Outdoors(value);
  if (StrCaseCmp(name, "iweapon") == 0)
    return main_win->adjust_box->set_Iweapon(value);
  if (StrCaseCmp(name, "switches") == 0)
    return main_win->adjust_box->set_Switches(value);
  if (StrCaseCmp(name, "keytype") == 0)
    return main_win->adjust_box->set_KeyType(value);
  if (StrCaseCmp(name, "roomsize") == 0)
    return main_win->adjust_box->set_RoomSize(value);
  if (StrCaseCmp(name, "lighting") == 0)
    return main_win->adjust_box->set_Lighting(value);
  if (StrCaseCmp(name, "enclosure") == 0)
    return main_win->adjust_box->set_Enclosure(value);
  if (StrCaseCmp(name, "questlength") == 0)
    return main_win->adjust_box->set_QuestLength(value);
  if (StrCaseCmp(name, "hallways") == 0)
    return main_win->adjust_box->set_Hallways(value);
  if (StrCaseCmp(name, "stairs") == 0)
    return main_win->adjust_box->set_Stairs(value);
  if (StrCaseCmp(name, "secrets") == 0)
    return main_win->adjust_box->set_Secrets(value);


  if (StrCaseCmp(name, "health") == 0)
    return main_win->adjust_box->set_Health(value);
  if (StrCaseCmp(name, "ammo") == 0)
    return main_win->adjust_box->set_Ammo(value);
  if (StrCaseCmp(name, "mons") == 0)
    return main_win->adjust_box->set_Monsters(value);
  

  // Other stuff...
  if (StrCaseCmp(name, "last_file") == 0)
    return UI_SetLastFile(value);

  LogPrintf("CONFIG: Ignoring unknown setting: %s = %s\n", name, value);
  return false;
}

static bool Cookie_ParseLine(char *buf)
{
  // remove whitespace
  while (isspace(*buf))
    buf++;

  int len = strlen(buf);

  while (len > 0 && isspace(buf[len-1]))
    buf[--len] = 0;
 
  // ignore blank lines and comments
  if (*buf == 0)
    return true;

  if (buf[0] == '-' && buf[1] == '-')
    return true;

  if (! isalpha(*buf))
  {
    LogPrintf("Weird config line: [%s]\n", buf);
    return false;
  }

  // Righteo, line starts with an identifier.  It should be of the
  // form "name = value".  We'll terminate the identifier, and pass
  // the name/value strings to the matcher function.

  const char *name = buf;

  for (buf++; isalpha(*buf) || *buf == '_'; buf++)
  { /* nothing here */ }

  while (isspace(*buf))
    *buf++ = 0;
  
  if (*buf != '=')
  {
    LogPrintf("Config line missing '=': [%s]\n", buf);
    return false;
  }

  *buf++ = 0;

  while (isspace(*buf))
    buf++;

  if (*buf == 0)
  {
    LogPrintf("Config line missing value!\n");
    return false;
  }

  return Cookie_SetValue(name, buf);
}

//------------------------------------------------------------------------


bool Cookie_Load(const char *filename)
{
  cookie_fp = fopen(filename, "r");

  if (! cookie_fp)
  {
    LogPrintf("Missing Config file -- using defaults.\n\n");
    return false;
  }

  LogPrintf("Loading Config...\n");

  // simple line-by-line parser
  char buffer[MSG_BUF_LEN];

  int error_count = 0;

  while (fgets(buffer, MSG_BUF_LEN-2, cookie_fp))
  {
    if (! Cookie_ParseLine(buffer))
      error_count += 1;
  }

  if (error_count > 0)
    LogPrintf("DONE (found %d parse errors)\n\n", error_count);
  else
    LogPrintf("DONE.\n\n");
    fclose(cookie_fp);

  return true;
}

bool Cookie_Save(const char *filename)
{
  cookie_fp = fopen(filename, "w");

  if (! cookie_fp)
  {
    LogPrintf("Error: unable to create file: %s\n(%s)\n\n",
        filename, strerror(errno));
    return false;
  }

  LogPrintf("Saving Config...\n");

  // header...
  fprintf(cookie_fp, "-- CONFIG FILE : ObHack %s\n", OBLIGE_VERSION); 
  fprintf(cookie_fp, "-- Oblige Level Generator" " (C) 2006-2007 Andrew Apted\n");
  fprintf(cookie_fp, "-- " OBLIGE_TITLE " (C) 2007-2017 Sam Trenholme\n");
  fprintf(cookie_fp, "-- " OBLIGE_TITLE " (C) 2009-2012 Fritz Langhart\n");
  fprintf(cookie_fp, "-- http://www.samiam.org/obhack/\n");
  fprintf(cookie_fp, "-- http://oblige.sourceforge.net/\n\n");

  // FIXME: duplicate code from g_doom.cc : How to merge??
 
  fprintf(cookie_fp, "-- Settings --\n");
  fprintf(cookie_fp, "seed = %s\n",  main_win->setup_box->get_Seed());
  fprintf(cookie_fp, "game = %s\n",  main_win->setup_box->get_Game());
  fprintf(cookie_fp, "port = %s\n",  main_win->setup_box->get_Port());
  fprintf(cookie_fp, "mode = %s\n",  main_win->setup_box->get_Mode());
  fprintf(cookie_fp, "length = %s\n",main_win->setup_box->get_Length());
  fprintf(cookie_fp, "\n");

  fprintf(cookie_fp, "-- Adjustments --\n");
  fprintf(cookie_fp, "size = %s\n",  main_win->adjust_box->get_Size());
  fprintf(cookie_fp, "maxsize = %s\n",  main_win->adjust_box->get_maxSize());
  fprintf(cookie_fp, "steep = %s\n",  main_win->adjust_box->get_Steep());
  fprintf(cookie_fp, "puzzles = %s\n",  main_win->adjust_box->get_Puzzles());
  fprintf(cookie_fp, "mons = %s\n",   main_win->adjust_box->get_Monsters());
  fprintf(cookie_fp, "health = %s\n", main_win->adjust_box->get_Health());
  fprintf(cookie_fp, "ammo = %s\n",   main_win->adjust_box->get_Ammo());
  fprintf(cookie_fp, "outdoors = %s\n", main_win->adjust_box->get_Outdoors());
  fprintf(cookie_fp, "iweapon = %s\n", main_win->adjust_box->get_Iweapon());
  fprintf(cookie_fp, "switches = %s\n", main_win->adjust_box->get_Switches());
  fprintf(cookie_fp, "keytype = %s\n", main_win->adjust_box->get_KeyType());
  fprintf(cookie_fp, "roomsize = %s\n", main_win->adjust_box->get_RoomSize());
  fprintf(cookie_fp, "lighting = %s\n", main_win->adjust_box->get_Lighting());
  fprintf(cookie_fp, "enclosure = %s\n", main_win->adjust_box->get_Enclosure());
  fprintf(cookie_fp, "questlength = %s\n", main_win->adjust_box->get_QuestLength());
  fprintf(cookie_fp, "hallways = %s\n", main_win->adjust_box->get_Hallways());
  fprintf(cookie_fp, "stairs = %s\n", main_win->adjust_box->get_Stairs());
  fprintf(cookie_fp, "secrets = %s\n", main_win->adjust_box->get_Secrets());

  fprintf(cookie_fp, "\n");

  fprintf(cookie_fp, "-- Miscellaneous --\n");
  fprintf(cookie_fp, "last_file = %s\n", UI_GetLastFile());
  fprintf(cookie_fp, "\n");

  LogPrintf("DONE.\n\n");
  fclose(cookie_fp);

  return true;
}

