#include <libintl.h>
#include <math.h>
#include "defaults.h"
#include "string.h"

/* Last updated 2024.10.25 */

const char *window_widths[NUM_WINDOW_WIDTHS] = {
  "640",
  "768",
  "800",
  "854",
  "1024",
  "1280",
  "1400",
  "1600",
  "1680",
  "1920",
  "2048",
  "2560"
};

const char *window_heights[NUM_WINDOW_HEIGHTS] = {
  "480",
  "576",
  "600",
  "720",
  "768",
  "800",
  "960",
  "1024",
  "1050",
  "1080",
  "1200",
  "1536",
  "1600",
  "2048"
};


/* Activate the "Apply" and "Reset" buttons
   (after something has changed, so the user knows
   there is something to either change, or reset back
   to what it was before, be it the default or something
   loaded from a config file */
void activate_buttons()
{
  BUTTON_apply->activate();
  BUTTON_reset->activate();
}

bool status_chng = 0;

void set_change_status(int status)
{
  status_chng = status;
  if (status_chng == 0)
  {
    BUTTON_apply->deactivate();
    BUTTON_reset->deactivate();
  }
  else
  {
    BUTTON_apply->activate();
    BUTTON_reset->activate();
  }
}

void cb_SLIDER_buttonsize(Fl_Slider *, void *)
{
  bool auto_chkbox;
  double val;
  char str[128];

  auto_chkbox = CHECKBUTTON_buttonsizeauto->value();

  if (!auto_chkbox)
  {
    val = floor(SLIDER_buttonsize->value());
    SLIDER_buttonsize->value(val);

    if (val == 48)
      snprintf(str, sizeof(str), BTN_SIZE_DEFAULT);
    else
      snprintf(str, sizeof(str),        /* Button size option: do overrdide */
               gettext("Button size: %dx%d"), (int) val, (int) val);

    SLIDER_buttonsize->label(strdup(str));
    SLIDER_buttonsize->parent()->redraw();
    SLIDER_buttonsize->activate();
  }
  else
  {
    SLIDER_buttonsize->deactivate();
  }

  update_canvas_size();
  set_change_status(1);
}

void cb_SLIDER_colorsrows(Fl_Slider *, void *)
{
  double val;
  char str[128];

  val = floor(SLIDER_colorsrows->value());
  SLIDER_colorsrows->value(val);

  if (val == 1)
    snprintf(str, sizeof(str), COLOR_SIZE_DEFAULT);
  else
    snprintf(str, sizeof(str),  /* Color palette size option: do override */
             gettext("Color palette rows: %d"), (int) val);

  SLIDER_colorsrows->label(strdup(str));
  SLIDER_colorsrows->parent()->redraw();

  update_canvas_size();
  set_change_status(1);
}

void cb_SLIDER_stampsize(Fl_Slider *, void *)
{
  double val;
  char str[128];

  val = floor(SLIDER_stampsize->value());
  SLIDER_stampsize->value(val);

  if (val == -1)
    snprintf(str, sizeof(str), STAMP_SIZE_DEFAULT);
  else if (val >= 0 && val <= 4)
    snprintf(str, sizeof(str),
             /* Stamp size option: override with a small size */
             gettext("Override: Small (%d)"), (int) val);
  else if (val >= 4 && val < 8)
    snprintf(str, sizeof(str),
             /* Stamp size option: override with a medium size */
             gettext("Override: Medium (%d)"), (int) val);
  else if (val >= 8)
    snprintf(str, sizeof(str),
             /* Stamp size option: override with a large size */
             gettext("Override: Large (%d)"), (int) val);

  SLIDER_stampsize->label(strdup(str));
  SLIDER_stampsize->parent()->redraw();

  set_change_status(1);
}


/* Set defaults on Video/Sound tab */
void DEF_videoandsound()
{
  int diff = 0;

  // Video Defaults

  diff += CHECKBUTTON_fullscreen->value(0);
  diff += CHECKBUTTON_native->value(0);
  diff += CHOICE_windowwidth->value(DEF_WINDOW_WIDTH);
  diff += CHOICE_windowheight->value(DEF_WINDOW_HEIGHT);
  diff += CHECKBUTTON_rotate->value(0);
  diff += CHECKBUTTON_screensaver->value(0);

  // Sound Defaults

  diff += CHECKBUTTON_soundeffects->value(1);
  diff += CHECKBUTTON_stereo->value(1);

  // Interface Size Defaults

  diff += SLIDER_buttonsize->value(48);
  diff += CHECKBUTTON_buttonsizeauto->value(0);
  cb_SLIDER_buttonsize(SLIDER_buttonsize, NULL);
  diff += SLIDER_colorsrows->value(1);

  if (diff)
    activate_buttons();
}

