/*
** MUI-Brief.c - alle Teile für die Briefliste und den Brief in MUI
**
** Copyright (C) 1996 by Stefan Scherer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for non-commerical use and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation.  This software is provided "as is" without
** express or implied warranty.
*/

#include "MUI_Main.h"


/* die Input Event Codes mit der Basis ID_LL_BASE  */

enum
  {
/* Briefliste */
    ID_LL_LIST = ID_LL_BASE,	/* Listview */
    ID_LL_NEWLETTER,		/* Neuer Brief */
    ID_LL_DELLETTER,		/* Brief löschen */
    ID_LL_COPYLETTER,		/* bestehenden Brief kopieren und edieren */
    ID_LL_EDITLETTER,		/* Brief edieren */
    ID_LL_PRINTLETTER,		/* Brief drucken */
    ID_LL_PRINTLIST,		/* Liste drucken (ShowDVI) */
    ID_LL_SELECTYEAR,		/* Jahrgang wählen */
    ID_LL_SELECTFILTER,		/* Filter für Liste wählen */

/* Briefe */
    ID_LE_OK,			/* Änderung des Briefes übernehmen */
    ID_LE_CANCEL,		/* Abbruch */
    ID_LE_NOADDR,		/* keine Adresse -> ohne Adreßfeld */
    ID_LE_CUSTOMER,		/* wähle Adresse aus Adreßliste für Brief */
    ID_LE_CHOOSE,		/* wähle Artikel aus Artikelliste */
    ID_LE_COMMAND,		/* wähle Befehl aus */
    ID_LE_TODAY,		/* "Ihre Nachricht vom" auf heutiges Datum */
    ID_LE_PREVIEW,		/* Briefvorschau */

    ID_LC_OK,			/* Befehl ausgewählt. */
  };


#ifndef MUIA_Boopsi_Smart
#define MUIA_Boopsi_Smart 0x8042b8d7	/* V9 i.. BOOL */
#endif


/*********************************************************************
**
**
**  B R I E F L I S T E
**
**
*********************************************************************/

/* Cycle Strings */

static char *CYA_LL_year[MAX_YEARS + 1];	/* Cycle-Array für MUI */
static char CYA_LL_year_buffer[5 * MAX_YEARS];	/* Puffer für Jahreszahlen */
static char *CYA_LL_mode[] =
{"alle Briefe",			/* DISP_LL_ALL */
 "nicht gedruckte Briefe",	/* DISP_LL_PRT */
 NULL};

/* Ausgabemöglichkeiten für den DisplayHook */

enum
  {
    DISP_LL_ALL,
    DISP_LL_PRT
  };

/* Gadgets der "Briefliste" */

APTR CY_LL_year, CY_LL_mode;
APTR LV_LL_list;
APTR BT_LL_new, BT_LL_del, BT_LL_edit, BT_LL_copy;
APTR BT_LL_prtlet, BT_LL_prtlist;

/*
** Cycle-Gadget Jahreszahlen der Briefliste:
** baue das String-Array für das Cycle-Gadget auf.
*/

void 
Build_LL_years (void)
{
  UWORD i;
  UWORD year;

  i = LL_GetYearCount ();
  for (i = 0; i < LL_GetYearCount () && i < MAX_YEARS; i++)
    {
      LL_GetYear (i, &year);
      sprintf (&CYA_LL_year_buffer[5 * i], "%04d", year);
      CYA_LL_year[i] = &CYA_LL_year_buffer[5 * i];
    }
  CYA_LL_year[i] = NULL;
}

/*
** Support-Funktionen für die "Briefliste"
**
** MUI verwaltet eine eigene Liste, die intern alle Daten aufnimmt
** und über eine DisplayFunc am Bildschirm angezeigt wird.
*/

SAVEDS ASM APTR 
LL_ConstructFunc (REG (a1)
		  struct MinLetter *letter,
		  REG (a2)
		  void *mempool)
{
  struct MinLetter *newitem;

  if (newitem = LibAllocPooled (mempool, sizeof (struct MinLetter)))
    {
      newitem->letterNumber = letter->letterNumber;
      newitem->letterYear = letter->letterYear;
      strcpy (newitem->letterDate, letter->letterDate);
      strcpy (newitem->Kunde, letter->Kunde);
      strcpy (newitem->Betreff, letter->Betreff);
      strcpy (newitem->orderDate, letter->orderDate);
    }

  return ((APTR) newitem);
}

SAVEDS ASM VOID 
LL_DestructFunc (REG (a1) struct MinLetter * letter,
		 REG (a2) void *mempool)
{
  LibFreePooled (mempool, letter, sizeof (struct MinLetter));
}

SAVEDS ASM LONG 
LL_DisplayFunc (REG (a2)
		char **array,
		REG (a1)
		struct MinLetter *letter)
{
  static char buf1[30];

