/*
 *  Prefs.c - Handhabung des Einstellungsfensters
 *
 *  Copyright (C) 1994-1996 by Christian Bauer
 */

#include <exec/types.h>
#include <intuition/gadgetclass.h>
#include <graphics/displayinfo.h>
#include <workbench/workbench.h>
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <clib/icon_protos.h>
#include <string.h>

#include "Prefs.h"
#include "FrodoGUI.h"
#include "Frodo_rev.h"
#define CATCOMP_NUMBERS 1
#include "LocStrings.h"


// Aus Main.asm
extern char *GetStr(int strnum);
extern short PrefsFromEmul;
extern char PrefsName[256];
extern USHORT IsDraco;

// Aus 6510(SC).asm
extern USHORT IsFrodoSC;


// Prototypes
void set_gadgets(Preferences *p);
void set_display_id_gadget(Preferences *p);
void get_gadgets(Preferences *p);
void ghost_gadgets(Preferences *p);
int handle_IDCMP(Preferences *p, struct Window *win, int done);
int handle_gadget(Preferences *p, struct Window *win, struct Gadget *gad, UWORD code, int done);
int handle_menu(Preferences *p, struct Window *win, int menu, int item, int done);
int handle_key(Preferences *p, struct Window *win, UWORD code, int done);
int request_display_id(struct Window *win, ULONG *display_id, UWORD *overscan);
int request_drive(struct Window *win, UWORD type, char *str);
int request_file(struct Window *win, char *name, int hail, int save);
void open_prefs_as(Preferences *p);
void save_prefs(Preferences *p);
void save_prefs_as(Preferences *p);


// Requester
struct EasyStruct about_req = {
  sizeof(struct EasyStruct), 0, NULL, NULL, NULL
};


// Icon der Prefs-Datei
const UWORD PrefsI1Data[] =
{
/* Plane 0 */
    0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0C00,
    0x0003,0xFFC0,0x0000,0x0C00,0x000C,0x0030,0x0000,0x0C00,
    0x0010,0x7E08,0x0000,0x0C00,0x0020,0x8104,0x0000,0x0C00,
    0x0020,0x4104,0x0000,0x0C00,0x0020,0x4104,0x0000,0x0C00,
    0x0010,0x8204,0x0000,0x0C00,0x000F,0x0C08,0x0000,0x0C00,
    0x0000,0x3010,0x0000,0x0C00,0x0000,0x4060,0x0000,0x0C00,
    0x0000,0x8180,0x0000,0x0C00,0x0001,0x0E00,0x0000,0x0C00,
    0x0000,0x8400,0x0000,0x0C00,0x0000,0x7800,0x0000,0x0C00,
    0x0000,0x8400,0x0000,0x0C00,0x0000,0x8400,0x0000,0x0C00,
    0x0000,0x7800,0x0000,0x0C00,0x0000,0x0000,0x0000,0x0C00,
    0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
/* Plane 1 */
    0xFFFF,0xFFFF,0xFFFF,0xF800,0xD555,0x5557,0xD555,0x5000,
    0xD554,0x001F,0xF555,0x5000,0xD553,0xFFCF,0xF555,0x5000,
    0xD54F,0x81F7,0xF555,0x5000,0xD55F,0x54FB,0xF555,0x5000,
    0xD55F,0x94FB,0xFFD5,0x5000,0xD55F,0x94F9,0x7FF5,0x5000,
    0xD54F,0x55F9,0x7FD5,0x5000,0xD550,0x53F5,0x7FD5,0x5000,
    0xD555,0x4FE5,0x5F55,0x5000,0xD555,0x3F95,0x60D5,0x5000,
    0xD555,0x7E7D,0x6055,0x5000,0xD554,0xF1FD,0x6035,0x5000,
    0xD555,0x79FF,0xFFD5,0x5000,0xD555,0x05FF,0xF555,0x5000,
    0xD555,0x797F,0xF555,0x5000,0xD555,0x797F,0xF555,0x5000,
    0xD555,0x055F,0xF555,0x5000,0xD555,0x5557,0xD555,0x5000,
    0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000,
/* Plane 2 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
/* Plane 3 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
/* Plane 4 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
/* Plane 5 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
/* Plane 6 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
/* Plane 7 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x000F,0xE000,0x0000,
    0x0000,0x0007,0xE000,0x0000,0x0000,0x0003,0xE000,0x0000,
    0x0000,0x0000,0x6000,0x0000,0x0000,0x0000,0x1FC0,0x0000,
    0x0000,0x0000,0x1F80,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F00,0x0000,
    0x0000,0x0070,0x1F80,0x0000,0x0000,0x00F0,0x1FC0,0x0000,
    0x0000,0x00FC,0x6000,0x0000,0x0000,0x007F,0xE000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x001F,0xE000,0x0000,
    0x0000,0x0007,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
};

const struct Image PrefsI1 =
{
    0, 0,			/* Upper left corner */
    54, 22, 8,		/* Width, Height, Depth */
    PrefsI1Data,	/* Image data */
    0x00FF, 0x0000,	/* PlanePick, PlaneOnOff */
    NULL			/* Next image */
};