/* Whether "Fullscreen" is checked */
bool CHKBUT_fulls_isdef()
{
  if (CHECKBUTTON_fullscreen->value() == 0)
    return 1;
  else
    return 0;
}

/* Set defaults on Mouse/Keyboard tab */
void DEF_mouseandkeyboard()
{
  int diff = 0;

  // Mouse Defaults

  diff += CHECKBUTTON_fancycursorshapes->value(1);
  diff += CHECKBUTTON_hidecursor->value(0);
  diff += CHECKBUTTON_grabmousepointer->value(0);
  diff += CHECKBUTTON_mousewheelsupport->value(1);
  diff += CHECKBUTTON_nobuttondistinction->value(0);

  // Keyboard Defaults

  diff += CHECKBUTTON_enablekbd->value(1);

  if (diff)
    activate_buttons();
}

bool CHKBUT_fancycursors_isdef()
{
  if (CHECKBUTTON_fancycursorshapes->value() == 1)
    return 1;
  else
    return 0;
}

bool CHKBUT_grabmouse_isdef()
{
  if (CHECKBUTTON_grabmousepointer->value() == 0)
    return 1;
  else
    return 0;
}

bool CHKBUT_mousewheelsup_isdef()
{
  if (CHECKBUTTON_mousewheelsupport->value() == 1)
    return 1;
  else
    return 0;
}

bool CHKBUT_enablekb_isdef()
{
  if (CHECKBUTTON_enablekbd->value() == 1)
    return 1;
  else
    return 0;
}

/* Set defaults on Simplification tab */
void DEF_simplification()
{
  int diff = 0;

  // Interface Simplification Defaults

  diff += CHECKBUTTON_disableshaperotation->value(0);
  diff += CHECKBUTTON_simpleshapeoutlines->value(0);
  diff += CHECKBUTTON_showuppercasetextonly->value(0);

  // Initial Stamp Size Default

  // Control Simplification Defaults
  diff += SLIDER_stampsize->value(-1);
  cb_SLIDER_stampsize(SLIDER_stampsize, NULL);

  diff += CHECKBUTTON_disablequitbutton->value(0);
  diff += CHECKBUTTON_disablestampstool->value(0);
  diff += CHECKBUTTON_disablestampcontrols->value(0);
  diff += CHECKBUTTON_disablestamprotation->value(0);
  diff += CHECKBUTTON_disablemagiccontrols->value(0);
  diff += CHECKBUTTON_disablemagicsizes->value(0);
  diff += CHECKBUTTON_ungroupmagictools->value(0);
  diff += CHECKBUTTON_disableshapecontrols->value(0);
  diff += CHECKBUTTON_disablelabeltool->value(0);
  diff += CHECKBUTTON_disablebrushspacing->value(0);
  diff += CHECKBUTTON_disabletemplateexport->value(0);
  diff += CHECKBUTTON_disableerase->value(0);
  diff += CHOICE_complexity->value(0);

  if (diff)
    activate_buttons();
}

bool CHKBUT_norots_isdef()
{
  if (CHECKBUTTON_disableshaperotation->value() == 0)
    return 1;
  else
    return 0;
}

bool CHKBUT_smploutlns_isdef()
{
  if (CHECKBUTTON_simpleshapeoutlines->value() == 0)
    return 1;
  else
    return 0;
}

bool CHKBUT_showUConly_isdef()
{
  if (CHECKBUTTON_showuppercasetextonly->value() == 0)
    return 1;
  else
    return 0;
}

bool CHKBUT_disablequit_isdef()
{
  if (CHECKBUTTON_disablequitbutton->value() == 0)
    return 1;
  else
    return 0;
}

/* Set defaults on Languages tab */
void DEF_locale()
{
  int diff = 0;

  // Locale Defaults

  diff += CHOICE_language->value(0);
  diff += CHECKBUTTON_mirrorstamps->value(0);
  diff += CHECKBUTTON_loadsystemfonts->value(0);
  diff += CHECKBUTTON_alllocalefonts->value(0);
  if (BROWSER_uifont->value() != UIFONT_NOCHANGE)
  {
    /* N.B. Fl_Browser's array is 1-based! */
    diff += 1;
    BROWSER_uifont->value(UIFONT_NOCHANGE);
    BROWSER_uifont->make_visible(UIFONT_NOCHANGE);
  }

  if (diff)
    activate_buttons();
}