  if (letter)
    {
      /* zeige den Eintrag an. */
      sprintf (buf1, "%04d/%d (%s)", letter->letterYear, letter->letterNumber,
	       letter->letterDate);
      *array++ = buf1;
      *array++ = letter->Betreff;
      *array = letter->Kunde;
    }
  else
    {
      /* zeige die Titel-Zeile an. */
      *array++ = "\033bBrief";
      *array++ = "\033bBetreff";
      *array = "\033bKunde";
    }
  return (0);
}


/* Hooks für Auftragsliste */

static struct Hook LL_ConstructHook =
{
  {NULL, NULL}, (VOID *) LL_ConstructFunc, NULL, NULL};
static struct Hook LL_DestructHook =
{
  {NULL, NULL}, (VOID *) LL_DestructFunc, NULL, NULL};
static struct Hook LL_DisplayHook =
{
  {NULL, NULL}, (VOID *) LL_DisplayFunc, NULL, NULL};


/*
** Beim Verändern der Einstellungen für die Briefliste muß diese komplett
** neu aufgebaut werden. Der alte Inhalt wird gelöscht und je nach Modus
** die entsprechenden Einträge neu eingefügt.
**
** Es werden auch andere DisplayHooks verwendet, da verschiedene Daten
** angezeigt werden.
*/

void 
Redraw_LL_List (void)
{
  UWORD year, actnum;
  int i, j, active;
  LONG mode, cyear;
  struct MinLetter minletter;

  get (CY_LL_year, MUIA_Cycle_Active, &cyear);
  get (CY_LL_mode, MUIA_Cycle_Active, &mode);

  year = atoi (&CYA_LL_year_buffer[5 * cyear]);
  LL_SetYear (year);

  set (LV_LL_list, MUIA_List_Quiet, TRUE);

  DoMethod (LV_LL_list, MUIM_List_Clear);

  actnum = LL_GetCurrentLetterNumber ();
  active = -1;

  switch (mode)
    {
    case DISP_LL_ALL:
      for (j = 0, i = 0; i < LL_GetLetterCount (); i++)
	{
	  LL_GetLetter (i, &minletter);
	  if (minletter.letterNumber == actnum)
	    active = j;
	  DoMethod (LV_LL_list, MUIM_List_InsertSingle, &minletter,
	            MUIV_List_Insert_Bottom);
	  j++;
	}
      break;

    case DISP_LL_PRT:
      for (j = 0, i = 0; i < LL_GetLetterCount (); i++)
	{
	  LL_GetLetter (i, &minletter);
	  if (minletter.letterNumber == actnum)
	    active = j;
	  if (minletter.printDate[0] == 0)
	    {
	      DoMethod (LV_LL_list, MUIM_List_InsertSingle, &minletter,
	                MUIV_List_Insert_Bottom);
	      j++;
	    }
	}
      break;
    }

  /* j ist die Anzahl der Einträge in der MUI-Liste */

  if (j == 0)
    {
      set (LV_LL_list, MUIA_List_Quiet, FALSE);
    }
  else
    {
      set (LV_LL_list, MUIA_List_Active, active);
      set (LV_LL_list, MUIA_List_Quiet, FALSE);
      DoMethod (LV_LL_list, MUIM_List_Jump, MUIV_List_Jump_Active);
    }
}



APTR 
MUI_BuildLetterList (void)
{
#ifdef DEBUG
  printf ("in BuildLetterList()\n");
#endif
  return (VGroup,
	  Child, HGroup,
	  Child, CY_LL_year = Cycle (CYA_LL_year),
	  Child, CY_LL_mode = Cycle (CYA_LL_mode),
	  End,

	  Child, LV_LL_list = ListviewObject,
	  MUIA_Listview_List, ListObject,
	  InputListFrame,
	  MUIA_List_ConstructHook, &LL_ConstructHook,
	  MUIA_List_DestructHook, &LL_DestructHook,
	  MUIA_List_DisplayHook, &LL_DisplayHook,
	  MUIA_List_Format, "D=8,D=8,",
	  MUIA_List_Title, TRUE,
	  End,
	  End,

	  Child, HGroup,
	  Child, BT_LL_new = KeyButton ("Neu", 'n'),
	  Child, BT_LL_del = KeyButton ("Löschen", 'l'),
	  Child, BT_LL_copy = KeyButton ("Kopieren", 'k'),
	  Child, BT_LL_edit = KeyButton ("Edieren", 'e'),
	  End,

	  Child, ColGroup (2),
	  Child, BT_LL_prtlet = KeyButton ("Brief drucken", 'd'),
#ifndef SHOW_DVI
	  Child, BT_LL_prtlist = KeyButton ("Briefliste drucken", 'b'),
#else
	  Child, BT_LL_prtlist = KeyButton ("Briefvorschau...", 'b'),
#endif
	  End,
	  End);
}



/*********************************************************************
**
**
**  B R I E F
**
**
*********************************************************************/

APTR BT_LE_ok, BT_LE_cancel;
APTR WI_letter, REG_LE_pages;
APTR TX_LE_letnum, ST_LE_letdate, BT_LE_noaddr;
APTR BT_LE_customer, ST_LE_adr1, ST_LE_adr2, ST_LE_adr3, ST_LE_adr4;
APTR ST_LE_adr5, ST_LE_kundennr, ST_LE_zeichen;
APTR BT_LE_insert, BT_LE_change, BT_LE_delete;
APTR BT_LE_choose, BT_LE_command, BT_LE_preview;
APTR ST_LE_betreff, TXT_LE_text, ST_LE_date, BT_LE_today;