const struct DiskObject PrefsIcon =
{
    WB_DISKMAGIC,		/* Magic Number */
    WB_DISKVERSION,		/* Version */
    {					/* Embedded Gadget Structure */
	NULL,				/* Next Gadget Pointer */
	0, 0, 54, 23,		/* Left,Top,Width,Height */
	GFLG_GADGIMAGE | GFLG_GADGHCOMP,	/* Flags */
	GACT_RELVERIFY,		/* Activation Flags */
	BOOLGADGET,			/* Gadget Type */
	(APTR)&PrefsI1,		/* Render Image */
	NULL,				/* Select Image */
	NULL,				/* Gadget Text */
	NULL,				/* Mutual Exclude */
	NULL,				/* Special Info */
	0,					/* Gadget ID */
	(APTR) 0x0001,		/* User Data (Revision) */
    },
    WBPROJECT,			/* Icon Type */
    (char *)"Frodo",	/* Default Tool */
    NULL,				/* Tool Type Array */
    NO_ICON_POSITION,	/* Current X */
    NO_ICON_POSITION,	/* Current Y */
    NULL,				/* Drawer Structure */
    NULL,				/* Tool Window */
    0					/* Stack Size */
};


/*
 *  Einstellungsfenster öffnen, handhaben und schließen
 *  Die Preferences werden auf jeden Fall verändert, auch bei Cancel
 *  0: Cancel, 1: OK
 */

int DoThePrefs(Preferences *p)
{
  int done = FALSE;

  if (!SetupScreen()) {
    if (!OpenPrefsWindow()) {
      SetWindowTitles(PrefsWnd,
        GetStr(IsFrodoSC ? MSG_PREFSTITLESC : MSG_PREFSTITLE),
        GetStr(IsFrodoSC ? MSG_SCREENTITLESC : MSG_SCREENTITLE));

      set_gadgets(p);

      // ScreenReqWindow, DirReqWindow, FileReqWindow setzen
      while (!done) {
        WaitPort(PrefsWnd->UserPort);
        done = handle_IDCMP(p, PrefsWnd, done);
      }
      if (done == -1) done = 0;

      get_gadgets(p);

      ClosePrefsWindow();
    }
    CloseDownScreen();
  }

  return done;
}


/*
 *  Gadgets auf die Einstellungen setzen
 */