bool CHKBUT_mirstamps_isdef()
{
  if (CHECKBUTTON_mirrorstamps->value() == 0)
    return 1;
  else
    return 0;
}

/* Set defaults on Printing tab */
void DEF_printing()
{
  int diff = 0;

  // Printing Perm. Defaults

  diff += CHECKBUTTON_allowprinting->value(1);
  diff += VALUEINPUT_printdelay->value(0);

  // Print Dialog

  diff += ROUNDBUTTON_printdialogmod->value(1);
  diff += ROUNDBUTTON_printdialogalways->value(0);
  diff += ROUNDBUTTON_printdialognever->value(0);

  // Print Cmd. Defaults

  diff += CHECKBUTTON_usealtprintcmd->value(0);
  TEXTINPUT_printcmd->value("");
  TEXTINPUT_printcmd->deactivate();

  // Print Dialog Cmd. Defaults

  diff += CHECKBUTTON_usealtprintdia->value(0);
  TEXTINPUT_printdia->value("");
  TEXTINPUT_printdia->deactivate();

#ifdef USE_PAPERSIZES
  diff += CHOICE_papersize->value(0);
#endif

  if (diff)
    activate_buttons();
}

bool CHKBUT_allowprint_isdef()
{
  if (CHECKBUTTON_allowprinting->value() == 1)
    return 1;
  else
    return 0;
}

bool VALINP_printdel_isdef()
{
  if (VALUEINPUT_printdelay->value() == 0)
    return 1;
  else
    return 0;
}

bool BROWSER_uifont_isdef()
{
  if (BROWSER_uifont->value() == UIFONT_NOCHANGE)
    return 1;
  else
    return 0;
}

/* Set defaults on Saving tab */
void DEF_saving()
{
  int diff = 0;

  // Save Over Earlier Work Defaults

  diff += ROUNDBUTTON_askbeforeoverwriting->value(1);
  diff += ROUNDBUTTON_alwaysoverwriteolderversion->value(0);
  diff += ROUNDBUTTON_alwayssavenewpicture->value(0);

  // Save and Export Directories Defaults

  diff += CHECKBUTTON_usealternatesavedir->value(0);
  FILEINPUT_alternatesavedir->value("");
  FILEINPUT_alternatesavedir->deactivate();
  BUTTON_browsealternatesavedir->deactivate();

  diff += CHECKBUTTON_usealternateexportdir->value(0);
  FILEINPUT_alternateexportdir->value("");
  FILEINPUT_alternateexportdir->deactivate();
  BUTTON_browsealternateexportdir->deactivate();

  // Starting Out Defaults

  diff += CHECKBUTTON_startblank->value(0);
  diff += CHECKBUTTON_newcolorslast->value(0);

  // More Saving Options Defaults

  diff += CHECKBUTTON_disablesavebutton->value(0);
  diff += CHECKBUTTON_autosave->value(0);
  diff += CHECKBUTTON_reversesort->value(0);

  if (diff)
    activate_buttons();
}

/* Set defaults on Data tab */
void DEF_data()
{
  int diff = 0;

  // Data Directory Defaults

  diff += CHECKBUTTON_nolockfile->value(0);

  diff += CHECKBUTTON_usealternatedatadir->value(0);
  FILEINPUT_alternatedatadir->value("");
  FILEINPUT_alternatedatadir->deactivate();
  BUTTON_browsealternatedatadir->deactivate();

  // Colors

  diff += CHECKBUTTON_usecolorfile->value(0);
  FILEINPUT_colorfile->value("");
  FILEINPUT_colorfile->deactivate();
  BUTTON_browsecolorfile->deactivate();

  if (diff)
    activate_buttons();
}

/* Set defaults on Accessibility tab */
void DEF_accessibility()
{
  int diff = 0;
  diff += CHECKBUTTON_mouse_accessibility->value(0);
  diff += CHECKBUTTON_keyboard_mouse->value(0);
  diff += CHECKBUTTON_onscreen_keyboard->value(0);
  diff += CHECKBUTTON_onscreen_keyboard_disable_change->value(0);
  diff += CHOICE_onscreen_keyboard_layout->value(0);

  if (diff)
    activate_buttons();
}