/* Befehle für Textfield */

APTR WI_letcomm, LV_LC_commands;

char *LVA_LC_commands[] =
{
  "{b}  - Fettschrift",
  "{i}  - Kursivschrift",
  "{n}  - Normalschrift",
  "{d}  - mit Punkten füllen",
  "{ }  - leer füllen",
  "{2}  - 2cm Freiraum",
  "{4}  - 4cm Freiraum",
  "{6}  - 6cm Freiraum",
  "{.2} - 2cm Punkte",
  "{.4} - 4cm Punkte",
  "{.6} - 6cm Punkte",
  "{-2} - 2cm Linie",
  "{-4} - 4cm Linie",
  "{-6} - 6cm Linie",
  "{ma} - Makro 1\0          ",
  "{mb} - Makro 2\0          ",
  "{mc} - Makro 3\0          ",
  "{md} - Makro 4\0          ",
  "{me} - Makro 5\0          ",
  "{@} -  TeX an/aus",
  NULL
};


/* weiter mit Brieffenster Sachen */

static char *LetterPages[] =
{"Kunde", "Inhalt", NULL};


/*
** Support-Funktionen für den "Brief"
**
** MUI verwaltet eine eigene Liste, die intern alle Daten aufnimmt
** und über eine DisplayFunc am Bildschirm angezeigt wird.
*/

void 
ReadLetterGadgets (void)
{
  STRPTR str;
  struct Window *window;
  struct Gadget *gadget;
  struct MinCustomer cust;

  get (ST_LE_letdate, MUIA_String_Contents, &str);
  LE_SetLetterDate (str);

  GetAttr (MUIA_Window_Window, WI_letter, (ULONG *) & window);
  set (REG_LE_pages, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Last);
  GetAttr (MUIA_Boopsi_Object, TXT_LE_text, (ULONG *) & gadget);
  if (window)
    {
      ULONG size;

      SetGadgetAttrs (gadget, window, NULL,
                      TEXTFIELD_ReadOnly, TRUE, TAG_DONE);
      GetAttr (TEXTFIELD_Size, gadget, &size);
      GetAttr (TEXTFIELD_Text, gadget, (ULONG *) & str);

      LE_SetLetterContents (str, size);
      SetGadgetAttrs (gadget, window, NULL,
                      TEXTFIELD_ReadOnly, FALSE, TAG_DONE);
    }

  get (ST_LE_date, MUIA_String_Contents, &str);
  LE_SetOrderDate (str);
  get (ST_LE_betreff, MUIA_String_Contents, &str);
  LE_SetBetreff (str);

  LE_GetLetterAddress (&cust);
  get (ST_LE_adr1, MUIA_String_Contents, &str);
  strcpy (cust.Adresse1, str);
  get (ST_LE_adr2, MUIA_String_Contents, &str);
  strcpy (cust.Adresse2, str);
  get (ST_LE_adr3, MUIA_String_Contents, &str);
  strcpy (cust.Adresse3, str);
  get (ST_LE_adr4, MUIA_String_Contents, &str);
  strcpy (cust.Adresse4, str);
  get (ST_LE_adr5, MUIA_String_Contents, &str);
  strcpy (cust.Adresse5, str);
  get (ST_LE_kundennr, MUIA_String_Contents, &str);
  cust.KundenNummer = atoi (str);
  get (ST_LE_zeichen, MUIA_String_Contents, &str);
  strcpy (cust.Zeichen, str);
  LE_SetLetterAddress (&cust);

}

/* von wo aus wurde das Fenster geöffnet, d.h.
** was passiert, wenn der Brief geschlossen wird
*/

UWORD closeLetterAction;


/*
** prüfe, ob der Brief abgebrochen werden darf. Gib evtl. einen Requester aus.
**
** Rückgabe:
**
** TRUE  - es darf abgebrochen werden.
** FALSE - nicht abbrechen, Brief weiter edieren
*/

