#include "config.h"

#include <string.h>

/* Persist keys. BirthData's latitude/longitude/utc_offset_hours are
 * doubles, but Pebble's persist API has no float storage - stored as
 * scaled int32s instead (microdegrees / minutes), matching how
 * AppMessage carries the same fields from the config page - see
 * app_message.c. */
enum {
  PKEY_CONFIGURED = 0,
  PKEY_BIRTH_YEAR,
  PKEY_BIRTH_MONTH,
  PKEY_BIRTH_DAY,
  PKEY_BIRTH_HOUR,
  PKEY_BIRTH_MINUTE,
  PKEY_BIRTH_UTC_OFFSET_MINUTES,
  PKEY_BIRTH_LAT_MICRODEG,
  PKEY_BIRTH_LON_MICRODEG,
  PKEY_GENDER,
  PKEY_LANG,
  PKEY_NOTIFY_ENABLED,
  PKEY_NOTIFY_HOUR,
  PKEY_NOTIFY_MINUTE,
};

void config_load(WatchConfig *out) {
  memset(out, 0, sizeof *out);

  out->configured = persist_exists(PKEY_CONFIGURED) && persist_read_bool(PKEY_CONFIGURED);
  if (!out->configured) {
    strcpy(out->lang, "en");
    return;
  }

  out->birth.year = (int)persist_read_int(PKEY_BIRTH_YEAR);
  out->birth.month = (int)persist_read_int(PKEY_BIRTH_MONTH);
  out->birth.day = (int)persist_read_int(PKEY_BIRTH_DAY);
  out->birth.hour = (int)persist_read_int(PKEY_BIRTH_HOUR);
  out->birth.minute = (int)persist_read_int(PKEY_BIRTH_MINUTE);
  out->birth.utc_offset_hours = (double)(int32_t)persist_read_int(PKEY_BIRTH_UTC_OFFSET_MINUTES) / 60.0;
  out->birth.latitude = (double)(int32_t)persist_read_int(PKEY_BIRTH_LAT_MICRODEG) / 1000000.0;
  out->birth.longitude = (double)(int32_t)persist_read_int(PKEY_BIRTH_LON_MICRODEG) / 1000000.0;
  out->gender = (Gender)persist_read_int(PKEY_GENDER); /* defaults to 0 = GENDER_UNSPECIFIED */

  if (persist_read_string(PKEY_LANG, out->lang, sizeof out->lang) <= 0) {
    strcpy(out->lang, "en");
  }

  out->notify_enabled = persist_read_bool(PKEY_NOTIFY_ENABLED);
  out->notify_hour = (int)persist_read_int(PKEY_NOTIFY_HOUR);
  out->notify_minute = (int)persist_read_int(PKEY_NOTIFY_MINUTE);
}

void config_save(const WatchConfig *cfg) {
  persist_write_bool(PKEY_CONFIGURED, cfg->configured);

  persist_write_int(PKEY_BIRTH_YEAR, cfg->birth.year);
  persist_write_int(PKEY_BIRTH_MONTH, cfg->birth.month);
  persist_write_int(PKEY_BIRTH_DAY, cfg->birth.day);
  persist_write_int(PKEY_BIRTH_HOUR, cfg->birth.hour);
  persist_write_int(PKEY_BIRTH_MINUTE, cfg->birth.minute);
  persist_write_int(PKEY_BIRTH_UTC_OFFSET_MINUTES, (int32_t)(cfg->birth.utc_offset_hours * 60.0));
  persist_write_int(PKEY_BIRTH_LAT_MICRODEG, (int32_t)(cfg->birth.latitude * 1000000.0));
  persist_write_int(PKEY_BIRTH_LON_MICRODEG, (int32_t)(cfg->birth.longitude * 1000000.0));
  persist_write_int(PKEY_GENDER, (int32_t)cfg->gender);

  persist_write_string(PKEY_LANG, cfg->lang);

  persist_write_bool(PKEY_NOTIFY_ENABLED, cfg->notify_enabled);
  persist_write_int(PKEY_NOTIFY_HOUR, cfg->notify_hour);
  persist_write_int(PKEY_NOTIFY_MINUTE, cfg->notify_minute);
}

/* Cast to int/long rather than %f - Pebble's APP_LOG doesn't support
 * floating-point format specifiers. */
void config_log(const WatchConfig *cfg) {
  if (!cfg->configured) {
    APP_LOG(APP_LOG_LEVEL_INFO, "config: not configured yet");
    return;
  }
  APP_LOG(APP_LOG_LEVEL_INFO, "config: birth %04d-%02d-%02d %02d:%02d UTC offset %dmin",
          cfg->birth.year, cfg->birth.month, cfg->birth.day, cfg->birth.hour, cfg->birth.minute,
          (int)(cfg->birth.utc_offset_hours * 60));
  APP_LOG(APP_LOG_LEVEL_INFO, "config: lat=%ld/1e6 lon=%ld/1e6 gender=%d lang=%s",
          (long)(cfg->birth.latitude * 1000000), (long)(cfg->birth.longitude * 1000000),
          (int)cfg->gender, cfg->lang);
  APP_LOG(APP_LOG_LEVEL_INFO, "config: notify_enabled=%d at %02d:%02d",
          cfg->notify_enabled, cfg->notify_hour, cfg->notify_minute);
}
