/*
 *   regpref.c
 *   Copyright (C) 2024 David García Goñi <dagargo@gmail.com>
 *
 *   This file is part of Elektroid.
 *
 *   Elektroid 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 3 of the License, or
 *   (at your option) any later version.
 *
 *   Elektroid 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.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Elektroid. If not, see <http://www.gnu.org/licenses/>.
 */

#include "regpref.h"

#define PREF_DEFAULT_SUBDIVISIONS 4
#define PREF_MAX_SUBDIVISIONS 8
#define PREF_MIN_SUBDIVISIONS 1

#define PREF_DEFAULT_AUDIO_BUF_LENGTH 1024
#define PREF_MAX_AUDIO_BUF_LENGTH 4096
#define PREF_MIN_AUDIO_BUF_LENGTH 256

// This uses the same separator as the IKEY in the LIST INFO chunk (IKEY_TOKEN_SEPARATOR).
// Alphabetically sorted in the tags window but listed as such in the tags tab of the preferences window.
#define PREF_DEFAULT_TAGS_STRUCTURES  "fill; loop; one-shot; phrase"
#define PREF_DEFAULT_TAGS_INSTRUMENTS "bass; brass; clap; cymbal; drums; FX; guitar; hi-hat; keys; kick; mallets; noise; object; organ; pad; percussion; piano; snare; strings; texture; tom; voice/choir; woodwind"
#define PREF_DEFAULT_TAGS_GENRES      "ambient; blues; breakbeat; chill-out; chiptune; country; drum; and; bass; electro; folk; folk,; caribbean; hip-hop; jazz; jungle; metal; punk; R&B/soul; reggae; rock; techno; trance"
#define PREF_DEFAULT_TAGS_OBJECTIVE   "acoustic; ambient; chromatic; distorted; electronic; glitchy; industrial; lo-fi; natural; noisy; percussive"
#define PREF_DEFAULT_TAGS_SUBJECTIVE  "bright; dark; peaceful; ominous; ethereal; massive"

static gpointer
regpref_get_subdivisions (const gpointer grid)
{
  return preferences_get_int_value (grid, PREF_MAX_SUBDIVISIONS,
				    PREF_MIN_SUBDIVISIONS,
				    PREF_DEFAULT_SUBDIVISIONS);
}

static gpointer
regpref_get_audio_buffer_length (const gpointer len)
{
  gpointer p = preferences_get_int_value (len, PREF_MAX_AUDIO_BUF_LENGTH,
					  PREF_MIN_AUDIO_BUF_LENGTH,
					  PREF_DEFAULT_AUDIO_BUF_LENGTH);
  gint v = *(gint *) p;
  if (v > 256 && v < 512)
    {
      v = 256;
    }
  else if (v > 512 && v < 1024)
    {
      v = 512;
    }
  else if (v > 1024 && v < 2048)
    {
      v = 1024;
    }
  else if (v > 2048 && v < 4096)
    {
      v = 2048;
    }

  *(gint *) p = v;

  return p;
}

static gpointer
regpref_get_home (const gpointer home)
{
  return home ? g_strdup (home) : get_user_dir (NULL);
}

static gpointer
regpref_get_tags_structures (const gpointer tags)
{
  return preferences_get_string_value_default (tags,
					       PREF_DEFAULT_TAGS_STRUCTURES);
}

static gpointer
regpref_get_tags_instruments (const gpointer tags)
{
  return preferences_get_string_value_default (tags,
					       PREF_DEFAULT_TAGS_INSTRUMENTS);
}

static gpointer
regpref_get_tags_genres (const gpointer tags)
{
  return preferences_get_string_value_default (tags,
					       PREF_DEFAULT_TAGS_GENRES);
}

static gpointer
regpref_get_tags_objective (const gpointer tags)
{
  return preferences_get_string_value_default (tags,
					       PREF_DEFAULT_TAGS_OBJECTIVE);
}

static gpointer
regpref_get_tags_subjective (const gpointer tags)
{
  return preferences_get_string_value_default (tags,
					       PREF_DEFAULT_TAGS_SUBJECTIVE);
}

static const struct preference PREF_LOCAL_DIR = {
  .key = PREF_KEY_LOCAL_DIR,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_home
};