BOOL 
LE_CheckAbort (BOOL endok)
{
  BOOL abort = TRUE;
  LONG isopen;
  char buffer[20];
  struct Window *window;
  struct Gadget *gadget;
  BOOL modified;
  ULONG size;
  STRPTR str, str2;

  LE_GetLetterNumber (buffer);
  get (WI_letter, MUIA_Window_Open, &isopen);

  if (isopen)
    {
      modified = FALSE;

      GetAttr (MUIA_Window_Window, WI_letter, (ULONG *) & window);
      set (REG_LE_pages, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Last);
      GetAttr (MUIA_Boopsi_Object, TXT_LE_text, (ULONG *) & gadget);
      if (window)
	{
	  SetGadgetAttrs (gadget, window, NULL,
	                  TEXTFIELD_ReadOnly, TRUE, TAG_DONE);
	  GetAttr (TEXTFIELD_Size, gadget, &size);
	  GetAttr (TEXTFIELD_Text, gadget, (ULONG *) & str);
	  SetGadgetAttrs (gadget, window, NULL,
	                  TEXTFIELD_ReadOnly, FALSE, TAG_DONE);

	  LE_GetLetterContents (&str2);
	  if (strncmp (str, str2, size))
	    modified = TRUE;
	}

      if ((LE_GetStatus () || modified) && !MUI_Request (app, WI_letter, 0,
                                                         "Brief abbrechen...",
							 "Verwerfen|Zurück",
				      "\033cDer Brief %s wurde verändert.\n"
			   "Wollen Sie Ihre Änderungen wirklich verwerfen?",
							 buffer))
	abort = FALSE;
    }
  if (abort && (closeCustomerAction == CCA_LETTER))
    {
      set (WI_customer, MUIA_Window_Title, "Adreßliste");
      closeCustomerAction = CCA_MAIN;
    }
  if (abort && (closeArticleAction == CAA_LETTER))
    {
      set (WI_article, MUIA_Window_Title, "Artikelliste");
      closeArticleAction = CAA_MAIN;
    }

  return (abort);
}


/* vor dem Öffnen werden die Daten aus dem Brief-Modul in die
** MUI-Oberfläche übertragen..
*/

void 
OpenLetterWin (void)
{
  struct MinCustomer mincust;
  struct MinLetter minletter;
  char buffer[40];
  STRPTR str;
  struct Window *window;
  struct Gadget *gadget;

  /* allgemeine Daten */
  LE_GetMinLetter (&minletter);
  set (ST_LE_letdate, MUIA_String_Contents, minletter.letterDate);
  LE_GetLetterNumber (buffer);
  set (TX_LE_letnum, MUIA_Text_Contents, buffer);
  set (ST_LE_betreff, MUIA_String_Contents, minletter.Betreff);

  /* Kundenseite */
  LE_GetLetterAddress (&mincust);
  set (ST_LE_adr1, MUIA_String_Contents, mincust.Adresse1);
  set (ST_LE_adr2, MUIA_String_Contents, mincust.Adresse2);
  set (ST_LE_adr3, MUIA_String_Contents, mincust.Adresse3);
  set (ST_LE_adr4, MUIA_String_Contents, mincust.Adresse4);
  set (ST_LE_adr5, MUIA_String_Contents, mincust.Adresse5);

  if (mincust.KundenNummer)
    {
      sprintf (buffer, "%d", mincust.KundenNummer);
      set (ST_LE_kundennr, MUIA_String_Contents, buffer);
    }
  else
    set (ST_LE_kundennr, MUIA_String_Contents, "");

  set (ST_LE_zeichen, MUIA_String_Contents, mincust.Zeichen);

  LE_GetOrderDate (buffer);
  set (ST_LE_date, MUIA_String_Contents, buffer);


  /* vor dem Textfield muß das Fenster geöffnet werden */

  set (WI_letter, MUIA_Window_Open, TRUE);
  set (WI_letcomm, MUIA_Window_Open, TRUE);
  set (REG_LE_pages, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Last);

  GetAttr (MUIA_Window_Window, WI_letter, (ULONG *) & window);
  GetAttr (MUIA_Boopsi_Object, TXT_LE_text, (ULONG *) & gadget);
  LE_GetLetterContents (&str);
  if (window)
    SetGadgetAttrs (gadget, window, NULL,
                    TEXTFIELD_Text, str, TEXTFIELD_Modified, FALSE, TAG_DONE);
}

/*
** Füge einen Text an in das Textfield ein.
*/

void 
Insert_LE_Text (STRPTR text)
{

  struct Window *window;
  struct Gadget *gadget;

  GetAttr (MUIA_Window_Window, WI_letter, (ULONG *) & window);
  GetAttr (MUIA_Boopsi_Object, TXT_LE_text, (ULONG *) & gadget);

  if (window)
    {
      set (REG_LE_pages, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Last);
      SetGadgetAttrs (gadget, window, NULL,
                      TEXTFIELD_InsertText, text, TAG_DONE);
    }
}