/* Set defaults on Joystick tab */
void DEF_joystick()
{
  int diff = 0;

  if (SPINNER_joystick_dev->value() != 0)
  {
    SPINNER_joystick_dev->value(0);
    diff += 1;
  }
  if (SPINNER_joystick_slowness->value() != 15)
  {
    SPINNER_joystick_slowness->value(15);
    diff += 1;
  }
  if (SPINNER_joystick_threshold->value() != 3200)
  {
    SPINNER_joystick_threshold->value(3200);
    diff += 1;
  }
  if (SPINNER_joystick_maxsteps->value() != 7)
  {
    SPINNER_joystick_maxsteps->value(7);
    diff += 1;
  }
  if (SPINNER_joystick_hat_slowness->value() != 15)
  {
    SPINNER_joystick_hat_slowness->value(15);
    diff += 1;
  }
  if (SPINNER_joystick_hat_timeout->value() != 1000)
  {
    SPINNER_joystick_hat_timeout->value(1000);
    diff += 1;
  }
  if (CHECKBUTTON_joystick_buttons_ignore->value() != 0)
  {
    CHECKBUTTON_joystick_buttons_ignore->value(0);
    diff += 1;
  }
  if (strlen(TEXTINPUT_joystick_buttons_ignore->value()) > 0)
  {
    TEXTINPUT_joystick_buttons_ignore->value("");
    diff += 1;
  }
  TEXTINPUT_joystick_buttons_ignore->deactivate();
  if (SPINNER_joystick_btn_brush->value() != 255)
  {
    SPINNER_joystick_btn_brush->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_label->value() != 255)
  {
    SPINNER_joystick_btn_label->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_new->value() != 255)
  {
    SPINNER_joystick_btn_new->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_print->value() != 255)
  {
    SPINNER_joystick_btn_print->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_shapes->value() != 255)
  {
    SPINNER_joystick_btn_shapes->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_undo->value() != 255)
  {
    SPINNER_joystick_btn_undo->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_eraser->value() != 255)
  {
    SPINNER_joystick_btn_eraser->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_lines->value() != 255)
  {
    SPINNER_joystick_btn_lines->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_open->value() != 255)
  {
    SPINNER_joystick_btn_open->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_redo->value() != 255)
  {
    SPINNER_joystick_btn_redo->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_stamp->value() != 255)
  {
    SPINNER_joystick_btn_stamp->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_escape->value() != 255)
  {
    SPINNER_joystick_btn_escape->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_fill->value() != 255)
  {
    SPINNER_joystick_btn_fill->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_magic->value() != 255)
  {
    SPINNER_joystick_btn_magic->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_pgsetup->value() != 255)
  {
    SPINNER_joystick_btn_pgsetup->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_save->value() != 255)
  {
    SPINNER_joystick_btn_save->value(255);
    diff += 1;
  }
  if (SPINNER_joystick_btn_text->value() != 255)
  {
    SPINNER_joystick_btn_text->value(255);
    diff += 1;
  }

  if (diff)
    activate_buttons();
}

bool RNDBUT_askoverwrite_isdef()
{
  if (ROUNDBUTTON_askbeforeoverwriting->value() == 1)
    return 1;
  else
    return 0;
}

bool CHKBUT_altsavedir_isdef()
{
  if (CHECKBUTTON_usealternatesavedir->value() == 0)
    return 1;
  else
    return 0;
}


bool CHKBUT_altexportdir_isdef()
{
  if (CHECKBUTTON_usealternateexportdir->value() == 0)
    return 1;
  else
    return 0;
}


bool CHKBUT_altdatadir_isdef()
{
  if (CHECKBUTTON_usealternatedatadir->value() == 0)
    return 1;
  else
    return 0;
}


void CB_SetActualTabToDefaults()
{
  if (TABE_videoandsound->visible())
  {
    DEF_videoandsound();
    return;
  }

  if (TABE_mouseandkeyboard->visible())
  {
    DEF_mouseandkeyboard();
    return;
  }

  if (TABE_simplification->visible())
  {
    DEF_simplification();
    return;
  }

  if (TABE_locale->visible())
  {
    DEF_locale();
    return;
  }

  if (TABE_printing->visible())
  {
    DEF_printing();
    return;
  }

  if (TABE_saving->visible())
  {
    DEF_saving();
    return;
  }

  if (TABE_data->visible())
  {
    DEF_data();
    return;
  }
  if (TABE_accessibility->visible())
  {
    DEF_accessibility();
    return;
  }
  if (TABE_joystick->visible())
  {
    DEF_joystick();
    return;
  }
}