static const struct preference PREF_REMOTE_DIR = {
  .key = PREF_KEY_REMOTE_DIR,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_home
};

const struct preference PREF_SHOW_REMOTE = {
  .key = PREF_KEY_SHOW_REMOTE,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

static const struct preference PREF_AUTOPLAY = {
  .key = PREF_KEY_AUTOPLAY,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

static const struct preference PREF_MIX = {
  .key = PREF_KEY_MIX,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_false
};

static const struct preference PREF_SUBDIVISIONS = {
  .key = PREF_KEY_SUBDIVISIONS,
  .type = PREFERENCE_TYPE_INT,
  .get_value = regpref_get_subdivisions
};

static const struct preference PREF_PLAY_WHILE_LOADING = {
  .key = PREF_KEY_PLAY_WHILE_LOADING,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

static const struct preference PREF_AUDIO_BUFFER_LEN = {
  .key = PREF_KEY_AUDIO_BUFFER_LEN,
  .type = PREFERENCE_TYPE_INT,
  .get_value = regpref_get_audio_buffer_length
};

static const struct preference PREF_AUDIO_USE_FLOAT = {
  .key = PREF_KEY_AUDIO_USE_FLOAT,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

static const struct preference PREF_SHOW_PLAYBACK_CURSOR = {
  .key = PREF_KEY_SHOW_PLAYBACK_CURSOR,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

const struct preference PREF_STOP_DEVICE_WHEN_CONNECTING = {
  .key = PREF_KEY_STOP_DEVICE_WHEN_CONNECTING,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

const struct preference PREF_ELEKTRON_LOAD_SOUND_TAGS = {
  .key = PREF_KEY_ELEKTRON_LOAD_SOUND_TAGS,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

static const struct preference PREF_TAGS_STRUCTURES = {
  .key = PREF_KEY_TAGS_STRUCTURES,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_tags_structures
};

static const struct preference PREF_TAGS_INSTRUMENTS = {
  .key = PREF_KEY_TAGS_INSTRUMENTS,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_tags_instruments
};

static const struct preference PREF_TAGS_GENRES = {
  .key = PREF_KEY_TAGS_GENRES,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_tags_genres
};

const struct preference PREF_TAGS_OBJECTIVE_CHARS = {
  .key = PREF_KEY_TAGS_OBJECTIVE_CHARS,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_tags_objective
};

const struct preference PREF_TAGS_SUBJECTIVE_CHARS = {
  .key = PREF_KEY_TAGS_SUBJECTIVE_CHARS,
  .type = PREFERENCE_TYPE_STRING,
  .get_value = regpref_get_tags_subjective
};

static const struct preference PREF_SHOW_FOLDER_SIZES = {
  .key = PREF_KEY_SHOW_FOLDER_SIZES,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_false
};

static const struct preference PREF_USE_SAFETY_QUESTIONS = {
  .key = PREF_KEY_USE_SAFETY_QUESTIONS,
  .type = PREFERENCE_TYPE_BOOLEAN,
  .get_value = preferences_get_boolean_value_true
};

void
regpref_register ()
{
  gslist_fill (&preferences, &PREF_LOCAL_DIR, &PREF_REMOTE_DIR,
	       &PREF_SHOW_REMOTE, &PREF_AUTOPLAY, &PREF_MIX,
	       &PREF_SUBDIVISIONS, &PREF_PLAY_WHILE_LOADING,
	       &PREF_AUDIO_BUFFER_LEN, &PREF_AUDIO_USE_FLOAT,
	       &PREF_SHOW_PLAYBACK_CURSOR, &PREF_STOP_DEVICE_WHEN_CONNECTING,
	       &PREF_ELEKTRON_LOAD_SOUND_TAGS, &PREF_TAGS_STRUCTURES,
	       &PREF_TAGS_INSTRUMENTS, &PREF_TAGS_GENRES,
	       &PREF_TAGS_OBJECTIVE_CHARS, &PREF_TAGS_SUBJECTIVE_CHARS,
	       &PREF_SHOW_FOLDER_SIZES, &PREF_USE_SAFETY_QUESTIONS, NULL);
}

void
regpref_unregister ()
{
  g_slist_free (g_steal_pointer (&preferences));
}
