/* Copyright 2022-2026 Kurt Nienhaus
 *
 * This file is part of VgaGames.
 * VgaGames 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.
 * VgaGames 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 VgaGames.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "dialog.h"

void init_dialog_volume(void);

static VG_BOOL dialog_volume(const char *, const struct VG_Position *, struct VG_Hash *);


/* set functions */
void
init_dialog_volume(void)
{
  vg4->dialog->volume = dialog_volume;
} /* Ende init_dialog_volume */


/* dialog_volume:
 * open a canvas-dialog for setting volumes
 * @param cvasdir     directory to load canvas from, or NULL = system-canvas
 * @param posdst      canvas-position on window, or NULL = centered
 * @param hvar        hash with variable-values for text control-commands "var", or NULL
 *                      hash-format:
 *                       - key:   variable name
 *                       - value: variable value
 *                    (see below)
 * @return  VG_TRUE = OK or VG_FALSE = exit-request
 *
 * The canvas-name must be:
 *  - volume.top.cvas: for setting volumes
 *    - with items:
 *      - [CV-TEXT]   with name "title": text for title
 *      - [CV-SWITCH] with name "mute": for setting to mute/unmute
 *      - [CV-BAR]    with name "bar-main": for setting main volume
 *      - [CV-BAR]    with name "bar-sound": for setting sound volume
 *      - [CV-BAR]    with name "bar-music": for setting music volume
 *      - [CV-BAR]    with name "bar-speech": for setting speech volume
 *      - [CV-BUTTON] with name "apply": for applying changes
 *      - [CV-BUTTON] as a cancel-button
 *    - uses following variables:
 *      - key: "title", value: <title of canvas>
 *    - hvar should contain:
 *      - key: "top:title", value: <title of canvas>
 */
static VG_BOOL
dialog_volume(const char *cvasdir, const struct VG_Position *posdst, struct VG_Hash *hvar)
{
  const char *cvprefix = "volume";
  const char *cvfile_top = "volume.top.cvas";
  const char *cvname_mute = "mute";
  const char *cvname_bar_main = "bar-main";
  const char *cvname_bar_sound = "bar-sound";
  const char *cvname_bar_music = "bar-music";
  const char *cvname_bar_speech = "bar-speech";
  const char *cvname_apply = "apply";
  struct VG_Hash *hvar_top;
  char cvaspath[512];
  VG_BOOL retw, ismute;
  struct VG_Canvas *cvas_top;
  const char *selname;
  int vol_main, vol_sound, vol_music, vol_speech, imod;

  if (!vg4->audio->is_open()) { return VG_TRUE; }

  hvar_top = NULL;

  /* get volumes */
  ismute = vg4->audio->is_mute();
  vol_main = vg4->audio->volume(VG_AUDIO_VOLUME_ALL, -1);
  imod = vol_main * 1000 / 255 % 10;
  vol_main = vol_main * 100 / 255 + imod / 5;
  vol_sound = vg4->audio->volume(VG_AUDIO_VOLUME_SOUND, -1);
  imod = vol_sound * 1000 / 255 % 10;
  vol_sound = vol_sound * 100 / 255 + imod / 5;
  vol_music = vg4->audio->volume(VG_AUDIO_VOLUME_MUSIC, -1);
  imod = vol_music * 1000 / 255 % 10;
  vol_music = vol_music * 100 / 255 + imod / 5;
  vol_speech = vg4->audio->volume(VG_AUDIO_VOLUME_SPEECH, -1);
  imod = vol_speech * 1000 / 255 % 10;
  vol_speech = vol_speech * 100 / 255 + imod / 5;

  /* set variables and load canvas */

  /* top-canvas */
  hvar_top = vg4->hash->create();
  dialog_transfer_variables(hvar, hvar_top, "top");
  dialog_cvasfile(cvprefix, cvfile_top, cvasdir, cvaspath, sizeof(cvaspath));
  cvas_top = vg4->canvas->load(cvaspath, hvar_top);
  if (cvas_top == NULL) {
    outerr("%s [at cvasdir=%s] not found", cvfile_top, (cvasdir == NULL ? "(null)" : cvasdir));
    return VG_TRUE;
  }
  vg4->canvas->switch_set(cvas_top, cvname_mute, ismute);
  vg4->canvas->bar_set_percent(cvas_top, cvname_bar_main, vol_main);
  vg4->canvas->bar_set_percent(cvas_top, cvname_bar_sound, vol_sound);
  vg4->canvas->bar_set_percent(cvas_top, cvname_bar_music, vol_music);
  vg4->canvas->bar_set_percent(cvas_top, cvname_bar_speech, vol_speech);


  /* loop */

  retw = VG_TRUE;
  for (;;) {
    /* execute top-canvas */
    if (!vg4->canvas->exec(cvas_top, posdst, &selname)) { retw = VG_FALSE; break; }
    if (selname == NULL) { break; }  /* cancel */

    /* act according to selection */
    if (strcmp(selname, cvname_apply) == 0) {
      ismute = vg4->canvas->switch_get(cvas_top, cvname_mute);
      vg4->audio->mute(ismute);
      vol_main = vg4->canvas->bar_get_percent(cvas_top, cvname_bar_main);
      vg4->audio->volume(VG_AUDIO_VOLUME_ALL, vol_main * 255 / 100);
      vol_sound = vg4->canvas->bar_get_percent(cvas_top, cvname_bar_sound);
      vg4->audio->volume(VG_AUDIO_VOLUME_SOUND, vol_sound * 255 / 100);
      vol_music = vg4->canvas->bar_get_percent(cvas_top, cvname_bar_music);
      vg4->audio->volume(VG_AUDIO_VOLUME_MUSIC, vol_music * 255 / 100);
      vol_speech = vg4->canvas->bar_get_percent(cvas_top, cvname_bar_speech);
      vg4->audio->volume(VG_AUDIO_VOLUME_SPEECH, vol_speech * 255 / 100);
      break;
    }
  }

  vg4->canvas->destroy(cvas_top);
  if (hvar_top != NULL) { vg4->hash->destroy(hvar_top); }

  return retw;
} /* Ende dialog_volume */