/* Set all settings on every tab to their default values */
void CB_SetAllTabsToDefaults()
{
  DEF_videoandsound();
  DEF_mouseandkeyboard();
  DEF_simplification();
  DEF_locale();
  DEF_printing();
  DEF_saving();
  DEF_data();
  DEF_accessibility();
  DEF_joystick();
}

void update_canvas_size(void)
{
  char * tmp;
  int max_scale, win_w, win_h, canv_w, canv_h;
  int button_w, button_h, buttons_tall, colors_rows, colors_h;
  float button_scale, max_w, max_h;
 
  tmp = (char *) malloc(sizeof(char) * 1024);

  if (CHOICE_windowwidth->value() == -1 ||
      CHOICE_windowheight->value() == -1) {
    tmp = gettext("Canvas size...");
  } else if (CHECKBUTTON_native->value()) {
    tmp = gettext("Canvas size will depend on native screen resolution.");
  } else {
    /* Start with window size */
    if (CHECKBUTTON_rotate->value()) {
      win_h = atoi(window_widths[CHOICE_windowwidth->value()]);
      win_w = atoi(window_heights[CHOICE_windowheight->value()]);
    } else {
      win_w = atoi(window_widths[CHOICE_windowwidth->value()]);
      win_h = atoi(window_heights[CHOICE_windowheight->value()]);
    }

    /* The calculations here need to be kept in sync with Tux Paint's
       setup_normal_screen_layout() function! */

    if (CHECKBUTTON_buttonsizeauto->value()) {
      float scale_w, scale_h;
      scale_w = (float)(48 * win_w) / 800.0;
      scale_h = (float)(48 * win_h) / 600.0;
      button_scale = (float) (scale_w < scale_h ? scale_w : scale_h) / 48.0;
    } else {
      button_scale = (float) SLIDER_buttonsize->value() / 48.0;
    }

    /* N.B. These are calc'd again below if max_scale gets set! */
    canv_w = win_w - (2 + 2) * (48 * button_scale);

    button_w = 48 * button_scale;
    button_h = 48 * button_scale;

    colors_rows = SLIDER_colorsrows->value();
    colors_h = 48 * button_scale * colors_rows;

    /* need 56 minimum for the Tux area */
    buttons_tall = (win_h - (40 * button_scale) - 56 * button_scale - colors_h) / button_h;

    max_scale = 0;

    if (buttons_tall < 5)
    {
      fprintf(stderr,
              "Button size '%d' with window size '%dx%d' is not reasonable (not tall enough).\n",
              button_w, win_w, win_h);
      max_scale = 1;
    }

    if (canv_w < button_w * 9)
    {
      fprintf(stderr,
              "Button size '%d' with window size '%dx%d' is not reasonable (not wide enough).\n",
              button_w, win_w, win_h);
      max_scale = 1;
    }

    if (max_scale) {
      /* WINDOW_WIDTH / original size of tools columns + 9 buttons + tooloption columns */
      max_w = (float)win_w / (float) (2 * 48 + 9 * 48 + 2 * 48);
  
      /* WINDOW_HEIGHT / original size of r_ttools.h + 5 buttons + colors rows + tux area */
      max_h = (float)win_h / (float) (40 + 5 * 48 + colors_rows * 48 + 56);
  
      button_scale = (max_w < max_h ? max_w : max_h);

      /* N.B. Re-calc of the above! */
      canv_w = win_w - (2 + 2) * (48 * button_scale);
  
      button_w = 48 * button_scale;
      button_h = 48 * button_scale;
  
      /* need 56 minimum for the Tux area */
      buttons_tall = (win_h - (40 * button_scale) - 56 * button_scale - 48 /* FIXME r_colors.h */) / button_h;
    }

    canv_h = (40 * button_scale) + buttons_tall * button_h;

    if (max_scale) {
      snprintf(tmp, 1024,
        gettext("Canvas: %1$d x %2$d (max button size %3$d)"),
        canv_w, canv_h, (int) (48 * button_scale)
      );
    } else {
      snprintf(tmp, 1024,
        gettext("Canvas size: %1$d x %2$d"),
        canv_w, canv_h
      );
    }
  }

  BOX_canvas_size->label(tmp);
} 