APTR 
MUI_BuildLetter (void)
{
#ifdef DEBUG
  printf ("in BuildLetter()\n");
#endif
  return (VGroup,
	  Child, HGroup,
	  Child, Label2 ("Briefnummer:"), Child, TX_LE_letnum = TextObject, TextFrame, MUIA_Background, MUII_TextBack, End,
	  Child, Label2 ("Briefdatum:"), Child, ST_LE_letdate = String ("01.01.1978", 16),
	  End,


	  Child, REG_LE_pages = RegisterGroup (LetterPages),
	  MUIA_Register_Frame, TRUE,

  /* Register "Kunde" */

	  Child, VGroup,
	  MUIA_HelpNode, "lettercust-register",

	  Child, VGroup, GroupFrameT ("Adreßfeld"),
	  Child, HGroup,
	  Child, BT_LE_customer = KeyButton ("Adresse auswählen...", 'a'),
	  Child, BT_LE_noaddr = KeyButton ("keine Adresse", 'e'),
	  End,
	  Child, ColGroup (2),
	  Child, KeyLabel2 ("Anrede:", 'r'),
	  Child, HGroup,
	  Child, ST_LE_adr1 = KeyString ("", 80, 'r'),
	  Child, KeyLabel2 ("Zeichen:", 'z'),
	  Child, ST_LE_zeichen = KeyString ("", 20, 'z'),
	  Child, KeyLabel2 ("Kundennr:", 'k'),
	  Child, ST_LE_kundennr = KeyString ("", 20, 'k'),
	  End,

	  Child, KeyLabel2 ("Adresse:", 'd'), Child, ST_LE_adr2 = KeyString ("", 80, 'd'),
	  Child, Label2 (""), Child, ST_LE_adr3 = String ("", 80),
	  Child, Label2 (""), Child, ST_LE_adr4 = String ("", 80),
	  Child, Label2 (""), Child, ST_LE_adr5 = String ("", 80),
	  End,
	  End,

	  Child, ColGroup (2), GroupFrameT ("weitere Daten"),
	  Child, KeyLabel2 ("'Ihre Nachricht vom':", 'i'), Child, HGroup,
	  Child, ST_LE_date = KeyString ("", 80, 'i'),
	  Child, BT_LE_today = KeyButton ("Heute", 'h'),
	  End,
	  Child, KeyLabel2 ("Betreff (Fileinfo):", 'b'),
	  Child, ST_LE_betreff = KeyString ("", 80, 'b'),

	  End,

	  End,

  /* Register "Inhalt" */

	  Child, VGroup,
	  MUIA_HelpNode, "lettercontents-register",

	  Child, TXT_LE_text = BoopsiObject,	/* MUI and Boopsi tags mixed */
	  InputListFrame,
	  MUIA_Boopsi_Class, TextFieldClass,
	  MUIA_Boopsi_Smart, TRUE,
	  MUIA_Boopsi_MinWidth, 20,	/* boopsi objects don't know */
	  MUIA_Boopsi_MinHeight, 20,	/* their sizes, so we help   */
	  ICA_TARGET, ICTARGET_IDCMP,	/* needed for notification */
	  TEXTFIELD_Text, (ULONG) "",
	  TEXTFIELD_ClipStream, clip_handle,
	  TEXTFIELD_UndoStream, undo_handle,
	  End,

	  Child, HGroup,
	  Child, BT_LE_choose = KeyButton ("Artikel einfügen...", 'a'),
	  Child, BT_LE_command = KeyButton ("{} Befehle...", 'b'),
	  Child, BT_LE_preview = KeyButton ("Vorschau...", 'v'),

	  End,

	  End,
	  End,

	  Child, HGroup,
	  Child, BT_LE_ok = KeyButton ("OK", 'o'),
	  Child, BT_LE_cancel = KeyButton ("Abbruch", 'u'),
	  End,
	  End);
}


/*
** nachdem die MUI aufgebaut ist, müssen noch einige Methoden eingebaut
** werden. Diese Funktion wird vom Hauptprogramm aufgerufen.
*/

void 
DoLetterMethods (void)
{
  /* Brief */

//   DoMethod(WI_letter,MUIM_Notify,MUIA_Window_InputEvent,"rawkey -capslock -shift right",REG_LE_pages,3,MUIM_Set,MUIA_Group_ActivePage,MUIV_Group_ActivePage_Next);
  //   DoMethod(WI_letter,MUIM_Notify,MUIA_Window_InputEvent,"rawkey -capslock -shift left",REG_LE_pages,3,MUIM_Set,MUIA_Group_ActivePage,MUIV_Group_ActivePage_Prev);
  DoMethod (WI_letter, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_LE_CANCEL);
  DoMethod (BT_LE_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_OK);
  DoMethod (BT_LE_cancel, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_CANCEL);
  DoMethod (BT_LE_customer, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_CUSTOMER);
  DoMethod (BT_LE_noaddr, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_NOADDR);
  DoMethod (BT_LE_today, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_TODAY);
  DoMethod (BT_LE_choose, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_CHOOSE);
  DoMethod (BT_LE_command, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_COMMAND);
  DoMethod (BT_LE_preview, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LE_PREVIEW);
  DoMethod (WI_letter, MUIM_Window_SetCycleChain, ST_LE_adr1, ST_LE_zeichen, ST_LE_kundennr, ST_LE_adr2, ST_LE_adr3, ST_LE_adr4, ST_LE_adr5,
	    ST_LE_date, ST_LE_betreff, TXT_LE_text, NULL);

  /* Befehlsfenster für Brief */

  DoMethod (WI_letcomm, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, WI_letcomm, 3, MUIM_Set, MUIA_Window_Open, FALSE);
  DoMethod (WI_letcomm, MUIM_Notify, MUIA_Window_Open, TRUE, WI_letcomm, 3, MUIM_Set, MUIA_Window_ActiveObject, LV_LC_commands);
  DoMethod (LV_LC_commands, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app, 2, MUIM_Application_ReturnID, ID_LC_OK);


  /* Briefliste */

  DoMethod (WI_letlist, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, WI_letlist, 3, MUIM_Set, MUIA_Window_Open, FALSE);
  DoMethod (WI_letlist, MUIM_Notify, MUIA_Window_Open, TRUE, WI_letlist, 3, MUIM_Set, MUIA_Window_ActiveObject, LV_LL_list);
  DoMethod (LV_LL_list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_LL_LIST);
  DoMethod (LV_LL_list, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app, 2, MUIM_Application_ReturnID, ID_LL_EDITLETTER);
  DoMethod (BT_LL_new, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_NEWLETTER);
  DoMethod (BT_LL_del, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_DELLETTER);
  DoMethod (BT_LL_copy, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_COPYLETTER);
  DoMethod (BT_LL_edit, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_EDITLETTER);
  DoMethod (BT_LL_prtlet, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_PRINTLETTER);
  DoMethod (BT_LL_prtlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LL_PRINTLIST);
  DoMethod (CY_LL_year, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_LL_SELECTYEAR);
  DoMethod (CY_LL_mode, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_LL_SELECTFILTER);
  set (CY_LL_year, MUIA_Cycle_Active, LL_GetCurrentYearNumber ());
  set (CY_LL_mode, MUIA_Cycle_Active, CO_GetLetterMode ());
}


