/*
 * saves/loads the application's preferences.
 *
 * This file is part of OpenKropki.
 *
 * Copyright (C) 2014-2020 Mateusz Viste
 *
 * MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>    /* free(), atoi() */
#include <string.h>    /* strcpy(), strlen()... */
#include <SDL2/SDL.h>

#include "prefs.h"

/* load full path to configuration or preference file f, result must be freed */
static char *getfname(const char *f) {
  char *ppath;
  char *tmppath;
  ppath = SDL_GetPrefPath("Mateusz Viste", "OpenKropki"); /* SDL_GetPrefPath() is supposed to create the directory if it does not exist - returns NULL if fails to */
  if (ppath == NULL) return(NULL);
  tmppath = malloc(strlen(f) + strlen(ppath) + 1);
  strcpy(tmppath, ppath);
  strcat(tmppath, f);
  SDL_free(ppath);
  return(tmppath);
}


char *prefs_load(const char *setting) {
  char *fname = NULL;
  FILE *fd = NULL;
  char *okps = NULL;
  size_t okps_sz = 0;
  size_t okps_len = 0;
  fname = getfname(setting);
  if (fname == NULL) goto FREE_AND_QUIT;
  fd = fopen(fname, "rb");
  if (fd == NULL) goto FREE_AND_QUIT;
  /* read until EOF or 1 GB limit */
  for (;;) {
    int c = getc(fd);
    if (c == EOF) {
      break;
    } else if (okps_len > 1024 * 1024 * 1024) {
      okps_len = 0;
      free(okps);
      okps = NULL;
      goto FREE_AND_QUIT;
    }
    /* realloc string if needed */
    if (okps_len + 16 > okps_sz) {
      okps_sz *= 2;
      if (okps_sz == 0) okps_sz = 64;
      okps = realloc(okps, okps_sz);
    }
    okps[okps_len++] = c;
  }
  /* */
  FREE_AND_QUIT:
  free(fname);
  if (fd != NULL) fclose(fd);
  if (okps != NULL) okps[okps_len] = 0;
  return(okps);
}


int prefs_loadint(const char *setting, int defaultvalue) {
  int res;
  char *s = prefs_load(setting);
  if (s == NULL) return(defaultvalue);
  res = atoi(s);
  free(s);
  return(res);
}


void prefs_save(const char *setting, const char *str) {
  char *fname = NULL;
  FILE *fd = NULL;
  fname = getfname(setting);
  if (fname == NULL) goto FREE_AND_QUIT;
  fd = fopen(fname, "wb");
  if (fd == NULL) goto FREE_AND_QUIT;
  /* */
  fputs(str, fd);
  /* */
  FREE_AND_QUIT:
  free(fname);
  if (fd != NULL) fclose(fd);
}


void prefs_saveint(const char *setting, int val) {
  char strv[64];
  snprintf(strv, sizeof(strv), "%d", val);
  prefs_save(setting, strv);
}
