
#ifndef config_c_INCLUDED 
#define config_c_INCLUDED

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

#include "config.h"
#include "fizmo.h"
#include "types.h"
#include "splint.h"
#include "math.h"
#include "i18n.h"

int system_charset = SYSTEM_CHARSET_ASCII;
bool auto_adapt_upper_window = true;
bool auto_open_upper_window = true;
bool skip_active_routines_stack_check_warning = false;
char false_value[] = "false";


struct configuration_option
{
  char *name;
  char *value;
};


struct configuration_option configuration_options[] = {
  { "locale", NULL },
  { "system-charset", NULL },
  { "random-mode", NULL },
  { "start-script-when-story-starts", NULL },
  { "start-command-recording-when-story-starts", NULL },
  { "start-file-input-when-story-starts", NULL },
  { "auto-open-upper-window", NULL },
  { "auto-adapt-upper-window", NULL },
  { "skip-active-routines-stack-check-warning", NULL },
  { "save-and-quit-file-before-read", NULL },
  { "restore-after-save-and-quit-file-before-read", NULL }, // bool-string
  { "disable-save", NULL }, // bool-string
  { "disable-restore", NULL }, // bool-string
  { "disable-external-streams", NULL },
  { "disable-sound", NULL },
  { "force-quetzal-umem", NULL }, // bool-string
  { "force-8bit-sound", NULL }, // bool-string
  { "enable-font3-conversion", NULL }, // bool-string, convert font3 to unicode
  { "set-tandy-bit", NULL }, //bool
  { "z-code-path", NULL },
  { "savegame-path", NULL },
  { "transcript-filename", NULL },
  { "command-filename", NULL },
  { NULL, NULL }
};


int set_configuration_value(char *key, char* new_value, ...)
{
  int i, j;
  va_list ap;
  char *ptr;

  if (key == NULL)
    return -1;

  i = 0;

  while (configuration_options[i].name != NULL)
  {
    if (strcmp(configuration_options[i].name, key) == 0)
    {
      if (strcmp(key, "random-mode") == 0)
      {
        if (new_value == NULL)
          return -1;
        else if (strcmp(new_value, "random") == 0)
        {
          if (configuration_options[i].value != NULL)
            free(configuration_options[i].value);
          configuration_options[i].value = fizmo_strdup("random");
        }
        else if (strcmp(new_value, "predictable") == 0)
        {
          if (configuration_options[i].value != NULL)
            free(configuration_options[i].value);
          configuration_options[i].value = fizmo_strdup("predictable");
        }
        else if (strcmp(new_value, "force-predictable") == 0)
        {
          if (configuration_options[i].value != NULL)
            free(configuration_options[i].value);
          configuration_options[i].value = fizmo_strdup("force-predictable");
        }
        else
          return -1;

        seed_random_generator();
        return 0;
      }
      else if (strcmp(key, "system-charset") == 0)
      {
        if (new_value == NULL)
          return -1;
        else if (
            (strcmp(new_value, "utf-8") == 0)
            ||
            (strcmp(new_value, "latin-1") == 0)
            )
        {
          ptr = fizmo_strdup(new_value);
          if (configuration_options[i].value != NULL)
            free(configuration_options[i].value);
          configuration_options[i].value = ptr;
          return 0;
        }
        else
          return -1;
      }
      else if (strcmp(key, "locale") == 0)
      {
        // module-name as first "..." parameter required.
        if (new_value == NULL)
          return -1;
        else
        {
          va_start(ap, new_value);
          ptr = va_arg(ap, char*);
          va_end(ap);

          if (ptr == NULL)
            return -1;

          for (j=0; j<NUMBER_OF_LOCALES; j++)
            if (
                (strcmp(locales[j].language_code, new_value) == 0)
                &&
                (strcmp(locales[j].module_name, ptr) == 0)
               )
            {
              active_locale = &(locales[j]);

              if (strcmp(ptr, "fizmo") == 0)
              {
                ptr = fizmo_strdup(new_value);
                if (configuration_options[i].value != NULL)
                  free(configuration_options[i].value);
                configuration_options[i].value = ptr;
              }

              return 0;
            }

          return -1;
        }
      }
      // Options for values are copied
      else if (
          (strcmp(key, "save-and-quit-file-before-read") == 0)
          ||
          (strcmp(key, "z-code-path") == 0)
          ||
          (strcmp(key, "savegame-path") == 0)
          ||
          (strcmp(key, "transcript-filename") == 0)
          ||
          (strcmp(key, "command-filename") == 0)
          )
      {
        ptr = fizmo_strdup(new_value);
        if (configuration_options[i].value != NULL)
          free(configuration_options[i].value);
        configuration_options[i].value = ptr;
        return 0;
      }
      // Boolean options
      else if (
          (strcmp(key, "disable-save") == 0)
          ||
          (strcmp(key, "disable-restore") == 0)
          ||
          (strcmp(key, "force-quetzal-umem") == 0)
          ||
          (strcmp(key, "start-script-when-story-starts") == 0)
          ||
          (strcmp(key, "start-command-recording-when-story-starts") == 0)
          ||
          (strcmp(key, "start-file-input-when-story-starts") == 0)
          ||
          (strcmp(key, "disable-external-streams") == 0)
          ||
          (strcmp(key, "restore-after-save-and-quit-file-before-read") == 0)
          ||
          (strcmp(key, "force-8bit-sound") == 0)
          ||
          (strcmp(key, "disable-sound") == 0)
          ||
          (strcmp(key, "enable-font3-conversion") == 0)
          ||
          (strcmp(key, "set-tandy-bit") == 0)
          )
      {
        if (new_value == NULL)
          return -1;

        if (
            (strcmp(new_value, "true") != 0)
            &&
            (strcmp(new_value, "false") != 0)
           )
          return -1;

        ptr = fizmo_strdup(new_value);
        if (configuration_options[i].value != NULL)
          free(configuration_options[i].value);
        configuration_options[i].value = ptr;
        return 0;
      }
      else
      {
        i18n_translate_and_exit(
            i18n_fizmo_UNKNOWN_CONFIGURATION_OPTION_P0S,
            -0x0101,
            key);
      } 
    }

    i++;
  }

  return -1;
}