void set_gadgets(Preferences *p)
{
  GT_SetGadgetAttrs(PrefsGadgets[GDX_NormalCycles], PrefsWnd, NULL,
    GTIN_Number, p->normal_cycles, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_BadLineCycles], PrefsWnd, NULL,
    GTIN_Number, p->bad_line_cycles, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_CIACycles], PrefsWnd, NULL,
    GTIN_Number, p->CIA_cycles, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_SkipLatch], PrefsWnd, NULL,
    GTIN_Number, p->skip_latch, TAG_DONE);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_Joystick1On], PrefsWnd, NULL,
    GTCB_Checked, p->joystick_1_on, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Joystick2On], PrefsWnd, NULL,
    GTCB_Checked, p->joystick_2_on, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_JoystickSwap], PrefsWnd, NULL,
    GTCB_Checked, p->joystick_swap, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_KeyboardYZ], PrefsWnd, NULL,
    GTCB_Checked, p->keyboard_yz, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_SpritesOn], PrefsWnd, NULL,
    GTCB_Checked, p->sprites_on, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Collisions], PrefsWnd, NULL,
    GTCB_Checked, p->collisions, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_FastReset], PrefsWnd, NULL,
    GTCB_Checked, p->fast_reset, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_LimitSpeed], PrefsWnd, NULL,
    GTCB_Checked, p->limit_speed, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_DirectVideo], PrefsWnd, NULL,
    GTCB_Checked, p->direct_video, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_OtherIEC], PrefsWnd, NULL,
    GTCB_Checked, p->other_IEC, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_MapSlash], PrefsWnd, NULL,
    GTCB_Checked, p->map_slash, TAG_DONE);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_SIDType], PrefsWnd, NULL,
    GTCY_Active, p->SID_type, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_ScreenType], PrefsWnd, NULL,
    GTCY_Active, p->screen_type, TAG_DONE);

  set_display_id_gadget(p);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_Drv8Type], PrefsWnd, NULL,
    GTCY_Active, p->drv_8_type, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Drv9Type], PrefsWnd, NULL,
    GTCY_Active, p->drv_9_type, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Drv10Type], PrefsWnd, NULL,
    GTCY_Active, p->drv_10_type, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Drv11Type], PrefsWnd, NULL,
    GTCY_Active, p->drv_11_type, TAG_DONE);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir8], PrefsWnd, NULL,
    GTST_String, p->dir_8, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir9], PrefsWnd, NULL,
    GTST_String, p->dir_9, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir10], PrefsWnd, NULL,
    GTST_String, p->dir_10, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir11], PrefsWnd, NULL,
    GTST_String, p->dir_11, TAG_DONE);

  ghost_gadgets(p);
}


/*
 *  Display-ID-Gadget setzen
 */

char mode_name[DISPLAYNAMELEN];

void set_display_id_gadget(Preferences *p)
{
  struct NameInfo query;

  GetDisplayInfoData(NULL, (UBYTE *)&query, sizeof(query), DTAG_NAME, p->display_id);
  strncpy(mode_name, query.Name, DISPLAYNAMELEN);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_DisplayID], PrefsWnd, NULL,
    GTTX_Text, mode_name, TAG_DONE);
}


/*
 *  Einstellungen aus den Gadgets lesen
 */

void get_gadgets(Preferences *p)
{
  p->normal_cycles = GetNumber(PrefsGadgets[GDX_NormalCycles]);
  p->bad_line_cycles = GetNumber(PrefsGadgets[GDX_BadLineCycles]);
  p->CIA_cycles = GetNumber(PrefsGadgets[GDX_CIACycles]);
  p->skip_latch = GetNumber(PrefsGadgets[GDX_SkipLatch]);

  strncpy(p->dir_8, GetString(PrefsGadgets[GDX_Dir8]), 256);
  strncpy(p->dir_9, GetString(PrefsGadgets[GDX_Dir9]), 256);
  strncpy(p->dir_10, GetString(PrefsGadgets[GDX_Dir10]), 256);
  strncpy(p->dir_11, GetString(PrefsGadgets[GDX_Dir11]), 256);
}


/*
 *  Gadgets korrekt ghosten
 */