/*
** Falls InputEvents für die Brief(liste) ankommen, werden sie über
** diese Funktion ausgewertet.
*/


void 
HandleLetterEvents (ULONG event)
{
  /* Briefiste */
  switch (event)
    {
    case ID_LL_LIST:
      /* Benutzer wählt einen Brief aus der Liste aus */
      {
	struct MinLetter *active;

	DoMethod (LV_LL_list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
	          &active);
	if (active)
	  {
	    LL_SetCurrentLetterNumber (active->letterNumber);
	  }
      }
      break;

    case ID_LL_SELECTYEAR:
    case ID_LL_SELECTFILTER:
      /* Jahrgang, Filter neu eingestellt: Liste neu aufbauen */
      Redraw_LL_List ();

      /* in alten Jahrgängen keine neuen Briefe erstellen lassen */
      if (LL_GetCurrentYear () < GetThisYear ())
	set (BT_LL_new, MUIA_Disabled, TRUE);
      else
	set (BT_LL_new, MUIA_Disabled, FALSE);
      break;

    case ID_LL_NEWLETTER:
      {
	char buf[16];

	if (LE_CheckAbort (FALSE))
	  {
	    closeLetterAction = CLA_MAIN_NEW;

	    /* Brief intern neu aufbauen */
	    LE_NewLetter ();
	    sprintf (buf, "%04d/%d", LL_GetCurrentYear (),
	             LL_GetNextLetterNumber ());
	    LE_SetLetterNumber (buf);
	    OpenLetterWin ();
	  }
      }
      break;

    case ID_LL_DELLETTER:
      /* aktuelle Brief löschen */
      {
	struct MinLetter *active;

	DoMethod (LV_LL_list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
	          &active);
	if (active)
	  {
	    struct MinLetter comp;
	    BOOL del = TRUE, abort = FALSE;

	    LE_GetMinLetter (&comp);
	    if ((active->letterYear == comp.letterYear) &&
		(active->letterNumber == comp.letterNumber))
	      abort = TRUE;

	    if (abort && !LE_CheckAbort (FALSE))
	      del = FALSE;
	    if (abort && del)
	      {
		set (WI_letcomm, MUIA_Window_Open, FALSE);
		set (WI_letter, MUIA_Window_Open, FALSE);
	      }

	    if (del)
	      {
		if (MUI_Request (app, WI_letlist, 0, "Brief löschen...",
		                                     "Löschen|Abbruch",
				 "\033cWollen Sie den Brief\n"
				 "'%04ld/%ld  %s'\nwirklich löschen?",
		 active->letterYear, active->letterNumber, active->Betreff))
		  {
		    LL_DelLetter ();
		    Redraw_LL_List ();
		  }
	      }
	  }
      }
      break;

    case ID_LL_COPYLETTER:
      /* aktuellen Brief kopieren und edieren */
      {
	char buf[16];
	struct MinLetter *active;

	if (LE_CheckAbort (FALSE))
	  {
	    closeLetterAction = CLA_MAIN_NEW;

	    DoMethod (LV_LL_list, MUIM_List_GetEntry,
	              MUIV_List_GetEntry_Active, &active);
	    if (active)
	      {
		/* Brief einlesen */
		if (!LL_LoadLetter (active))
		  {
		    /* Brieffenster vorbereiten */
		    sprintf (buf, "%04d/%d", LL_GetCurrentYear (),
			     LL_GetNextLetterNumber ());
		    LE_SetLetterNumber (buf);
		    LE_SetPrintDate ("");
		    OpenLetterWin ();
		  }
		else
		  {
		    MUI_Request (app, WI_letlist, 0, "Fehlermeldung", "OK",
		                 "Brief laden\n%s", LL_GetErrorMsg ());
		  }
	      }
	  }
      }
      break;

    case ID_LL_EDITLETTER:
      /* aktuellen Brief edieren */
      {
	struct MinLetter *active;

	if (LE_CheckAbort (FALSE))
	  {
	    closeLetterAction = CLA_MAIN_EDIT;

	    DoMethod (LV_LL_list, MUIM_List_GetEntry,
	              MUIV_List_GetEntry_Active, &active);
	    if (active)
	      {
		/* Brief einlesen */
		if (!LL_LoadLetter (active))
		  {
		    /* Brieffenster vorbereiten */
		    OpenLetterWin ();
		  }
		else
		  {
		    MUI_Request (app, WI_letlist, 0, "Fehlermeldung", "OK",
		                 "Brief laden\n%s", LL_GetErrorMsg ());
		  }
	      }
	  }
      }
      break;

    case ID_LL_PRINTLETTER:
      /* Brief drucken */
      {
	struct MinLetter *active;
	STRPTR name;
	struct Screen *scr;

	DoMethod (LV_LL_list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
	          &active);
	if (active)
	  {
	    /* Brief einlesen */
	    if (!LL_LoadLetter (active))
	      {
		struct MinCustomer cust;
		char refdate[12], letdate[12], number[12];
		STRPTR str;

		LE_GetLetterAddress (&cust);
		LE_GetOrderDate (refdate);
		LE_GetLetterDate (letdate);
		LE_GetLetterNumber (number);
		get (WI_main, MUIA_Window_Screen, &scr);
		name = GetPublicScreenName (scr);

#ifndef OUTPUTWIN
		set (app, MUIA_Application_Sleep, TRUE);
#endif
		if (!CheckSum (Benutzer, oldchecksum))
		  LE_GetDummyLetterContents (&str);
		else
		  LE_GetLetterContents (&str);

		if (!P_PrintLetter (name, &cust, number, letdate, refdate,
		                    str, FALSE))
		  {
		    /* Brief gedruckt. Dies auch vermerken */
		    struct MinLetter minletter;
		    char date[12];

		    date[0] = 0;
		    CorrectDate (date);
		    LE_SetPrintDate (date);
		    LE_GetMinLetter (&minletter);
		    if (LL_SaveLetter (&minletter))
		      MUI_Request (app, WI_letlist, 0, "Fehlermeldung", "OK",
		                   "Brief speichern\n%s", LL_GetErrorMsg ());
		    LL_ChangeLetter (&minletter);
		    Redraw_LL_List ();
		  }
#ifndef OUTPUTWIN
		set (app, MUIA_Application_Sleep, FALSE);
#endif
	      }
	    else
	      {
		MUI_Request (app, WI_letlist, 0, "Fehlermeldung", "OK",
		             "Brief laden\n%s", LL_GetErrorMsg ());
	      }
	  }
      }
      break;

    case ID_LL_PRINTLIST:
      /* Briefliste drucken */
#ifdef SHOW_DVI
      {
	struct MinLetter *active;
	STRPTR name;
	struct Screen *scr;

	DoMethod (LV_LL_list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
	          &active);
	if (active)
	  {
	    /* Brief einlesen */
	    if (!LL_LoadLetter (active))
	      {
		struct MinCustomer cust;
		char letdate[12], refdate[12], number[12];
		STRPTR str;

		LE_GetLetterAddress (&cust);
		LE_GetOrderDate (refdate);
		LE_GetLetterDate (letdate);
		LE_GetLetterNumber (number);
		get (WI_main, MUIA_Window_Screen, &scr);
		name = GetPublicScreenName (scr);

#ifndef OUTPUTWIN
		set (app, MUIA_Application_Sleep, TRUE);
#endif
		if (!CheckSum (Benutzer, oldchecksum))
		  LE_GetDummyLetterContents (&str);
		else
		  LE_GetLetterContents (&str);

		if (!P_PrintLetter (name, &cust, number, letdate, refdate,
		    str, TRUE))
		  {
		  }
#ifndef OUTPUTWIN
		set (app, MUIA_Application_Sleep, FALSE);
#endif
	      }
	    else
	      {
		MUI_Request (app, WI_letlist, 0, "Fehlermeldung", "OK",
		             "Brief laden\n%s", LL_GetErrorMsg ());
	      }
	  }
      }

#endif
      break;

      /* Brief */

    case ID_LE_CUSTOMER:
      /* Kunden auswählen -> in Kundenliste gehen */
      {
	struct Customer cust;
	if (C_CheckAbort (FALSE))
	  {
	    closeCustomerAction = CCA_LETTER;
	    LE_GetLetterAddress ((struct MinCustomer *) &cust);
	    InitCustomerWin (cust.KundenNummer);
	    set (WI_customer, MUIA_Window_Title, "Adresse für Brief");
	    set (WI_customer, MUIA_Window_Open, TRUE);
	  }
      }
      break;

    case ID_LE_NOADDR:
      /* kein Kunde -> ohne Adreßfeld */
      {
	struct MinCustomer empty =
	{"", "", "", "", "", "", 0};
	LE_SetLetterAddress (&empty);
	set (ST_LE_adr1, MUIA_String_Contents, "");
	set (ST_LE_adr2, MUIA_String_Contents, "");
	set (ST_LE_adr3, MUIA_String_Contents, "");
	set (ST_LE_adr4, MUIA_String_Contents, "");
	set (ST_LE_adr5, MUIA_String_Contents, "");

	set (ST_LE_kundennr, MUIA_String_Contents, "");
	set (ST_LE_zeichen, MUIA_String_Contents, "");

	set (ST_LE_date, MUIA_String_Contents, "");
      }
      break;

    case ID_LE_TODAY:
      /* Datum für "Ihre Nachricht vom" auf heutiges Datum setzen */
      {
	char date[20];

	date[0] = 0;
	CorrectDate (date);
	set (ST_LE_date, MUIA_String_Contents, date);
      }
      break;

    case ID_LE_PREVIEW:
      /* Brief ansehen */
      {
	STRPTR name;
	struct Screen *scr;
	struct MinCustomer cust;
	STRPTR str;
	char letdate[12], refdate[12], number[12];

	ReadLetterGadgets ();

	LE_GetLetterAddress (&cust);
	LE_GetOrderDate (refdate);
	LE_GetLetterDate (letdate);
	LE_GetLetterNumber (number);
	get (WI_main, MUIA_Window_Screen, &scr);
	name = GetPublicScreenName (scr);

#ifndef OUTPUTWIN
	set (app, MUIA_Application_Sleep, TRUE);
#endif
	if (!CheckSum (Benutzer, oldchecksum))
	  LE_GetDummyLetterContents (&str);
	else
	  LE_GetLetterContents (&str);

	if (!P_PrintLetter (name, &cust, number, letdate, refdate, str, TRUE))
	  {
	  }
#ifndef OUTPUTWIN
	set (app, MUIA_Application_Sleep, FALSE);
#endif
      }
      break;

    case ID_LE_CHOOSE:
      /* Artikel auswählen -> in Artikelliste gehen */
      if (A_CheckAbort (FALSE))
	{
	  closeArticleAction = CAA_LETTER;
	  InitArticleWin ();
	  set (REG_A_mode, MUIA_Group_ActivePage, MUIV_Group_ActivePage_First);
	  set (WI_article, MUIA_Window_Open, TRUE);
	  set (WI_article, MUIA_Window_Title, "Artikel für Brief");
	}
      break;

    case ID_LE_COMMAND:
      /* Befehl auswählen */
      set (WI_letcomm, MUIA_Window_Open, TRUE);
      break;

    case ID_LC_OK:
      /* Befehl auswählt -> in Brief einfügen */
      {
	ULONG num;
	struct Window *window;
	struct Gadget *gadget;
	char buf[10];
	char *s, *t;

	get (LV_LC_commands, MUIA_List_Active, &num);
	s = LVA_LC_commands[num];
	t = buf;
	while (*s && *s != '}')
	  {
	    *t++ = *s++;
	  }
	*t++ = '}';
	*t = '\0';

	Insert_LE_Text (buf);
	set (WI_letter, MUIA_Window_Activate, TRUE);
	GetAttr (MUIA_Window_Window, WI_letter, (ULONG *) & window);
	GetAttr (MUIA_Boopsi_Object, TXT_LE_text, (ULONG *) & gadget);
	ActivateGadget (gadget, window, NULL);
#if 0
	set (WI_letcomm, MUIA_Window_Open, FALSE);
#endif
      }
      break;

    case ID_LE_OK:
      /* Brief speichern */
      {
	struct MinLetter minletter;

	ReadLetterGadgets ();

	LE_GetMinLetter (&minletter);

	if (LL_SaveLetter (&minletter))
	  MUI_Request (app, WI_letter, 0, "Fehlermeldung", "OK",
	               "Brief speichern\n%s", LL_GetErrorMsg ());
	else
	  {
	    switch (closeLetterAction)
	      {
	      case CLA_MAIN_EDIT:
		LL_SetYear (minletter.letterYear);
		LL_SetCurrentLetterNumber (minletter.letterNumber);
		LL_ChangeLetter (&minletter);
		Redraw_LL_List ();
		break;

	      case CLA_MAIN_NEW:
		/* neuen Eintrag in die Liste einfügen */
		LL_SetYear (minletter.letterYear);
		LL_NewLetter (&minletter);
		Redraw_LL_List ();
		break;
	      }
	    set (WI_letcomm, MUIA_Window_Open, FALSE);
	    set (WI_letter, MUIA_Window_Open, FALSE);
	  }
      }
      break;


    case ID_LE_CANCEL:
      if (LE_CheckAbort (FALSE))
	{
	  switch (closeLetterAction)
	    {
	    case CLA_MAIN_EDIT:
	    case CLA_MAIN_NEW:
	      break;
	    }
	  set (WI_letcomm, MUIA_Window_Open, FALSE);
	  set (WI_letter, MUIA_Window_Open, FALSE);
	}
      break;
    }
}