char *get_configuration_value(char *key)
{
  int i = 0;

  if (key == NULL)
    return NULL;

  while (configuration_options[i].name != NULL)
  {
    if (strcmp(configuration_options[i].name, key) == 0)
    {
      if (
          (
           (strcmp(key, "disable-save") == 0)
           ||
           (strcmp(key, "disable-restore") == 0)
           ||
           (strcmp(key, "force-quetzal-umem") == 0)
           ||
           (strcmp(key, "start-script-when-story-starts") == 0)
           ||
           (strcmp(key, "start-command-recording-when-story-starts") == 0)
           ||
           (strcmp(key, "start-file-input-when-story-starts") == 0)
           ||
           (strcmp(key, "disable-external-streams") == 0)
           ||
           (strcmp(key, "restore-after-save-and-quit-file-before-read") == 0)
           ||
           (strcmp(key, "force-8bit-sound") == 0)
           ||
           (strcmp(key, "disable-sound") == 0)
           ||
           (strcmp(key, "enable-font3-conversion") == 0)
           ||
           (strcmp(key, "set-tandy-bit") == 0)
          )
          &&
          (configuration_options[i].value == NULL)
         )
        return false_value;
      else
        return configuration_options[i].value;
    }

    i++;
  }

  return NULL;
}


char **get_valid_configuration_options(char *key, ...)
{
  char **result;
  int result_index;
  size_t memory_size;
  va_list ap;
  char *ptr;
  int i;

  if (strcmp(key, "locale") == 0)
  {
    va_start(ap, key);
    ptr = va_arg(ap, char*);
    va_end(ap);

    if (ptr == NULL)
      return NULL;

    result_index = 0;
    for (i=0; i<NUMBER_OF_LOCALES; i++)
      if (strcmp(locales[i].module_name, "fizmo") == 0)
        result_index++;

    memory_size = (result_index + 1) * sizeof(char*);

    result = (char**)fizmo_malloc(memory_size);

    result_index = 0;
    for (i=0; i<NUMBER_OF_LOCALES; i++)
      if (strcmp(locales[i].module_name, "fizmo") == 0)
        result[result_index++] = fizmo_strdup(locales[i].language_code);

    result[result_index] = NULL;

    return result;
  }
  else
    return NULL;
}


#endif /* config_c_INCLUDED */