void ghost_gadgets(Preferences *p)
{
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir8], PrefsWnd, NULL,
    GA_Disabled, p->drv_8_type == DRVTYPE_IEC, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir9], PrefsWnd, NULL,
    GA_Disabled, p->drv_9_type == DRVTYPE_IEC, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir10], PrefsWnd, NULL,
    GA_Disabled, p->drv_10_type == DRVTYPE_IEC, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir11], PrefsWnd, NULL,
    GA_Disabled, p->drv_11_type == DRVTYPE_IEC, TAG_DONE);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_Collisions], PrefsWnd, NULL,
    GA_Disabled, p->screen_type == SCRTYPE_1BIT, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_DirectVideo], PrefsWnd, NULL,
    GA_Disabled, (p->screen_type != SCRTYPE_8BIT) || PrefsFromEmul, TAG_DONE);

  GT_SetGadgetAttrs(PrefsGadgets[GDX_GetDisplayID], PrefsWnd, NULL,
    GA_Disabled, PrefsFromEmul, TAG_DONE);
  GT_SetGadgetAttrs(PrefsGadgets[GDX_ScreenType], PrefsWnd, NULL,
    GA_Disabled, PrefsFromEmul, TAG_DONE);

  if (IsFrodoSC) {
    GT_SetGadgetAttrs(PrefsGadgets[GDX_ScreenType], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_Collisions], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_NormalCycles], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_BadLineCycles], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_CIACycles], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_DirectVideo], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
  }

  if (IsDraco) {
    GT_SetGadgetAttrs(PrefsGadgets[GDX_Joystick1On], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_Joystick2On], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
    GT_SetGadgetAttrs(PrefsGadgets[GDX_OtherIEC], PrefsWnd, NULL,
      GA_Disabled, TRUE, TAG_DONE);
  }
}


/*
 *  IDCMP-Messages eines Fensters handhaben
 *  -1: Cancel, 1: OK, 0: weitermachen
 */

int handle_IDCMP(Preferences *p, struct Window *win, int done)
{
  struct IntuiMessage *msg;
  ULONG class;
  UWORD code;
  UWORD menu_number;
  struct Gadget *gad;
  struct MenuItem *item;

  while (!done && (msg = GT_GetIMsg(win->UserPort))) {
    class = msg->Class;
    code = msg->Code;
    gad = (struct Gadget *)msg->IAddress;

    GT_ReplyIMsg(msg);

    switch (class) {
      case IDCMP_GADGETUP:
        done = handle_gadget(p, win, gad, code, done);
        break;

      case IDCMP_MENUPICK:
        menu_number = code;
        while (!done && (menu_number != MENUNULL)) {
          item = ItemAddress(win->MenuStrip, menu_number);
          done = handle_menu(p, win, MENUNUM(menu_number), ITEMNUM(menu_number), done);
          menu_number = item->NextSelect;
        }
        break;

      case IDCMP_VANILLAKEY:
        done = handle_key(p, win, code, done);
        break;

      case IDCMP_REFRESHWINDOW:
        GT_BeginRefresh(win);
        GT_EndRefresh(win, TRUE);
        break;
    }
  }

  return done;
}


/*
 *  Gadget wurde betätigt
 *  -1: Cancel, 1: OK, 0: weitermachen
 */

