/* 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_wdsize(void);

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


/* set functions */
void
init_dialog_wdsize(void)
{
  vg4->dialog->windowsize = dialog_windowsize;
} /* Ende init_dialog_wdsize */


/* dialog_windowsize:
 * open a canvas-dialog for resizing the window and scaling-configuration
 * @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:
 *  - windowsize.top.cvas: for resize the window and scaling-configuration
 *    - with items:
 *      - [CV-TEXT]   with name "title": text for title
 *      - [CV-BUTTON] with name "done": for returning
 *      - [CV-BUTTON] with name "resize-none": for resizing to VG_WINDOW_SCALE_NONE
 *      - [CV-BUTTON] with name "resize-best": for resizing to VG_WINDOW_SCALE_BEST
 *      - [CV-BUTTON] with name "resize-max": for resizing to VG_WINDOW_SCALE_MAX
 *      - [CV-BUTTON] with name "resize-full": for resizing to VG_WINDOW_SCALE_FULL
 *      - [CV-SWITCH] with name "scale-nearest": set image-scaling: on=nearest, off=linear
 *      - [CV-SWITCH] with name "scale-integer": set window-scaling: on=integer, off=float
 *    - uses following variables:
 *      - key: "title", value: <title of canvas>
 *    - hvar should contain:
 *      - key: "top:title", value: <title of canvas>
 */
static VG_BOOL
dialog_windowsize(const char *cvasdir, const struct VG_Position *posdst, struct VG_Hash *hvar)
{
  const char *cvprefix = "windowsize";
  const char *cvfile_top = "windowsize.top.cvas";
  const char *cvname_done = "done";
  const char *cvname_resize_none = "resize-none";
  const char *cvname_resize_best = "resize-best";
  const char *cvname_resize_max = "resize-max";
  const char *cvname_resize_full = "resize-full";
  const char *cvname_scale_nearest = "scale-nearest";
  const char *cvname_scale_integer = "scale-integer";
  struct VG_Hash *hvar_top;
  char cvaspath[512];
  VG_BOOL retw, scale_nearest, scale_integer;
  struct VG_Canvas *cvas_top;
  const char *selname;
  int wscale;

  hvar_top = NULL;

  /* 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;
  }

  /* set parameters */
  vg4->window->getparameters(NULL, &wscale);
  vg4->window->scale_params(VG_FALSE, &scale_nearest, &scale_integer);
  vg4->canvas->switch_set(cvas_top, cvname_scale_nearest, scale_nearest);
  vg4->canvas->switch_set(cvas_top, cvname_scale_integer, scale_integer);

  /* 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 (*selname == '\0' || strcmp(selname, cvname_done) == 0) { break; }
    if (strcmp(selname, cvname_resize_none) == 0) {
      if (wscale != VG_WINDOW_SCALE_NONE) {
        if (!vg4->window->reopen(-1, VG_WINDOW_SCALE_NONE)) { retw = VG_FALSE; break; }
        vg4->window->getparameters(NULL, &wscale);
      }
    } else if (strcmp(selname, cvname_resize_best) == 0) {
      if (wscale != VG_WINDOW_SCALE_BEST) {
        if (!vg4->window->reopen(-1, VG_WINDOW_SCALE_BEST)) { retw = VG_FALSE; break; }
        vg4->window->getparameters(NULL, &wscale);
      }
    } else if (strcmp(selname, cvname_resize_max) == 0) {
      if (wscale != VG_WINDOW_SCALE_MAX) {
        if (!vg4->window->reopen(-1, VG_WINDOW_SCALE_MAX)) { retw = VG_FALSE; break; }
        vg4->window->getparameters(NULL, &wscale);
      }
    } else if (strcmp(selname, cvname_resize_full) == 0) {
      if (wscale != VG_WINDOW_SCALE_FULL) {
        if (!vg4->window->reopen(-1, VG_WINDOW_SCALE_FULL)) { retw = VG_FALSE; break; }
        vg4->window->getparameters(NULL, &wscale);
      }
    } else if (strcmp(selname, cvname_scale_nearest) == 0) {
      VG_BOOL scale_nearest;
      vg4->window->scale_params(VG_FALSE, &scale_nearest, NULL);
      scale_nearest = !scale_nearest;
      vg4->window->scale_params(VG_TRUE, &scale_nearest, NULL);
      if (!vg4->window->reopen(-1, wscale)) { retw = VG_FALSE; break; }
    } else if (strcmp(selname, cvname_scale_integer) == 0) {
      VG_BOOL scale_integer;
      vg4->window->scale_params(VG_FALSE, NULL, &scale_integer);
      scale_integer = !scale_integer;
      vg4->window->scale_params(VG_TRUE, NULL, &scale_integer);
      if (!vg4->window->reopen(-1, wscale)) { retw = VG_FALSE; break; }
    }
  }

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

  return retw;
} /* Ende dialog_windowsize */