int handle_gadget(Preferences *p, struct Window *win, struct Gadget *gad, UWORD code, int done)
{
  switch (gad->GadgetID) {
    case GD_OK:
      done = 1;
      break;

    case GD_Cancel:
      done = -1;
      break;

    case GD_Save:
      save_prefs(p);
      break;

    case GD_Joystick1On:
      p->joystick_1_on = p->joystick_1_on ? 0 : -1;
      break;

    case GD_Joystick2On:
      p->joystick_2_on = p->joystick_2_on ? 0 : -1;
      break;

    case GD_JoystickSwap:
      p->joystick_swap = p->joystick_swap ? 0 : -1;
      break;

    case GD_SIDType:
      p->SID_type = code;
      break;

    case GD_OtherIEC:
      p->other_IEC = p->other_IEC ? 0 : -1;
      break;

    case GD_KeyboardYZ:
      p->keyboard_yz = p->keyboard_yz ? 0 : -1;
      break;

    case GD_SpritesOn:
      p->sprites_on = p->sprites_on ? 0 : -1;
      break;

    case GD_Collisions:
      p->collisions = p->collisions ? 0 : -1;
      break;

    case GD_MapSlash:
      p->map_slash = p->map_slash ? 0 : -1;
      break;

    case GD_FastReset:
      p->fast_reset = p->fast_reset ? 0 : -1;
      break;

    case GD_LimitSpeed:
      p->limit_speed = p->limit_speed ? 0 : -1;
      break;

    case GD_DirectVideo:
      if (!PrefsFromEmul)
        p->direct_video = p->direct_video ? 0 : -1;
      break;

    case GD_ScreenType:
      if (!PrefsFromEmul)
        p->screen_type = code;
      ghost_gadgets(p);
      break;

    case GD_GetDisplayID:
      if (!PrefsFromEmul)
        if (request_display_id(win, &p->display_id, &p->overscan))
          set_display_id_gadget(p);
      break;

    case GD_Drv8Type:
      p->drv_8_type = code;
      ghost_gadgets(p);
      break;

    case GD_Drv9Type:
      p->drv_9_type = code;
      ghost_gadgets(p);
      break;

    case GD_Drv10Type:
      p->drv_10_type = code;
      ghost_gadgets(p);
      break;

    case GD_Drv11Type:
      p->drv_11_type = code;
      ghost_gadgets(p);
      break;

    case GD_GetDir8:
      strncpy(p->dir_8, GetString(PrefsGadgets[GDX_Dir8]), 256);
      if (request_drive(win, p->drv_8_type, p->dir_8))
        GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir8], PrefsWnd, NULL,
          GTST_String, p->dir_8, TAG_DONE);
      break;

    case GD_GetDir9:
      strncpy(p->dir_9, GetString(PrefsGadgets[GDX_Dir9]), 256);
      if (request_drive(win, p->drv_9_type, p->dir_9))
        GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir9], PrefsWnd, NULL,
          GTST_String, p->dir_9, TAG_DONE);
      break;

    case GD_GetDir10:
      strncpy(p->dir_10, GetString(PrefsGadgets[GDX_Dir10]), 256);
      if (request_drive(win, p->drv_10_type, p->dir_10))
        GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir10], PrefsWnd, NULL,
          GTST_String, p->dir_10, TAG_DONE);
      break;

    case GD_GetDir11:
      strncpy(p->dir_11, GetString(PrefsGadgets[GDX_Dir11]), 256);
      if (request_drive(win, p->drv_11_type, p->dir_11))
        GT_SetGadgetAttrs(PrefsGadgets[GDX_Dir11], PrefsWnd, NULL,
          GTST_String, p->dir_11, TAG_DONE);
      break;
  }

  return done;
}


/*
 *  Menü wurde ausgewählt
 *  -1: Cancel, 1: OK, 0: weitermachen
 */

int handle_menu(Preferences *p, struct Window *win, int menu, int item, int done)
{
  if (menu == 0) {
    switch (item) {
      case 0:		// Open
        open_prefs_as(p);
        break;

      case 2:		// Save
        save_prefs(p);
        break;

      case 3:		// Save As
        save_prefs_as(p);
        break;

      case 5:		// About
        EasyRequest(win, &about_req, NULL, VERSION, REVISION);
        break;

      case 7:		// OK
        done = 1;
        break;

      case 8:		// Cancel
        done = -1;
        break;
    }
  }

  return done;
}


/*
 *  Taste wurde gedrückt
 *  -1: Cancel, 1: OK, 0: weitermachen
 */

int handle_key(Preferences *p, struct Window *win, UWORD code, int done)
{
  switch (code) {
    case 'o':		// OK
    case 'O':
      done = 1;
      break;

    case 'c':		// Cancel
    case 'C':
      done = -1;
      break;

    case 's':
    case 'S':
      save_prefs(p);
      break;
  }

  return done;
}


/*
 *  Screenmode-Requester
 *  FALSE: Cancel, TRUE: OK
 */

int request_display_id(struct Window *win, ULONG *display_id, UWORD *overscan)
{
  struct ScreenModeRequester *sm;
  int result = FALSE;

  if (sm = AllocAslRequestTags(ASL_ScreenModeRequest,
    ASLSM_TitleText, GetStr(MSG_SCREENHAIL),
    ASLSM_Window, win,
    ASLSM_SleepWindow, TRUE,
    ASLSM_DoOverscanType, TRUE,
    ASLSM_PropertyMask, DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE | DIPF_IS_DUALPF,
    ASLSM_PropertyFlags, 0,
    ASLSM_InitialDisplayID, *display_id,
    ASLSM_InitialOverscanType, *overscan,
    TAG_DONE)) {

    if (result = AslRequest(sm, NULL)) {
      *display_id = sm->sm_DisplayID;
      *overscan = sm->sm_OverscanType;
    }

    FreeAslRequest(sm);
  }

  return result;
}


/*
 *  Requester für Verzeichnis/.d64-Datei
 *  FALSE: Cancel, TRUE: OK
 */

int request_drive(struct Window *win, UWORD type, char *str)
{
  struct FileRequester *fr;
  int result = FALSE;

  if (type == DRVTYPE_D64) {
    return request_file(win, str, MSG_D64HAIL, FALSE);

  } else {
    if (fr = AllocAslRequestTags(ASL_FileRequest,
      ASLFR_TitleText, GetStr(MSG_DIRHAIL),
      ASLFR_InitialDrawer, str,
      ASLFR_Window, win,
      ASLFR_SleepWindow, TRUE,
      ASLFR_Flags2, FRF_REJECTICONS | FRF_DRAWERSONLY,
      TAG_DONE)) {

      if (result = AslRequest(fr, NULL))
        strncpy(str, fr->fr_Drawer, 256);

      FreeAslRequest(fr);
    }
  }

  return result;
}


/*
 *  Einfacher Dateirequester
 *  FALSE: Cancel, TRUE: OK
 */

int request_file(struct Window *win, char *name, int hail, int save)
{
  struct FileRequester *fr;
  int result = FALSE;
  char dir[256];
  char file[256];
  char *s;

  // Pfad und Dateinamen aufteilen (dir, file)
  strcpy(dir, name);
  s = FilePart(dir);
  strcpy(file, s);
  *s = 0;

  if (fr = AllocAslRequestTags(ASL_FileRequest,
    ASLFR_TitleText, GetStr(hail),
    ASLFR_Window, win,
    ASLFR_SleepWindow, TRUE,
    ASLFR_InitialDrawer, dir,
    ASLFR_InitialFile, file,
    ASLFR_Flags1, save ? FRF_DOSAVEMODE : 0,
    ASLFR_Flags2, FRF_REJECTICONS,
    TAG_DONE)) {

    if (result = AslRequest(fr, NULL)) {
      strncpy(name, fr->fr_Drawer, 256);
      AddPart(name, fr->fr_File, 256);
    }

    FreeAslRequest(fr);
  }

  return result;
}


/*
 *  Einstellungen laden
 */

void OpenPrefs(Preferences *p)
{
  BPTR fh;

  if (fh = Open(PrefsName, MODE_OLDFILE)) {
    Read(fh, p, sizeof(Preferences));
    Close(fh);

    // Altes drv_?_is_IEC konvertieren
    if (p->drv_8_type == 0xffff)
      p->drv_8_type = DRVTYPE_IEC;
    if (p->drv_9_type == 0xffff)
      p->drv_9_type = DRVTYPE_IEC;
    if (p->drv_10_type == 0xffff)
      p->drv_10_type = DRVTYPE_IEC;
    if (p->drv_11_type == 0xffff)
      p->drv_11_type = DRVTYPE_IEC;

    // Altes use_SID_card konvertieren
    if (p->SID_type == 0xffff)
      p->SID_type = SIDTYPE_CARD;
  }  
}


/*
 *  Einstellungen laden (Dateirequester, ändert PrefsName)
 */

void open_prefs_as(Preferences *p)
{
  if (request_file(PrefsWnd, PrefsName, MSG_PREFSHAIL, FALSE)) {
    OpenPrefs(p);
    set_gadgets(p);
  }
}


/*
 *  Einstellungen unter aktuellem Namen speichern
 */

void save_prefs(Preferences *p)
{
  BPTR fh;
  struct DiskObject *dobj;

  get_gadgets(p);

  if (fh = Open(PrefsName, MODE_NEWFILE)) {
    Write(fh, p, sizeof(Preferences));
    Close(fh);

    if (dobj = GetDiskObject(PrefsName))
      FreeDiskObject(dobj);
    else
      PutDiskObject(PrefsName, &PrefsIcon);
  }
}


/*
 *  Einstellungen speichern (Dateirequester, ändert PrefsName)
 */

void save_prefs_as(Preferences *p)
{
  if (request_file(PrefsWnd, PrefsName, MSG_PREFSHAIL, TRUE))
    save_prefs(p);
}


/*
 *  Lokalisierungen vornehmen
 */

const int gadget_table[] = {
  GDX_OK, MSG_OK_GAD,
  GDX_Save, MSG_SAVE_GAD,
  GDX_Cancel, MSG_CANCEL_GAD,
  GDX_Joystick1On, MSG_JOYSTICK1ON_GAD,
  GDX_Joystick2On, MSG_JOYSTICK2ON_GAD,
  GDX_JoystickSwap, MSG_JOYSTICKSWAP_GAD,
  GDX_GetDisplayID, MSG_GETDISPLAYID_GAD,
  GDX_DisplayID, MSG_DISPLAYID_GAD,
  GDX_ScreenType, MSG_SCREENTYPE_GAD,
  GDX_NormalCycles, MSG_NORMALCYCLES_GAD,
  GDX_BadLineCycles, MSG_BADLINECYCLES_GAD,
  GDX_CIACycles, MSG_CIACYCLES_GAD,
  GDX_Drv8Type, MSG_DIR8_GAD,
  GDX_Drv9Type, MSG_DIR9_GAD,
  GDX_Drv10Type, MSG_DIR10_GAD,
  GDX_Drv11Type, MSG_DIR11_GAD,
  GDX_SIDType, MSG_SIDTYPE_GAD,
  GDX_OtherIEC, MSG_OTHERIEC_GAD,
  GDX_KeyboardYZ, MSG_KEYBOARDYZ_GAD,
  GDX_SpritesOn, MSG_SPRITESON_GAD,
  GDX_Collisions, MSG_COLLISIONS_GAD,
  GDX_MapSlash, MSG_MAPSLASH_GAD,
  GDX_FastReset, MSG_FASTRESET_GAD,
  GDX_SkipLatch, MSG_SKIPLATCH_GAD,
  GDX_LimitSpeed, MSG_LIMITSPEED_GAD,
  GDX_DirectVideo, MSG_DIRECTVIDEO_GAD,
  -1
};

void LocalizePrefs(void)
{
  int i;

  about_req.es_Title = GetStr(IsFrodoSC ? MSG_ABOUTTITLESC : MSG_ABOUTTITLE);
  about_req.es_TextFormat = GetStr(IsFrodoSC ? MSG_ABOUTSC_REQ : MSG_ABOUT_REQ);
  about_req.es_GadgetFormat = GetStr(MSG_REQGADS5);

  PrefsWdt = GetStr(MSG_PREFSTITLE);

  PrefsNewMenu[0].nm_Label = GetStr(MSG_PROJECT_MENU);
  PrefsNewMenu[1].nm_Label = GetStr(MSG_OPEN_MENU);
  PrefsNewMenu[3].nm_Label = GetStr(MSG_SAVE_MENU);
  PrefsNewMenu[4].nm_Label = GetStr(MSG_SAVEAS_MENU);
  PrefsNewMenu[6].nm_Label = GetStr(IsFrodoSC ? MSG_ABOUTSC_MENU : MSG_ABOUT_MENU);
  PrefsNewMenu[8].nm_Label = GetStr(MSG_OK_MENU);
  PrefsNewMenu[9].nm_Label = GetStr(MSG_CANCEL_MENU);

  for (i=0; gadget_table[i]>=0; i+=2)
    PrefsNGad[gadget_table[i]].ng_GadgetText = GetStr(gadget_table[i+1]);

  SIDType0Labels[0] = GetStr(MSG_SIDTYPEOFF_LAB);
  SIDType0Labels[1] = GetStr(MSG_SIDTYPECARD_LAB);
  SIDType0Labels[2] = GetStr(MSG_SIDTYPEA64_LAB);
  SIDType0Labels[3] = GetStr(MSG_SIDTYPEPSID_LAB);
}
