/*
** MUI-Main.c - Das Hauptprogramm und die ganze Steuerung von 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"

struct Library *MUIMasterBase = NULL;

struct Library *TextFieldBase = NULL;
Class *TextFieldClass;

struct Library *IFFParseBase = NULL;
struct ClipboardHandle *clip_handle = NULL;
struct ClipboardHandle *undo_handle = NULL;


#ifdef __SASC
void __regargs __chkabort (void);
void __regargs 
__chkabort (void)
{
}
#endif


#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif


LONG __stack = 8192;


/*********************************************************************
**
**
**  A L L G E M E I N E S
**
**
*********************************************************************/


STRPTR ProgVersion = VERSTAG;

/* maximale Länge eines Adreß-Eintrags bzw. der Telefonnummer
** man muß jedoch noch das Null-Byte hinzurechnen!
*/

APTR app, WI_customerprint, WI_articleprint, WI_customer, WI_order;
APTR WI_invoice, WI_article, WI_main;
APTR WI_config, WI_letlist, WI_invlist, WI_ordlist;

/* Revision in einem Byte speichern */

UBYTE revision = REVISION;

#define MAX_NAME_LENGTH 80


/* Gadget und Menü ID-Nummern */

enum
  {
    ID_QUIT = 1,	/* Programm beenden */
    ID_ABSQUIT = 2,	/* test! *//* Programm beenden */

/* Hauptfenster (Dock) */
    ID_M_LETLIST,	/* Angebotsfenster öffnen */
    ID_M_INVLIST,	/* Rechnungsliste öffnen */
    ID_M_ORDLIST,	/* Auftragsliste öffnen */
    ID_M_CUSTLIST,	/* Adreßliste öffnen */
    ID_M_ARTLIST,	/* Artikelliste öffnen */
    ID_M_LABEL,		/* Etiketten-Fenster öffnen */

/* Menü */
    ID_MEN_LABEL,	/* Etikettenfenster öffnen */
    ID_MEN_PREFS,	/* eigene Adresse ändern */
    ID_MEN_HELP,	/* Hilfe starten */
    ID_MEN_HELP_INDEX,	/* Hilfsindex starten */
    ID_MEN_HELP_NEWS,	/* Hilfe über Neuigkeiten starten */
    ID_ABOUT,		/* über das tolle Programm... */


/* Kundenliste */
    ID_C_OK,		/* Änderung übernehmen */
    ID_C_OKcheck,	/* Änderung übernehmen per Doppelklick */
    ID_C_CANCEL,	/* Abbruch */
    ID_C_LIST,		/* Kundenliste Listview */
    ID_C_INSERT,	/* neuen Kunden in Liste einfügen */
    ID_C_CHANGE,	/* Kunden in Liste ändern */
    ID_C_DELETE,	/* Kunden aus Liste löschen */
    ID_C_CLEAR,		/* lösche alle Eingabegadgets im Eingabemodus */
    ID_C_INPUT,		/* Name wurde verändert -> Liste dorthin bewegen */
    ID_C_SCLEAR,	/* lösche alle Eingabegadgets im Suchmodus */
    ID_C_SEARCH,	/* suche alle Kunden nach dem Suchkriterium */
    ID_C_SALL,		/* alle Kunden wieder darstellen */
    ID_C_POPINSERT,	/* neue Kategorie in Liste einfügen */
    ID_C_POPCHANGE,	/* Kategorie in Liste ändern */
    ID_C_POPDELETE,	/* Kategorie aus Liste löschen */
    ID_C_LISTMODE,	/* Popupstring für Listview wurde verändert */

/* Kundenlistendruck */
    ID_CP_OK,		/* Liste drucken */

/* Artikelliste */
    ID_A_OK,		/* Änderung übernehmen */
    ID_A_OKcheck,	/* Änderung übernehmen per Doppelklick */
    ID_A_CANCEL,	/* Abbruch */
    ID_A_LISTMODE,	/* Popupstring für Listview wurde verändert */
    ID_A_LIST,		/* Artikelliste Listview */
    ID_A_INSERT,	/* neuen Artikel in Liste einfügen */
    ID_A_CHANGE,	/* Artikel in Liste ändern */
    ID_A_DELETE,	/* Artikel aus Liste löschen */
    ID_A_CLEAR,		/* lösche alle Eingabegadgets */
    ID_A_TODAY,		/* heutiges Datum in Stringgadget eintragen */
    ID_A_INPUT,		/* Preis(e) wurden verändert. Neu anzeigen */
    ID_A_SCLEAR,	/* lösche alle Eingabegadgets im Suchmodus */
    ID_A_SEARCH,	/* suche alle Artikel nach dem Suchkriterium */
    ID_A_SALL,		/* alle Artikel wieder darstellen */
    ID_A_BRUTTONETTO,	/* Eingabemodus Brutto oder Netto */
    ID_A_POPINSERT,	/* neue Kategorie in Liste einfügen */
    ID_A_POPCHANGE,	/* Kategorie in Liste ändern */
    ID_A_POPDELETE,	/* Kategorie aus Liste löschen */

/* Kundenlistendruck */
    ID_AP_OK,		/* Liste drucken */

/* Konfiguration */
    ID_CO_OK,		/* Konfiguration speichern */
    ID_CO_CANCEL,	/* Konfiguration abbrechen */
    ID_CO_OFFSET,	/* Druckeroffsets testen */
    ID_CO_MEN_LOAD,	/* Konfiguration laden */
    ID_CO_MEN_SAVE,	/* Konfiguration speichern */

/* Etikettenfenster */
    ID_E_OK,		/* Fertig, Fenster zu */
    ID_E_PRINT,		/* Etikett drucken */
    ID_E_CUSTOMER,	/* Kunde für Etikett wählen */
    ID_E_PRINTVISIT,	/* Visitenkarte drucken */
  };

static struct NewMenu MenuData1[] =
{
  {NM_TITLE, (STRPTR) MENU_MAIN_PROJECT, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_CONFIG, (STRPTR) MENUKEY_MAIN_CONFIG, 0, 0, (APTR) ID_MEN_PREFS},
  {NM_ITEM, NM_BARLABEL, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_ABOUT, (STRPTR) MENUKEY_MAIN_ABOUT, 0, 0, (APTR) ID_ABOUT},
  {NM_ITEM, NM_BARLABEL, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_QUIT, (STRPTR) MENUKEY_MAIN_QUIT, 0, 0, (APTR) ID_ABSQUIT},

  {NM_TITLE, (STRPTR) MENU_MAIN_HELP, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_STARTHELP, (STRPTR) MENUKEY_MAIN_STARTHELP, 0, 0, (APTR) ID_MEN_HELP},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_INDEX, (STRPTR) MENUKEY_MAIN_INDEX, 0, 0, (APTR) ID_MEN_HELP_INDEX},
  {NM_ITEM, (STRPTR) MENUITEM_MAIN_NEWS, (STRPTR) MENUKEY_MAIN_NEWS, 0, 0, (APTR) ID_MEN_HELP_NEWS},

  {NM_END, NULL, 0, 0, 0, (APTR) 0},
};



/* private Funktionen */

static void Quit (APTR app, char *str, char *str2);

static char muierrbuf[20];

/* Cycle-Array mit den Mehrwertsteuersätzen, die für allgemeine Sachen
** benötigt werden. Für die Rechnung und den Auftrag gibt es getrennte Werte!
*/

static char CYA_MwSt1_buffer[12];	/* Puffer für MwSt-Strings */
static char CYA_MwSt2_buffer[12];	/* Puffer für MwSt-Strings */
char *CYA_MwSt[] =
{CYA_MwSt1_buffer, CYA_MwSt2_buffer, NULL};

char *CYA_BruttoNetto[] =
{(STRPTR) MSG_STRING_NETTO, (STRPTR) MSG_STRING_BRUTTO, NULL};

/* zum Barverkauf gibt es einen Pseudo-Kunden */

struct MinCustomer cashcust =
{
  "", "", "", "", "", "", 0
};





/*********************************************************************
**
**
**  A R T I K E L L I S T E
**
**
*********************************************************************/

/* Gadgets des Artikeldrucks */

static APTR BT_AP_ok, BT_AP_cancel, RA_AP_mode;

static char *CustomerModePages[] =
{(STRPTR) MSG_ADDRESS_MODE_PAGE_INPUT,
 (STRPTR) MSG_ADDRESS_MODE_PAGE_SEARCH, NULL};


/* Gadgets der Artikelliste */

static APTR LV_A_list;
static APTR BT_A_print, BT_A_popinsert, BT_A_popchange, BT_A_popdelete;
static APTR BT_A_insert, BT_A_change, BT_A_delete, BT_A_clear;
static APTR BT_A_today, ST_A_menge, ST_A_VGLeinzel, ST_A_article;
static APTR ST_A_number, BT_A_clear;
static APTR REG_A_inputmode, BT_A_search, BT_A_sall, ST_A_snumber;
static APTR ST_A_sarticle;
static APTR ST_A_sbezeichnung, BT_A_sclear;
static APTR ST_A_VKeinzel, ST_A_EKeinzel, ST_A_EKversand;
static APTR BT_A_ok, BT_A_cancel, TX_A_brutto, ST_A_zuschlag;
static APTR CY_A_mode, CY_A_mwst, ST_A_date, ST_A_firma, ST_A_note;
static APTR POP_A_mode, LV_A_pop, ST_A_pop;
APTR REG_A_mode;


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

static char *artPages[] =
{(STRPTR) MSG_PAGE_ARTICLE, (STRPTR) MSG_PAGE_PRICE,
 (STRPTR) MSG_PAGE_INFORMATION, NULL};

UWORD closeArticleAction;


/*
** prüfe, ob die Artikelliste abgebrochen werden darf. Gib evtl. Requester aus.
**
** endok - TRUE wenn mit "Ok" button beendet werden soll, FALSE bei Abort
**
** Rückgabe:
**
** TRUE  - es darf abgebrochen werden.
** FALSE - nicht abbrechen, Rechnung weiter edieren
*/
struct Article emptyarticle =
{
  0.0, 1, "", "", 1, "", 0.0, 0.0, 0.0, "", "", ""
};

BOOL 
A_CheckAbort (BOOL endok)
{
  BOOL abort = TRUE;
  LONG isopen;
  struct Article article;
  LONG num;
  STRPTR str;
  BOOL diff = FALSE;
  float betrag;

  get (WI_article, MUIA_Window_Open, &isopen);
  if (isopen)
    {
      if (A_GetCurrentItem (&article) != ERR_ART_LISTEMPTY)
	{
	  get (ST_A_pop, MUIA_String_Contents, &str);
	  if (strcmp (str, article.Kategorie))
	    article = emptyarticle;
	}
      else
	{
	  article = emptyarticle;
	}

      get (ST_A_number, MUIA_String_Contents, &str);
      diff |= (strcmp (article.Artikelnummer, str) != 0);
      get (ST_A_article, MUIA_String_Contents, &str);
      diff |= (strcmp (article.Bezeichnung, str) != 0);
      get (CY_A_mwst, MUIA_Cycle_Active, &num);
      diff |= (article.Preistabelle != num + 1);

      get (ST_A_VKeinzel, MUIA_String_Contents, &str);
      betrag = ScanMonetary (str);

      /* Bruttobetrag in Netto wandeln */
      if (CO_GetArticleMwStMode ())
	{
	  betrag = Brutto2Netto (betrag, CO_GetMwSt (num + 1));
	}
      diff |= (abs (article.Betrag - betrag) > 0.01);

      get (ST_A_VGLeinzel, MUIA_String_Contents, &str);
      betrag = ScanMonetary (str);

      /* Bruttobetrag in Netto wandeln */
      if (CO_GetArticleMwStMode ())
	{
	  betrag = Brutto2Netto (betrag, CO_GetMwSt (num + 1));
	}
      diff |= (article.VGLBetrag != betrag);

      get (ST_A_EKeinzel, MUIA_String_Contents, &str);
      diff |= (article.EKBetrag != ScanMonetary (str));
      get (ST_A_EKversand, MUIA_String_Contents, &str);
      diff |= (article.EKVersand != ScanMonetary (str));
      get (ST_A_firma, MUIA_String_Contents, &str);
      diff |= (strcmp (article.Lieferfirma, str) != 0);
      get (ST_A_note, MUIA_String_Contents, &str);
      diff |= (strcmp (article.Notiz, str) != 0);
      diff = FALSE;
      if (diff && !MUI_Request (app, WI_article, 0,
                                STRING (MSG_ABORTARTICLE_REQ_TITLE),
				STRING (MSG_ABORTARTICLE_REQ_BUTTONS),
				STRING (MSG_ABORTARTICLE_REQ_BODY)))
	{
	  abort = FALSE;
	}

      if (!endok && abort)
	{
	  /* abort */
	  if (A_GetStatus () && !MUI_Request (app, WI_article, 0,
	                              STRING (MSG_ABORTARTICLES_REQ_TITLE),
				      STRING (MSG_ABORTARTICLE_REQ_BUTTONS),
				      STRING (MSG_ABORTARTICLES_REQ_BODY)))
	    abort = FALSE;
	}
    }
  return (abort);
}


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

SAVEDS ASM LONG 
A_StrObjFunc (REG (a2) Object * pop, REG (a1) Object * str)
{
  char *x, *s;
  int i;

  get (str, MUIA_String_Contents, &s);

  for (i = 0;; i++)
    {
      DoMethod (pop, MUIM_List_GetEntry, i, &x);
      if (!x)
	{
	  set (pop, MUIA_List_Active, MUIV_List_Active_Off);
	  break;
	}
      else if (!stricmp (x, s))
	{
	  set (pop, MUIA_List_Active, i);
	  break;
	}
    }
  return (TRUE);
}


SAVEDS ASM VOID 
A_ObjStrFunc (REG (a2) Object * pop, REG (a1) Object * str)
{
  char *x;
  DoMethod (pop, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &x);
  set (str, MUIA_String_Contents, x);
  /* notify string input */
  DoMethod (app, MUIM_Application_ReturnID, ID_A_LISTMODE);
  set (WI_article, MUIA_Window_ActiveObject, LV_A_list);
}

SAVEDS ASM VOID 
A_WindowFunc (REG (a2) Object * pop, REG (a1) Object * win)
{
  set (win, MUIA_Window_DefaultObject, pop);
}

SAVEDS ASM APTR 
A_ConstructFunc (REG (a1)
		 struct Article *article,
		 REG (a2)
		 void *mempool)
{
  struct Article *newitem;

  if (newitem = LibAllocPooled (mempool, sizeof (struct Article)))
    {
      newitem->Betrag = article->Betrag;
      newitem->EKBetrag = article->EKBetrag;
      newitem->EKVersand = article->EKVersand;
      newitem->VGLBetrag = article->VGLBetrag;
      newitem->Preistabelle = article->Preistabelle;
      newitem->Menge = article->Menge;
      strcpy (newitem->Artikelnummer, article->Artikelnummer);
      strcpy (newitem->Bezeichnung, article->Bezeichnung);
      strcpy (newitem->Lieferfirma, article->Lieferfirma);
      strcpy (newitem->Kategorie, article->Kategorie);
      strcpy (newitem->Notiz, article->Notiz);
    }

  return ((APTR) newitem);
}

SAVEDS ASM VOID 
A_DestructFunc (REG (a1) struct Article * article,
		REG (a2) void *mempool)
{
  LibFreePooled (mempool, article, sizeof (struct Article));
}

SAVEDS ASM LONG 
A_DisplayFunc (REG (a2)
	       char **array,
	       REG (a1)
	       struct Article *article)
{
  static char buf1[12], buf2[24];


  if (article)
    {
      /* zeige den Eintrag an. */

      *array++ = article->Artikelnummer;
      *array++ = article->Bezeichnung;

      sprintf (buf1, "\033r");
      PrintMonetary (&buf1[2], article->Menge);
      *array++ = buf1;

      strcpy (buf2, "\033r");
      DisplayBetrag (&buf2[2], article->Betrag,
                     CO_GetMwSt (article->Preistabelle), 1);
      *array = buf2;
    }
  else
    {
      /* zeige die Titel-Zeile an. */
      *array++ = STRING (MSG_ARTICLE_LIST_NUMBER);
      *array++ = STRING (MSG_ARTICLE_LIST_DESCRIPTION);
      *array++ = "\033bMenge";
      *array = STRING (MSG_ARTICLE_LIST_BRUTTO);
    }

  return (0);
}

/* Hooks für Artikelliste */

static struct Hook A_StrObjHook =
{
  {NULL, NULL}, (VOID *) A_StrObjFunc, NULL, NULL};
static struct Hook A_ObjStrHook =
{
  {NULL, NULL}, (VOID *) A_ObjStrFunc, NULL, NULL};
static struct Hook A_WindowHook =
{
  {NULL, NULL}, (VOID *) A_WindowFunc, NULL, NULL};

static struct Hook A_ConstructHook =
{
  {NULL, NULL}, (VOID *) A_ConstructFunc, NULL, NULL};
static struct Hook A_DestructHook =
{
  {NULL, NULL}, (VOID *) A_DestructFunc, NULL, NULL};
static struct Hook A_DisplayHook =
{
  {NULL, NULL}, (VOID *) A_DisplayFunc, NULL, NULL};

/*
** Beim Verändern der Einstellungen für die Artikelliste muß diese komplett
** neu aufgebaut werden. Der alte Inhalt wird gelöscht und je nach Modus
** die entsprechenden Einträge neu eingefügt.
*/

static void 
Redraw_A_List (void)
{
  struct Article article;
  int i, act;
  STRPTR str;
  char buf[80];

  set (LV_A_list, MUIA_List_Quiet, TRUE);
  get (ST_A_pop, MUIA_String_Contents, &str);
  strcpy (buf, str);

  DoMethod (LV_A_list, MUIM_List_Clear);

  act = 0;
  A_GetCurrentItem (&article);
  if (!stricmp (buf, article.Kategorie))
    act = A_GetCurrentItemCat ();

  for (i = 0; i < A_GetArticleCount (); i++)
    {
      A_GetItem (i, &article);
      if (!stricmp (buf, article.Kategorie))
	{
	  DoMethod (LV_A_list, MUIM_List_InsertSingle, &article,
	            MUIV_List_Insert_Bottom);
	}
    }

  if (i == 0)
    {
      set (LV_A_list, MUIA_List_Quiet, FALSE);
    }
  else
    {
      set (LV_A_list, MUIA_List_Active, act);
      set (LV_A_list, MUIA_List_Quiet, FALSE);
      DoMethod (LV_A_list, MUIM_List_Jump, MUIV_List_Jump_Active);
    }
}

/*
** Zeige in der Artikelliste nur diejenigen Artikel an, die dem Suchkriterium
** entsprechen.
*/

static void 
Redraw_A_SList (void)
{
  struct Article art, pat;
  STRPTR str;

  int j, i, act;
  char artnum[100];

  get (ST_A_snumber, MUIA_String_Contents, &str);
  strcpy (pat.Artikelnummer, str);
  get (ST_A_sbezeichnung, MUIA_String_Contents, &str);
  strcpy (pat.Bezeichnung, str);
  get (ST_A_pop, MUIA_String_Contents, &str);
  strcpy (pat.Kategorie, str);

  set (LV_A_list, MUIA_List_Quiet, TRUE);

  DoMethod (LV_A_list, MUIM_List_Clear);
  A_GetCurrentItem (&art);
  strcpy (artnum, art.Artikelnummer);

  for (j = 0, act = 0, i = 0; i < A_GetArticleCount (); i++)
    {
      if (A_ComparePattern (i, &pat))
	{
	  A_GetItem (i, &art);
	  DoMethod (LV_A_list, MUIM_List_InsertSingle, &art,
	            MUIV_List_Insert_Bottom);
	  if (!strcmp (artnum, art.Artikelnummer))
	    act = j;
	  j++;
	}
    }

  if (i == 0)
    {
      set (LV_A_list, MUIA_List_Quiet, FALSE);
    }
  else
    {
      set (LV_A_list, MUIA_List_Active, act);
      set (LV_A_list, MUIA_List_Quiet, FALSE);
      DoMethod (LV_A_list, MUIM_List_Jump, MUIV_List_Jump_Active);
    }
}

/* lösche alle Eingabefelder */

static void 
Clear_A_Inputs (void)
{
  char buffer[24];

  set (CY_A_mwst, MUIA_Cycle_Active, 0);
  /* 3.3.96, ss: automatisch Artikelnummer vergeben */
  set (ST_A_number, MUIA_String_Contents, "?");
/*   set(ST_A_number,MUIA_String_Contents,""); */

  set (ST_A_article, MUIA_String_Contents, "");
  set (ST_A_menge, MUIA_String_Contents, "");
  set (ST_A_VKeinzel, MUIA_String_Contents, "");
  set (ST_A_EKeinzel, MUIA_String_Contents, "");
  set (ST_A_zuschlag, MUIA_String_Contents, "");
  set (ST_A_VGLeinzel, MUIA_String_Contents, "");
  set (ST_A_EKversand, MUIA_String_Contents, "");
  buffer[0] = 0;
  CorrectDate (buffer);
  set (ST_A_date, MUIA_String_Contents, buffer);
  set (ST_A_firma, MUIA_String_Contents, "");
  set (ST_A_note, MUIA_String_Contents, "");
}

static void 
Clear_A_SInputs (void)
{
  set (ST_A_snumber, MUIA_String_Contents, "");
  set (ST_A_sbezeichnung, MUIA_String_Contents, "");
}

/* vor dem Öffnen des Fensters Änderungen in den Gadgets eintragen */

void 
InitArticleWin (void)
{
  char buffer[80];
  STRPTR str;
  int i;

  A_LoadArticles ();

  DoMethod (LV_A_pop, MUIM_List_Clear);
  for (i = 0; i < A_GetCategoryCount (); i++)
    {
      A_GetCategory (i, buffer);
      DoMethod (LV_A_pop, MUIM_List_InsertSingle, buffer,
                MUIV_List_Insert_Bottom);
    }

  DoMethod (LV_A_pop, MUIM_List_GetEntry, 0, &str);
  if (str)
    set (ST_A_pop, MUIA_String_Contents, str);
  Redraw_A_List ();
}

static APTR 
MUI_BuildArticleList (void)
{
#ifdef DEBUG
  printf ("in BuildArticleList()\n");
#endif
  return (VGroup,
	  Child, HGroup,
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_LABEL_CATEGORY), CHAR (MSG_ARTICLE_LABEL_CATEGORY_KEY)),
	  Child, POP_A_mode = PopobjectObject,
	  MUIA_Popstring_String, ST_A_pop = KeyString (0, 60, CHAR (MSG_ARTICLE_LABEL_CATEGORY_KEY)),
	  MUIA_Popstring_Button, PopButton (MUII_PopUp),
	  MUIA_Popobject_StrObjHook, &A_StrObjHook,
	  MUIA_Popobject_ObjStrHook, &A_ObjStrHook,
	  MUIA_Popobject_WindowHook, &A_WindowHook,
	  MUIA_Popobject_Object, VGroup,
	  MUIA_Group_Spacing, 0,	/* im Popup kann Zwischenraum auf 0 */
	  Child, LV_A_pop = ListviewObject,
	  MUIA_Listview_List, ListObject,
	  InputListFrame,
	  MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
	  MUIA_List_DestructHook, MUIV_List_DestructHook_String,
	  End,
	  End,
	  Child, HGroup,
	  MUIA_Group_Spacing, 0,	/* im Popup kann Zwischenraum auf 0 */
	  Child, BT_A_popinsert = KeyButton (STRING (MSG_ARTICLE_POPBUTTON_INSERT), CHAR (MSG_ARTICLE_POPBUTTON_INSERT_KEY)),
	  Child, BT_A_popchange = KeyButton (STRING (MSG_ARTICLE_POPBUTTON_CHANGE), CHAR (MSG_ARTICLE_POPBUTTON_CHANGE_KEY)),
	  Child, BT_A_popdelete = KeyButton (STRING (MSG_ARTICLE_POPBUTTON_DELETE), CHAR (MSG_ARTICLE_POPBUTTON_DELETE_KEY)),
	  End,
	  End,
	  End,
	  End,


	  Child, LV_A_list = ListviewObject,
	  MUIA_Listview_List, ListObject,
	  InputListFrame,
	  MUIA_List_ConstructHook, &A_ConstructHook,
	  MUIA_List_DestructHook, &A_DestructHook,
	  MUIA_List_DisplayHook, &A_DisplayHook,
	  MUIA_List_Format, "D=8,D=8,D=8,",
	  MUIA_List_Title, TRUE,
	  End,
	  End,

	  Child, REG_A_inputmode = RegisterGroup (CustomerModePages),
	  MUIA_Register_Frame, TRUE,
	  MUIA_VertWeight, 1,

/* Unterregister "Eingabemodus" */

	  Child, VGroup,
	  Child, HGroup,
	  Child, BT_A_insert = KeyButton (STRING (MSG_ARTICLE_BUTTON_INSERT), CHAR (MSG_ARTICLE_BUTTON_INSERT_KEY)),
	  Child, BT_A_change = KeyButton (STRING (MSG_ARTICLE_BUTTON_CHANGE), CHAR (MSG_ARTICLE_BUTTON_CHANGE_KEY)),
	  Child, BT_A_delete = KeyButton (STRING (MSG_ARTICLE_BUTTON_DELETE), CHAR (MSG_ARTICLE_BUTTON_DELETE_KEY)),
	  Child, BT_A_clear = KeyButton (STRING (MSG_ARTICLE_BUTTON_NEW), CHAR (MSG_ARTICLE_BUTTON_NEW_KEY)),
	  End,


	  Child, REG_A_mode = RegisterGroup (artPages),
	  MUIA_Register_Frame, TRUE,
	  MUIA_VertWeight, 1,

	  Child, ColGroup (2), GroupFrameT (STRING (MSG_ARTICLE_GROUP_CHOOSEN_ARTICLE)),
	  MUIA_HelpNode, "articleinput-register",

	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_ARTICLENUMBER), CHAR (MSG_ARTICLE_STRING_ARTICLENUMBER_KEY)), Child, ST_A_number = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_ARTICLENUMBER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_DESCRIPTION), CHAR (MSG_ARTICLE_STRING_DESCRIPTION_KEY)), Child, ST_A_article = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_DESCRIPTION_KEY)),
	  Child, KeyLabel2 ("Menge", 'm'), Child, ST_A_menge = KeyString ("", 10, 'm'),
	  End,

	Child, ColGroup (4), GroupFrameT (STRING (MSG_ARTICLE_GROUP_PRICE)),
	  MUIA_HelpNode, "articlecost-register",
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_PRICE_1), CHAR (MSG_ARTICLE_STRING_PRICE_1_KEY)),
	  Child, ST_A_EKeinzel = KeyMonetaryString ("", 20, CHAR (MSG_ARTICLE_STRING_PRICE_1_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_PRICE_2), CHAR (MSG_ARTICLE_STRING_PRICE_2_KEY)),
	  Child, ST_A_EKversand = KeyMonetaryString ("", 20, CHAR (MSG_ARTICLE_STRING_PRICE_2_KEY)),

	  Child, Label2 (STRING (MSG_ARTICLE_TEXT_MINPRICE)),
	  Child, TX_A_brutto = TextObject, TextFrame, MUIA_Background, MUII_TextBack, End,
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_CYCLE_VAT), CHAR (MSG_ARTICLE_CYCLE_VAT_KEY)),
   Child, CY_A_mwst = KeyCycle (CYA_MwSt, CHAR (MSG_ARTICLE_CYCLE_VAT_KEY)),

	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_PRICE_3), CHAR (MSG_ARTICLE_STRING_PRICE_3_KEY)),
	  Child, ST_A_VKeinzel = KeyMonetaryString ("", 20, CHAR (MSG_ARTICLE_STRING_PRICE_3_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_PRICE_4), CHAR (MSG_ARTICLE_STRING_PRICE_4_KEY)),
	  Child, ST_A_zuschlag = KeyZuschlagString ("", 20, CHAR (MSG_ARTICLE_STRING_PRICE_4_KEY)),

	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_PRICE_NOTE), CHAR (MSG_ARTICLE_STRING_PRICE_NOTE_KEY)),
	  Child, ST_A_VGLeinzel = KeyMonetaryString ("", 20, CHAR (MSG_ARTICLE_STRING_PRICE_NOTE_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_CYCLE_INPUT), CHAR (MSG_ARTICLE_CYCLE_INPUT_KEY)),
	  Child, CY_A_mode = KeyCycle (CYA_BruttoNetto, CHAR (MSG_ARTICLE_CYCLE_INPUT_KEY)),
	  End,

	Child, ColGroup (2), GroupFrameT (STRING (MSG_ARTICLE_GROUP_INFOS)),
	  MUIA_HelpNode, "articleinfo-register",

	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_LASTCHANGE), CHAR (MSG_ARTICLE_STRING_LASTCHANGE_KEY)), Child, HGroup,
	  Child, ST_A_date = KeyDateString ("", 20, CHAR (MSG_ARTICLE_STRING_LASTCHANGE_KEY)),
	  Child, BT_A_today = KeyButton (STRING (MSG_ARTICLE_BUTTON_TODAY), CHAR (MSG_ARTICLE_BUTTON_TODAY_KEY)),
	  End,
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_DELIVERY), CHAR (MSG_ARTICLE_STRING_DELIVERY_KEY)), Child, ST_A_firma = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_DELIVERY_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_NOTE), CHAR (MSG_ARTICLE_STRING_NOTE_KEY)), Child, ST_A_note = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_NOTE_KEY)),

	  End,
	  End,
	  End,

/* Unterregister "Suchfilter" */

	  Child, VGroup,
	  MUIA_HelpNode, "articlesearch-register",
	  Child, HGroup,
	  Child, BT_A_search = KeyButton (STRING (MSG_ARTICLE_BUTTON_DISPLAY_FILTER), CHAR (MSG_ARTICLE_BUTTON_DISPLAY_FILTER_KEY)),
	  Child, BT_A_sall = KeyButton (STRING (MSG_ARTICLE_BUTTON_DISPLAY_ALL), CHAR (MSG_ARTICLE_BUTTON_DISPLAY_ALL_KEY)),
	  End,

       Child, ColGroup (2), GroupFrameT (STRING (MSG_ARTICLE_GROUP_SEARCH)),
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_SEARCH_ARTNUM), CHAR (MSG_ARTICLE_STRING_SEARCH_ARTNUM_KEY)), Child, HGroup,
	  Child, ST_A_snumber = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_SEARCH_ARTNUM_KEY)),
	  Child, BT_A_sclear = KeyButton (STRING (MSG_ARTICLE_BUTTON_SEARCH_NEW), CHAR (MSG_ARTICLE_BUTTON_SEARCH_NEW_KEY)),
	  End,
	  Child, KeyLabel2 (STRING (MSG_ARTICLE_STRING_SEARCH_ARTICLE), CHAR (MSG_ARTICLE_STRING_SEARCH_ARTICLE_KEY)), Child, ST_A_sbezeichnung = KeyString ("", 80, CHAR (MSG_ARTICLE_STRING_SEARCH_ARTICLE_KEY)),
	  End,
	  End,


	  End,

	  Child, HGroup,
	  Child, BT_A_ok = KeyButton (STRING (MSG_ARTICLE_BUTTON_OK), CHAR (MSG_ARTICLE_BUTTON_OK_KEY)),
	  Child, BT_A_print = KeyButton (STRING (MSG_ARTICLE_BUTTON_PRINT), CHAR (MSG_ARTICLE_BUTTON_PRINT_KEY)),
	  Child, BT_A_cancel = KeyButton (STRING (MSG_ARTICLE_BUTTON_ABORT), CHAR (MSG_ARTICLE_BUTTON_ABORT_KEY)),
	  End,

	  End);
}

static char *RAA_AP_mode[] =
{
  (STRPTR) MSG_ARTICLEPRINT_ALL_CATEGORIES,
  (STRPTR) MSG_ARTICLEPRINT_THIS_CATEGORY,
  NULL
};

static APTR 
MUI_BuildArticlePrint (void)
{
#ifdef DEBUG
  printf ("in BuildArticlePrint()\n");
#endif
  return (VGroup,
	  Child, RA_AP_mode = KeyRadio (STRING (MSG_ARTICLEPRINT_RADIO_PRINTMODE), &RAA_AP_mode, CHAR (MSG_ARTICLEPRINT_RADIO_PRINTMODE_KEY)),

	  Child, HGroup,
	  Child, BT_AP_ok = KeyButton (STRING (MSG_ARTICLEPRINT_BUTTON_PRINT), CHAR (MSG_ARTICLEPRINT_BUTTON_PRINT_KEY)),
	  Child, BT_AP_cancel = KeyButton (STRING (MSG_ARTICLEPRINT_BUTTON_ABORT), CHAR (MSG_ARTICLEPRINT_BUTTON_ABORT_KEY)),
	  End,

	  End);
}






/*********************************************************************
**
**
**  E T I K E T T
**
**
*********************************************************************/

/* Gadgets */

static APTR BT_E_customer, ST_E_adr1, ST_E_adr2, ST_E_adr3, ST_E_adr4,
  ST_E_adr5;
static APTR SL_E_col, SL_E_line, BT_E_print, WI_label, BT_E_visprint;





/*********************************************************************
**
**
**  K U N D E N L I S T E
**
**
*********************************************************************/

/* Gadgets des Kundenlistendrucks */

static APTR RA_CP_mode, RA_CP_list, BT_CP_ok, BT_CP_cancel;

/* Gadgets der Kundenliste */

static APTR LV_C_list, LV_C_pop, POP_C_mode, BT_C_print, BT_C_popinsert;
static APTR BT_C_popchange, BT_C_popdelete;
static APTR BT_C_insert, BT_C_change, BT_C_delete, BT_C_clear;
static APTR ST_C_number, CY_C_anrede, ST_C_remark1, ST_C_remark2;
static APTR ST_C_zeichen, ST_C_pop;
static APTR ST_C_patadr, ST_C_adr2, ST_C_adr3, ST_C_adr4, ST_C_adr5;
static APTR ST_C_phone;
static APTR BT_C_ok, BT_C_cancel;
static APTR BT_C_sall, BT_C_search, REG_C_input, REG_C_mode, BT_C_sclear;
static APTR CY_C_sanrede, ST_C_szeichen;
static APTR ST_C_snumber, ST_C_sadr, ST_C_sphone, ST_C_fax;

static char *CYA_Anrede[] =
{(STRPTR) MSG_STRING_HERRN, (STRPTR) MSG_STRING_FRAU,
 (STRPTR) MSG_STRING_FIRMA, (STRPTR) MSG_STRING_EMPTY, NULL};

static char *CustomerInputPages[] =
{(STRPTR) MSG_ADDRESS_INPUT_PAGE_ADDRESS,
 (STRPTR) MSG_ADDRESS_INPUT_PAGE_INFORMATION, NULL};



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

UWORD closeCustomerAction;

/*
** Suche die Nummer im Cycle-Array anhand einer gegebenen Anrede.
*/

static int 
SearchAnrede (STRPTR string)
{
  BOOL searching = TRUE;
  int i;

  for (i = 0; searching && i < 4; i++)
    {
      if (!strcmp (CYA_Anrede[i], string))
	searching = FALSE;
    }
  return (i - 1);
}


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

struct Customer emptycust =
{
  "", "", "", "", "", "", 0, "", "", "", "", ""
};


BOOL 
C_CheckAbort (BOOL endok)
{
  BOOL abort = TRUE;
  LONG isopen;
  struct Customer cust;
  LONG num;
  STRPTR str;
  BOOL diff = FALSE;

  get (WI_customer, MUIA_Window_Open, &isopen);
  if (isopen)
    {
      if (C_GetCurrentCustomer (&cust) != ERR_CUST_LISTEMPTY)
	{
	  get (ST_C_pop, MUIA_String_Contents, &str);
	  if (strcmp (str, cust.Kategorie))
	    cust = emptycust;
	}
      else
	{
	  cust = emptycust;
	  get (CY_C_anrede, MUIA_Cycle_Active, &num);
	  strcpy (cust.Adresse1, CYA_Anrede[num]);
	}

      get (CY_C_anrede, MUIA_Cycle_Active, &num);
      diff |= (strcmp (cust.Adresse1, CYA_Anrede[num]) != 0);
      get (ST_C_adr2, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Adresse2, str) != 0);
      get (ST_C_adr3, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Adresse3, str) != 0);
      get (ST_C_adr4, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Adresse4, str) != 0);
      get (ST_C_adr5, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Adresse5, str) != 0);
      get (ST_C_zeichen, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Zeichen, str) != 0);
      get (ST_C_phone, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Telefon, str) != 0);
      get (ST_C_fax, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Fax, str) != 0);
      get (ST_C_remark1, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Kommentar1, str) != 0);
      get (ST_C_remark2, MUIA_String_Contents, &str);
      diff |= (strcmp (cust.Kommentar2, str) != 0);
      get (ST_C_number, MUIA_String_Contents, &str);
      if (!strchr (str, '?'))
	diff |= (cust.KundenNummer != atol (str));

      diff = FALSE;

      if (diff && !MUI_Request (app, WI_customer, 0,
                                STRING (MSG_ABORTADDRESS_REQ_TITLE),
				STRING (MSG_ABORTADDRESS_REQ_BUTTONS),
				STRING (MSG_ABORTADDRESS_REQ_BODY)))
	{
	  abort = FALSE;
	}

      if (!endok && abort)
	{
	  if (C_GetStatus () && !MUI_Request (app, WI_customer, 0,
	                              STRING (MSG_ABORTADDRESSES_REQ_TITLE),
				      STRING (MSG_ABORTADDRESS_REQ_BUTTONS),
				      STRING (MSG_ABORTADDRESSES_REQ_BODY)))
	    abort = FALSE;
	}
    }
  return (abort);
}


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


SAVEDS ASM LONG 
C_StrObjFunc (REG (a2) Object * pop, REG (a1) Object * str)
{
  char *x, *s;
  int i;

  get (str, MUIA_String_Contents, &s);

  for (i = 0;; i++)
    {
      DoMethod (pop, MUIM_List_GetEntry, i, &x);
      if (!x)
	{
	  set (pop, MUIA_List_Active, MUIV_List_Active_Off);
	  break;
	}
      else if (!stricmp (x, s))
	{
	  set (pop, MUIA_List_Active, i);
	  break;
	}
    }
  return (TRUE);
}


SAVEDS ASM VOID 
C_ObjStrFunc (REG (a2) Object * pop, REG (a1) Object * str)
{
  char *x;
  DoMethod (pop, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &x);
  set (str, MUIA_String_Contents, x);
  /* notify string input */
  DoMethod (app, MUIM_Application_ReturnID, ID_C_LISTMODE);
  set (WI_customer, MUIA_Window_ActiveObject, LV_C_list);
}

SAVEDS ASM VOID 
C_WindowFunc (REG (a2) Object * pop, REG (a1) Object * win)
{
  set (win, MUIA_Window_DefaultObject, pop);
}

SAVEDS ASM APTR 
C_ConstructFunc (REG (a1)
		 struct Customer *cust,
		 REG (a2)
		 void *mempool)
{
  struct Customer *newitem;

  if (newitem = LibAllocPooled (mempool, sizeof (struct Customer)))
    {
      strcpy (newitem->Adresse2, cust->Adresse2);
      strcpy (newitem->Adresse3, cust->Adresse3);
      strcpy (newitem->Adresse4, cust->Adresse4);
      strcpy (newitem->Kategorie, cust->Kategorie);
      newitem->KundenNummer = cust->KundenNummer;
    }

  return ((APTR) newitem);
}

SAVEDS ASM VOID 
C_DestructFunc (REG (a1) struct Customer * cust,
		REG (a2) void *mempool)
{
  LibFreePooled (mempool, cust, sizeof (struct Customer));
}

SAVEDS ASM LONG 
C_DisplayFunc (REG (a2)
	       char **array,
	       REG (a1)
	       struct Customer *cust)
{
  static char buf1[16], buf2[100];

  if (cust)
    {
      /* zeige den Eintrag an. */

      if (cust->KundenNummer)
	sprintf (buf1, "\033r%d", cust->KundenNummer);
      else
	buf1[0] = 0;
      *array++ = buf1;

      C_PrintCustLine ((struct MinCustomer *) cust, buf2);
      *array++ = buf2;

      *array++ = cust->Adresse3;
      *array = cust->Adresse4;

    }
  else
    {
      /* zeige die Titel-Zeile an. */
      *array++ = STRING (MSG_ADDRESS_LIST_NUMBER);
      *array++ = STRING (MSG_ADDRESS_LIST_ADDRESS);
      *array++ = "";
      *array = "";
    }
  return (0);
}

/* Hooks für Kundenliste */

static struct Hook C_StrObjHook =
{
  {NULL, NULL}, (VOID *) C_StrObjFunc, NULL, NULL};
static struct Hook C_ObjStrHook =
{
  {NULL, NULL}, (VOID *) C_ObjStrFunc, NULL, NULL};
static struct Hook C_WindowHook =
{
  {NULL, NULL}, (VOID *) C_WindowFunc, NULL, NULL};

static struct Hook C_ConstructHook =
{
  {NULL, NULL}, (VOID *) C_ConstructFunc, NULL, NULL};
static struct Hook C_DestructHook =
{
  {NULL, NULL}, (VOID *) C_DestructFunc, NULL, NULL};
static struct Hook C_DisplayHook =
{
  {NULL, NULL}, (VOID *) C_DisplayFunc, NULL, NULL};

/*
** Beim Verändern der Einstellungen für die Kundenliste muß diese komplett
** neu aufgebaut werden. Der alte Inhalt wird gelöscht und je nach Modus
** die entsprechenden Einträge neu eingefügt.
*/

static void 
Redraw_C_List (void)
{
  struct Customer cust;
  int i, act;
  STRPTR str;
  char buf[80];

  set (LV_C_list, MUIA_List_Quiet, TRUE);
  get (ST_C_pop, MUIA_String_Contents, &str);
  strcpy (buf, str);

  DoMethod (LV_C_list, MUIM_List_Clear);

  act = 0;
  C_GetCurrentCustomer (&cust);
  if (!stricmp (buf, cust.Kategorie))
    act = C_GetCurrentCustomerNumberCat ();

  for (i = 0; i < C_GetCustomerCount (); i++)
    {
      C_GetCustomer (i, &cust);
      if (!stricmp (buf, cust.Kategorie))
	{
	  DoMethod (LV_C_list, MUIM_List_InsertSingle, &cust,
	            MUIV_List_Insert_Bottom);
	}
    }

  if (i == 0)
    {
      set (LV_C_list, MUIA_List_Quiet, FALSE);
    }
  else
    {
      set (LV_C_list, MUIA_List_Active, act);
      set (LV_C_list, MUIA_List_Quiet, FALSE);
      DoMethod (LV_C_list, MUIM_List_Jump, MUIV_List_Jump_Active);
    }
}


/*
** Zeige in der Kundenliste nur diejenigen Kunden an, die dem Suchkriterium
** entsprechen.
*/

static void 
Redraw_C_SList (void)
{
  struct Customer cust, pat;
  STRPTR str;
  LONG num;
  int j, i, act, custnum;

  get (ST_C_snumber, MUIA_String_Integer, &num);
  pat.KundenNummer = num;
  get (CY_C_sanrede, MUIA_Cycle_Active, &num);
  strcpy (pat.Adresse1, CYA_Anrede[num]);
  get (ST_C_sadr, MUIA_String_Contents, &str);
  strcpy (pat.Adresse2, str);
  pat.Adresse5[0] = pat.Adresse4[0] = pat.Adresse3[0] = 0;
  pat.Kommentar1[0] = pat.Kommentar2[0] = pat.Fax[0] = 0;
  get (ST_C_pop, MUIA_String_Contents, &str);
  strcpy (pat.Kategorie, str);
  get (ST_C_szeichen, MUIA_String_Contents, &str);
  strcpy (pat.Zeichen, str);
  get (ST_C_sphone, MUIA_String_Contents, &str);
  strcpy (pat.Telefon, str);

  set (LV_C_list, MUIA_List_Quiet, TRUE);

  DoMethod (LV_C_list, MUIM_List_Clear);
  C_GetCurrentCustomer (&cust);
  custnum = cust.KundenNummer;

  for (j = 0, act = 0, i = 0; i < C_GetCustomerCount (); i++)
    {
      if (C_ComparePattern (i, &pat))
	{
	  C_GetCustomer (i, &cust);
	  DoMethod (LV_C_list, MUIM_List_InsertSingle, &cust,
	            MUIV_List_Insert_Bottom);
	  if (custnum == cust.KundenNummer)
	    act = j;
	  j++;
	}
    }

  if (i == 0)
    {
      set (LV_C_list, MUIA_List_Quiet, FALSE);
    }
  else
    {
      set (LV_C_list, MUIA_List_Active, act);
      set (LV_C_list, MUIA_List_Quiet, FALSE);
      DoMethod (LV_C_list, MUIM_List_Jump, MUIV_List_Jump_Active);
    }
}

/* lösche alle Eingabefelder */

static void 
Clear_C_Inputs (void)
{
  set (CY_C_anrede, MUIA_Cycle_Active, 0);
  set (ST_C_adr2, MUIA_String_Contents, "");
  set (ST_C_adr3, MUIA_String_Contents, "");
  set (ST_C_adr4, MUIA_String_Contents, "");
  set (ST_C_adr5, MUIA_String_Contents, "");
  set (ST_C_zeichen, MUIA_String_Contents, "");
  set (ST_C_number, MUIA_String_Contents, "?");
  set (ST_C_phone, MUIA_String_Contents, "");
  set (ST_C_fax, MUIA_String_Contents, "");
  set (ST_C_remark1, MUIA_String_Contents, "");
  set (ST_C_remark2, MUIA_String_Contents, "");
}

static void 
Clear_C_SInputs (void)
{
  set (ST_C_snumber, MUIA_String_Contents, "");
  set (CY_C_sanrede, MUIA_Cycle_Active, 3);
  set (ST_C_sadr, MUIA_String_Contents, "");
  set (ST_C_szeichen, MUIA_String_Contents, "");
  set (ST_C_sphone, MUIA_String_Contents, "");
}

/* vor dem Öffnen des Fensters Änderungen in den Gadgets eintragen
**
** Parameter:
**             num  - Kundennummer oder 0 wenn egal. Dieser Kunde wird
**                    zu Beginn selektiert.
*/

void 
InitCustomerWin (UWORD number)
{
  char buffer[80];
  STRPTR str;
  int i;

  C_LoadCustomerList ();

  DoMethod (LV_C_pop, MUIM_List_Clear);
  for (i = 0; i < C_GetCategoryCount (); i++)
    {
      C_GetCategory (i, buffer);
      DoMethod (LV_C_pop, MUIM_List_InsertSingle, buffer,
                MUIV_List_Insert_Bottom);
    }

  DoMethod (LV_C_pop, MUIM_List_GetEntry, 0, &str);
  if (str)
    set (ST_C_pop, MUIA_String_Contents, str);

  if (number)
    C_SetCurrentCustomer (number);
  Redraw_C_List ();
  set (WI_customer, MUIA_Window_ActiveObject, ST_C_patadr);
}



static APTR 
MUI_BuildCustomer (void)
{
#ifdef DEBUG
  printf ("in BuildCustomer()\n");
#endif
  return (VGroup,

	  Child, HGroup,
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_LABEL_CATEGORY), CHAR (MSG_ADDRESS_LABEL_CATEGORY_KEY)),
	  Child, POP_C_mode = PopobjectObject,
	  MUIA_Popstring_String, ST_C_pop = KeyString (0, 60, CHAR (MSG_ADDRESS_LABEL_CATEGORY_KEY)),
	  MUIA_Popstring_Button, PopButton (MUII_PopUp),
	  MUIA_Popobject_StrObjHook, &C_StrObjHook,
	  MUIA_Popobject_ObjStrHook, &C_ObjStrHook,
	  MUIA_Popobject_WindowHook, &C_WindowHook,
	  MUIA_Popobject_Object, VGroup,
	  MUIA_Group_Spacing, 0,	/* im Popup kann Zwischenraum auf 0 */
	  Child, LV_C_pop = ListviewObject,
	  MUIA_Listview_List, ListObject,
	  InputListFrame,
	  MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
	  MUIA_List_DestructHook, MUIV_List_DestructHook_String,
	  End,
	  End,
	  Child, HGroup,
	  MUIA_Group_Spacing, 0,	/* im Popup kann Zwischenraum auf 0 */
	  Child, BT_C_popinsert = KeyButton (STRING (MSG_ADDRESS_POPBUTTON_INSERT), CHAR (MSG_ADDRESS_POPBUTTON_INSERT_KEY)),
	  Child, BT_C_popchange = KeyButton (STRING (MSG_ADDRESS_POPBUTTON_CHANGE), CHAR (MSG_ADDRESS_POPBUTTON_CHANGE_KEY)),
	  Child, BT_C_popdelete = KeyButton (STRING (MSG_ADDRESS_POPBUTTON_DELETE), CHAR (MSG_ADDRESS_POPBUTTON_DELETE_KEY)),
	  End,
	  End,
	  End,
	  End,

	  Child, LV_C_list = ListviewObject,
	  MUIA_Listview_List, ListObject,
	  InputListFrame,
	  MUIA_List_ConstructHook, &C_ConstructHook,
	  MUIA_List_DestructHook, &C_DestructHook,
	  MUIA_List_DisplayHook, &C_DisplayHook,
	  MUIA_List_Format, "D=8,D=8,D=8,",
	  MUIA_List_Title, TRUE,
	  End,
	  End,

	  Child, ColGroup (2),
	  Child, Label2 (STRING (MSG_ADDRESS_STRING_SEARCH)),
	  Child, ST_C_patadr = String ("", 80),
	  End,

	  Child, REG_C_mode = RegisterGroup (CustomerModePages),
	  MUIA_Register_Frame, TRUE,
	  MUIA_VertWeight, 1,

/* Unterregister "Eingabemodus" */

	  Child, VGroup,
	  MUIA_HelpNode, "customerinput-register",

	  Child, HGroup,
	  Child, BT_C_insert = KeyButton (STRING (MSG_ADDRESS_BUTTON_INSERT), CHAR (MSG_ADDRESS_BUTTON_INSERT_KEY)),
	  Child, BT_C_change = KeyButton (STRING (MSG_ADDRESS_BUTTON_CHANGE), CHAR (MSG_ADDRESS_BUTTON_CHANGE_KEY)),
	  Child, BT_C_delete = KeyButton (STRING (MSG_ADDRESS_BUTTON_DELETE), CHAR (MSG_ADDRESS_BUTTON_DELETE_KEY)),
	  Child, BT_C_clear = KeyButton (STRING (MSG_ADDRESS_BUTTON_NEW), CHAR (MSG_ADDRESS_BUTTON_NEW_KEY)),
	  End,

	  Child, REG_C_input = RegisterGroup (CustomerInputPages),
	  MUIA_Register_Frame, TRUE,
	  MUIA_VertWeight, 1,

  /* Unterregister "Adresse" */

	  Child, ColGroup (2),

	  Child, KeyLabel2 (STRING (MSG_ADDRESS_CYCLE_ANREDE), CHAR (MSG_ADDRESS_CYCLE_ANREDE_KEY)),
	  Child, HGroup,
	  Child, CY_C_anrede = KeyCycle (CYA_Anrede, CHAR (MSG_ADDRESS_CYCLE_ANREDE_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_REF), CHAR (MSG_ADDRESS_STRING_REF_KEY)),
    Child, ST_C_zeichen = KeyString ("", 20, CHAR (MSG_ADDRESS_STRING_REF)),
	  End,

	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_ADDRESS), CHAR (MSG_ADDRESS_STRING_ADDRESS_KEY)), Child, ST_C_adr2 = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_ADDRESS_KEY)),
	  Child, Label2 (""), Child, ST_C_adr3 = String ("", 80),
	  Child, Label2 (""), Child, ST_C_adr4 = String ("", 80),
	  Child, Label2 (""), Child, ST_C_adr5 = String ("", 80),
	  End,

  /* Unterregister "weitere Daten" */

	  Child, ColGroup (2),

	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_CUSTNUMBER), CHAR (MSG_ADDRESS_STRING_CUSTNUMBER_KEY)), Child, ST_C_number = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_CUSTNUMBER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_PHONENUMBER), CHAR (MSG_ADDRESS_STRING_PHONENUMBER_KEY)), Child, ST_C_phone = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_PHONENUMBER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_FAXNUMBER), CHAR (MSG_ADDRESS_STRING_FAXNUMBER_KEY)), Child, ST_C_fax = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_FAXNUMBER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_NOTE), CHAR (MSG_ADDRESS_STRING_NOTE)), Child, ST_C_remark1 = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_NOTE_KEY)),
	  Child, Label2 (""), Child, ST_C_remark2 = String ("", 80),

	  End,

	  End,
	  End,

/* Unterregister "Suchmodus" */

	  Child, VGroup,
	  MUIA_HelpNode, "customersearch-register",
	  Child, HGroup,
	  Child, BT_C_search = KeyButton (STRING (MSG_ADDRESS_BUTTON_DISPLAY_FILTER), CHAR (MSG_ADDRESS_BUTTON_DISPLAY_FILTER_KEY)),
	  Child, BT_C_sall = KeyButton (STRING (MSG_ADDRESS_BUTTON_DISPLAY_ALL), CHAR (MSG_ADDRESS_BUTTON_DISPLAY_ALL_KEY)),
	  End,

       Child, ColGroup (2), GroupFrameT (STRING (MSG_ADDRESS_GROUP_SEARCH)),
	  Child, VGroup,
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_SEARCH_CUSTNUMBER), CHAR (MSG_ADDRESS_STRING_SEARCH_CUSTNUMBER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_CYCLE_SEARCH_ANREDE), CHAR (MSG_ADDRESS_CYCLE_SEARCH_ANREDE_KEY)),
	  End,
	  Child, VGroup,
	  Child, ColGroup (2),
	  Child, ST_C_snumber = KeyString ("", 10, CHAR (MSG_ADDRESS_STRING_SEARCH_CUSTNUMBER_KEY)),
	  Child, BT_C_sclear = KeyButton (STRING (MSG_ADDRESS_BUTTON_SEARCH_NEW), CHAR (MSG_ADDRESS_BUTTON_SEARCH_NEW_KEY)),

	  Child, CY_C_sanrede = KeyCycle (CYA_Anrede, CHAR (MSG_ADDRESS_CYCLE_SEARCH_ANREDE_KEY)),
	  Child, HGroup,
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_SEARCH_YOURREF), CHAR (MSG_ADDRESS_STRING_SEARCH_YOURREF_KEY)),
	  Child, ST_C_szeichen = KeyString ("", 20, CHAR (MSG_ADDRESS_STRING_SEARCH_YOURREF)),
	  End,
	  End,
	  End,

	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_SEARCH_ADDRESSPAT), CHAR (MSG_ADDRESS_STRING_SEARCH_ADDRESSPAT_KEY)), Child, ST_C_sadr = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_SEARCH_ADDRESSPAT_KEY)),
	  Child, KeyLabel2 (STRING (MSG_ADDRESS_STRING_SEARCH_PHONEPAT), CHAR (MSG_ADDRESS_STRING_SEARCH_PHONEPAT_KEY)), Child, ST_C_sphone = KeyString ("", 80, CHAR (MSG_ADDRESS_STRING_SEARCH_PHONEPAT_KEY)),
	  End,
	  End,

	  End,

	  Child, HGroup,
	  Child, BT_C_ok = KeyButton (STRING (MSG_ADDRESS_BUTTON_OK), CHAR (MSG_ADDRESS_BUTTON_OK_KEY)),
	  Child, BT_C_print = KeyButton (STRING (MSG_ADDRESS_BUTTON_PRINT), CHAR (MSG_ADDRESS_BUTTON_PRINT_KEY)),
	  Child, BT_C_cancel = KeyButton (STRING (MSG_ADDRESS_BUTTON_ABORT), CHAR (MSG_ADDRESS_BUTTON_ABORT_KEY)),
	  End,

	  End);
}

static char *RAA_CP_mode[] =
{
  (STRPTR) MSG_ADDRESSPRINT_ALL_CATEGORIES,
  (STRPTR) MSG_ADDRESSPRINT_THIS_CATEGORY,
  NULL
};

static char *RAA_CP_list[] =
{
  (STRPTR) MSG_ADDRESSPRINT_PHONELIST,
  (STRPTR) MSG_ADDRESSPRINT_FAXLIST,
  (STRPTR) MSG_ADDRESSPRINT_ADDRESSLIST,
  NULL
};

static APTR 
MUI_BuildCustomerPrint (void)
{
#ifdef DEBUG
  printf ("in BuildCustomerPrint()\n");
#endif
  return (VGroup,
	  Child, RA_CP_mode = KeyRadio (STRING (MSG_ADDRESSPRINT_RADIO_PRINTMODE), &RAA_CP_mode, CHAR (MSG_ADDRESSPRINT_RADIO_PRINTMODE_KEY)),

	  Child, RA_CP_list = KeyRadio (STRING (MSG_ADDRESSPRINT_RADIO_LISTMODE), &RAA_CP_list, CHAR (MSG_ADDRESSPRINT_RADIO_LISTMODE_KEY)),

	  Child, HGroup,
	  Child, BT_CP_ok = KeyButton (STRING (MSG_ADDRESSPRINT_BUTTON_PRINT), CHAR (MSG_ADDRESSPRINT_BUTTON_PRINT_KEY)),
	  Child, BT_CP_cancel = KeyButton (STRING (MSG_ADDRESSPRINT_BUTTON_ABORT), CHAR (MSG_ADDRESSPRINT_BUTTON_ABORT_KEY)),
	  End,

	  End);
}






/*********************************************************************
**
**
**  K O N F I G U R A T I O N                 ( C O N F I G )
**
**
*********************************************************************/

/* von DVIprint unterstützte Drucker */

static char *CYA_printers[] =
{"DeskJet", "NECP6", "NECP6c", "STYLUS", "LQ",
 "CheapDJ", "LaserJet", "LaserJet4", "FX", "GENERIC",
 "NECP7", "FujitsuDL1100", "BJ300", "BJ200",
 "BJ130", "CanonLBP", NULL};

/* Menü des Konfigfensters */

static struct NewMenu ConfigMenu[] =
{
  {NM_TITLE, (STRPTR) MENU_CONFIG_PROJECT, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_CONFIG_LOAD, (STRPTR) MENUITEM_CONFIG_LOAD_KEY, 0, 0, (APTR) ID_CO_MEN_LOAD},
  {NM_ITEM, (STRPTR) MENUITEM_CONFIG_SAVE, (STRPTR) MENUITEM_CONFIG_SAVE_KEY, 0, 0, (APTR) ID_CO_MEN_SAVE},
  {NM_ITEM, NM_BARLABEL, 0, 0, 0, (APTR) 0},
  {NM_ITEM, (STRPTR) MENUITEM_CONFIG_QUIT, (STRPTR) MENUITEM_CONFIG_QUIT_KEY, 0, 0, (APTR) ID_CO_CANCEL},

  {NM_END, NULL, 0, 0, 0, (APTR) 0},
};

/* Gadgets für die Konfiguration */

APTR BT_CO_ok, BT_CO_cancel, ST_CO_bankname, ST_CO_blz, ST_CO_konto;
APTR ST_CO_phonevorwahl, ST_CO_phone, ST_CO_faxvorwahl, ST_CO_fax;
APTR ST_CO_firmaname, ST_CO_inhaber, ST_CO_str;
APTR ST_CO_ort, ST_CO_zeichen, ST_CO_kopf1, ST_CO_kopf2;
APTR ST_CO_fuss1, ST_CO_fuss2, ST_CO_fuss3, ST_CO_fuss4;
APTR CY_CO_prt, SL_CO_voff, SL_CO_hoff, BT_CO_offset;
APTR ST_CO_mwst1, ST_CO_mwst2, REG_CO_pages;

static char *ConfigPages[] =
{(STRPTR) MSG_CONFIG_PAGE_ADDRESS, (STRPTR) MSG_CONFIG_PAGE_CONNECT,
 (STRPTR) MSG_CONFIG_PAGE_TEXTS, (STRPTR) MSG_CONFIG_PAGE_PRINTERS, NULL};

static APTR 
MUI_BuildConfig (void)
{
#ifdef DEBUG
  printf ("in BuildConfig()\n");
#endif
  return (VGroup,
	  Child, REG_CO_pages = RegisterGroup (ConfigPages),
	  MUIA_Register_Frame, TRUE,

/* Anschrift */

       Child, ColGroup (2), GroupFrameT (STRING (MSG_CONFIG_GROUP_ADDRESS)),
	  MUIA_HelpNode, "configaddress-register",
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_FIRM), CHAR (MSG_CONFIG_STRING_FIRM_KEY)), Child, ST_CO_firmaname = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_FIRM_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_INHABER), CHAR (MSG_CONFIG_STRING_INHABER_KEY)), Child, ST_CO_inhaber = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_INHABER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_STREET), CHAR (MSG_CONFIG_STRING_STREET_KEY)), Child, ST_CO_str = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_STREET_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_CITY), CHAR (MSG_CONFIG_STRING_CITY_KEY)), Child, ST_CO_ort = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_CITY_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_MYREF), CHAR (MSG_CONFIG_STRING_MYREF_KEY)), Child, ST_CO_zeichen = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_MYREF_KEY)),

	  End,

/* Verbindungen */

	  Child, VGroup,
	  MUIA_HelpNode, "configconnect-register",
   Child, ColGroup (2), GroupFrameT (STRING (MSG_CONFIG_GROUP_BANKCONNECT)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_BANKNAME), CHAR (MSG_CONFIG_STRING_BANKNAME_KEY)), Child, ST_CO_bankname = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_BANKNAME_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_BLZ), CHAR (MSG_CONFIG_STRING_BLZ_KEY)), Child, ST_CO_blz = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_BLZ_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_KONTO), CHAR (MSG_CONFIG_STRING_KONTO_KEY)), Child, ST_CO_konto = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_KONTO_KEY)),
	  End,

  Child, ColGroup (4), GroupFrameT (STRING (MSG_CONFIG_GROUP_PHONECONNECT)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_PHONEPRE), CHAR (MSG_CONFIG_STRING_PHONEPRE_KEY)), Child, ST_CO_phonevorwahl = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_PHONEPRE_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_PHONE), CHAR (MSG_CONFIG_STRING_PHONE_KEY)), Child, ST_CO_phone = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_PHONE_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_FAXPRE), CHAR (MSG_CONFIG_STRING_FAXPRE_KEY)), Child, ST_CO_faxvorwahl = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_FAXPRE_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_FAX), CHAR (MSG_CONFIG_STRING_FAX_KEY)), Child, ST_CO_fax = KeyString ("", 80, CHAR (MSG_CONFIG_STRING_FAX_KEY)),
	  End,

	  End,

/* Texte */

	  Child, VGroup,
	  MUIA_HelpNode, "configtext-register",
	  Child, VGroup, GroupFrameT (STRING (MSG_CONFIG_GROUP_HEAD)),
	  Child, ST_CO_kopf1 = String ("", 80),
	  Child, ST_CO_kopf2 = String ("", 80),
	  End,

	  Child, VGroup, GroupFrameT (STRING (MSG_CONFIG_GROUP_FOOT)),
	  Child, ST_CO_fuss1 = String ("", 80),
	  Child, ST_CO_fuss2 = String ("", 80),
	  Child, ST_CO_fuss3 = String ("", 80),
	  Child, ST_CO_fuss4 = String ("", 80),
	  End,
	  End,

/* Drucker, MwSt */

	  Child, VGroup,
	  MUIA_HelpNode, "configprinter-register",
       Child, ColGroup (2), GroupFrameT (STRING (MSG_CONFIG_GROUP_PRINTER)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_CYCLE_PRINTER), CHAR (MSG_CONFIG_CYCLE_PRINTER_KEY)), Child, CY_CO_prt = KeyCycle (CYA_printers, CHAR (MSG_CONFIG_CYCLE_PRINTER_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_VOFFSET), CHAR (MSG_CONFIG_STRING_VOFFSET_KEY)), Child, SL_CO_voff = KeySlider (-20, 40, 0, CHAR (MSG_CONFIG_STRING_VOFFSET_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_HOFFSET), CHAR (MSG_CONFIG_STRING_HOFFSET_KEY)), Child, SL_CO_hoff = KeySlider (-20, 40, 0, CHAR (MSG_CONFIG_STRING_HOFFSET_KEY)),
	  Child, Label2 (""), Child, BT_CO_offset = KeyButton (STRING (MSG_CONFIG_BUTTON_TEST), CHAR (MSG_CONFIG_BUTTON_TEST_KEY)),
	  End,

	  Child, ColGroup (2), GroupFrameT (STRING (MSG_CONFIG_GROUP_VAT)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_VAT1), CHAR (MSG_CONFIG_STRING_VAT1_KEY)), Child, ST_CO_mwst1 = KeyMonetaryString ("", 10, CHAR (MSG_CONFIG_STRING_VAT1_KEY)),
	  Child, KeyLabel2 (STRING (MSG_CONFIG_STRING_VAT2), CHAR (MSG_CONFIG_STRING_VAT2_KEY)), Child, ST_CO_mwst2 = KeyMonetaryString ("", 10, CHAR (MSG_CONFIG_STRING_VAT2_KEY)),
	  End,

	  End,

	  End,

	  Child, HGroup,
	  Child, BT_CO_ok = KeyButton (STRING (MSG_CONFIG_BUTTON_OK), CHAR (MSG_CONFIG_BUTTON_OK_KEY)),
	  Child, BT_CO_cancel = KeyButton (STRING (MSG_CONFIG_BUTTON_CANCEL), CHAR (MSG_CONFIG_BUTTON_CANCEL_KEY)),
	  End,
	  End);
}

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

static BOOL 
CO_GetStatus (void)
{
  BOOL status = FALSE;
  STRPTR s;
  LONG num;
  double d;

  get (ST_CO_bankname, MUIA_String_Contents, &s);
  if (strcmp (s, CO_GetBankName ()))
    status = TRUE;

  if (!status)
    {
      get (ST_CO_blz, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetBLZ ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_konto, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetKontonr ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_phonevorwahl, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetPhoneVorwahl ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_phone, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetPhone ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_faxvorwahl, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFaxVorwahl ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_fax, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFax ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_zeichen, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetZeichen ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_firmaname, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFirma ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_inhaber, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetInhaber ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_str, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetStrasse ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_ort, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetOrt ()))
	status = TRUE;
    }
  if (!status)
    {
      get (CY_CO_prt, MUIA_Cycle_Active, &num);
      if (strcmp (CYA_printers[num], CO_GetDVIprinter ()))
	status = TRUE;
    }
  if (!status)
    {
      get (SL_CO_voff, MUIA_Slider_Level, &num);
      if (num != CO_GetDVIVoffset ())
	status = TRUE;
    }
  if (!status)
    {
      get (SL_CO_hoff, MUIA_Slider_Level, &num);
      if (num != CO_GetDVIHoffset ())
	status = TRUE;
    }

  if (!status)
    {
      get (ST_CO_mwst1, MUIA_String_Contents, &s);
      d = ScanMonetary (s);
      if (d != CO_GetMwSt1New ())
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_mwst2, MUIA_String_Contents, &s);
      d = ScanMonetary (s);
      if (d != CO_GetMwSt2New ())
	status = TRUE;
    }

  if (!status)
    {
      get (ST_CO_kopf1, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetKopf1 ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_kopf2, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetKopf2 ()))
	status = TRUE;
    }

  if (!status)
    {
      get (ST_CO_fuss1, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFuss1 ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_fuss2, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFuss2 ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_fuss3, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFuss3 ()))
	status = TRUE;
    }
  if (!status)
    {
      get (ST_CO_fuss4, MUIA_String_Contents, &s);
      if (strcmp (s, CO_GetFuss4 ()))
	status = TRUE;
    }

  return (status);
}

static BOOL 
CO_CheckAbort (BOOL endok)
{
  BOOL abort = TRUE;
  LONG isopen;

  get (WI_config, MUIA_Window_Open, &isopen);
  if (isopen)
    {
      if (CO_GetStatus () && !MUI_Request (app, WI_config, 0,
                                       STRING (MSG_ABORTCONFIG_REQ_TITLE),
				       STRING (MSG_ABORTCONFIG_REQ_BUTTONS),
				       STRING (MSG_ABORTCONFIG_REQ_BODY)))
	abort = FALSE;
    }

  return (abort);
}

/*
** Stelle alle Grundeinstellungen im Fenster so ein,
** wie sie intern aktuell sind.
*/

static void 
InitConfigWin (void)
{
  LONG num;
  STRPTR str;
  char buf[12];

  set (ST_CO_bankname, MUIA_String_Contents, CO_GetBankName ());
  set (ST_CO_blz, MUIA_String_Contents, CO_GetBLZ ());
  set (ST_CO_konto, MUIA_String_Contents, CO_GetKontonr ());
  set (ST_CO_phonevorwahl, MUIA_String_Contents, CO_GetPhoneVorwahl ());
  set (ST_CO_phone, MUIA_String_Contents, CO_GetPhone ());
  set (ST_CO_faxvorwahl, MUIA_String_Contents, CO_GetFaxVorwahl ());
  set (ST_CO_fax, MUIA_String_Contents, CO_GetFax ());
  set (ST_CO_zeichen, MUIA_String_Contents, CO_GetZeichen ());
  set (ST_CO_firmaname, MUIA_String_Contents, CO_GetFirma ());
  set (ST_CO_inhaber, MUIA_String_Contents, CO_GetInhaber ());
  set (ST_CO_str, MUIA_String_Contents, CO_GetStrasse ());
  set (ST_CO_ort, MUIA_String_Contents, CO_GetOrt ());
  PrintMonetary (buf, CO_GetMwSt1New ());
  set (ST_CO_mwst1, MUIA_String_Contents, buf);
  PrintMonetary (buf, CO_GetMwSt2New ());
  set (ST_CO_mwst2, MUIA_String_Contents, buf);

  str = CO_GetDVIprinter ();
  for (num = 0; CYA_printers[num] &&
       strcmp (CYA_printers[num], str); num++);
  if (!CYA_printers[num])
    num = 0;
  set (CY_CO_prt, MUIA_Cycle_Active, num);

  set (SL_CO_voff, MUIA_Slider_Level, CO_GetDVIVoffset ());
  set (SL_CO_hoff, MUIA_Slider_Level, CO_GetDVIHoffset ());
  set (ST_CO_kopf1, MUIA_String_Contents, CO_GetKopf1 ());
  set (ST_CO_kopf2, MUIA_String_Contents, CO_GetKopf2 ());
  set (ST_CO_fuss1, MUIA_String_Contents, CO_GetFuss1 ());
  set (ST_CO_fuss2, MUIA_String_Contents, CO_GetFuss2 ());
  set (ST_CO_fuss3, MUIA_String_Contents, CO_GetFuss3 ());
  set (ST_CO_fuss4, MUIA_String_Contents, CO_GetFuss4 ());
}


/*
** Lädt alle Konfigurationen ab MIT den Cyclegadgetständen.
*/

static void 
CO_LoadAllConfigs (void)
{
  CO_LoadConfig ();
  set (CY_OL_mode, MUIA_Cycle_Active, CO_GetOrderMode ());
  set (CY_IL_mode, MUIA_Cycle_Active, CO_GetInvoiceMode ());
  set (CY_LL_mode, MUIA_Cycle_Active, CO_GetLetterMode ());
  set (CY_I_mode, MUIA_Cycle_Active, CO_GetInvoiceMwStMode ());
  set (CY_O_mode, MUIA_Cycle_Active, CO_GetOrderMwStMode ());
  set (CY_A_mode, MUIA_Cycle_Active, CO_GetArticleMwStMode ());
  InitConfigWin ();
}

/*
** Speichert alle Konfigurationen ab MIT den Cyclegadgetständen.
** es wird auch das File "TeXwork/invoice.tex" neu erzeugt.
*/


static void 
CO_SaveAllConfigs (void)
{
  LONG num;

  get (CY_IL_mode, MUIA_Cycle_Active, &num);
  CO_SetInvoiceMode (num);
  get (CY_OL_mode, MUIA_Cycle_Active, &num);
  CO_SetOrderMode (num);
  get (CY_LL_mode, MUIA_Cycle_Active, &num);
  CO_SetLetterMode (num);

  get (CY_I_mode, MUIA_Cycle_Active, &num);
  CO_SetInvoiceMwStMode (num);
  get (CY_O_mode, MUIA_Cycle_Active, &num);
  CO_SetOrderMwStMode (num);
  get (CY_A_mode, MUIA_Cycle_Active, &num);
  CO_SetArticleMwStMode (num);

  /* MwSt-Sätze für Cycle-Gadget erstellen */
  PrintMonetary (CYA_MwSt1_buffer, CO_GetMwSt1New ());
  PrintMonetary (CYA_MwSt2_buffer, CO_GetMwSt2New ());
  strcat (CYA_MwSt1_buffer, "%");
  strcat (CYA_MwSt2_buffer, "%");

  if (CO_SaveConfig ())
    MUI_Request (app, WI_main, 0, STRING (MSG_ERR_REQ_TITLE),
                 STRING (MSG_ERR_REQ_BUTTONS),
                 STRING (MSG_CONFIGERR_SAVE_REQ_BODY), CO_GetErrorMsg ());

  if (P_SaveConfig ())		/* TeXwork/invoice.tex erzeugen */
    MUI_Request (app, WI_main, 0, STRING (MSG_ERR_REQ_TITLE),
                 STRING (MSG_ERR_REQ_BUTTONS),
                 STRING (MSG_CONFIGERR_SAVETEX_REQ_BODY), OL_GetErrorMsg ());
}


/*********************************************************************
**
**
**  M A I N
**
**
*********************************************************************/

int 
main (void)
{
  /* Zeiger für "Hauptfenster"  (Buchstabe "M") */

  APTR BT_M_quit, BT_M_prefs, BT_M_ordlist, BT_M_invlist, BT_M_artlist,
    BT_M_custlist, BT_M_letlist, BT_M_label;
  APTR strip;
  ULONG signals;
  BOOL running = TRUE;
  struct NewMenu *menu;
  char **str;

  ULONG event;			/* der Eventcode der Hauptwarteschleife */

  if (ConstructLocale ())
    Quit (NULL, "Locale", L_GetErrorMsg ());

  if (IFFParseBase = OpenLibrary ("iffparse.library", 0))
    {
      clip_handle = OpenClipboard (0);
      undo_handle = OpenClipboard (42);
    }

  if (!(TextFieldBase = OpenLibrary ("gadgets/textfield.gadget", 0)))
    Quit (NULL, STRING (MSG_ERR_TEXTFIELD_HEAD),
          STRING (MSG_ERR_TEXTFIELD_TEXT));
  else
    TextFieldClass = TEXTFIELD_GetClass ();

  if (!(MUIMasterBase = OpenLibrary (MUIMASTER_NAME, MUIMASTER_VMIN)))
    Quit (NULL, STRING (MSG_ERR_MUIMASTER_HEAD),
          STRING (MSG_ERR_MUIMASTER_TEXT));

  /* alle Module initialisieren */

  if (ConstructArticle ())
    Quit (NULL, STRING (MSG_ERR_ARTICLE_HEAD), A_GetErrorMsg ());
  if (ConstructCustomer ())
    Quit (NULL, STRING (MSG_ERR_CUSTOMER_HEAD), C_GetErrorMsg ());
  if (ConstructOrder ())
    Quit (NULL, STRING (MSG_ERR_ORDER_HEAD), O_GetErrorMsg ());
  if (ConstructInvoice ())
    Quit (NULL, STRING (MSG_ERR_INVOICE_HEAD), I_GetErrorMsg ());
  if (ConstructLetter ())
    Quit (NULL, STRING (MSG_ERR_LETTER_HEAD), LE_GetErrorMsg ());
  if (ConstructOrderList ())
    Quit (NULL, STRING (MSG_ERR_ORDERLIST_HEAD), OL_GetErrorMsg ());
  if (ConstructInvoiceList ())
    Quit (NULL, STRING (MSG_ERR_INVOICELIST_HEAD), IL_GetErrorMsg ());
  if (ConstructLetterList ())
    Quit (NULL, STRING (MSG_ERR_LETTERLIST_HEAD), LL_GetErrorMsg ());

  /* lies das Keyfile ein */

  ReadKeyfile (Keyfile);

  /* Anpassung der Cycle-Gadgets an die vorhandenen Jahrgänge */

  Build_OL_years ();
  Build_IL_years ();
  Build_LL_years ();
  CO_LoadConfig ();
  A_LoadArticles ();

  /* 16.4.95: new feature: use exact "netto" -> set all cycles to "brutto" */
  if (CO_GetIsNetto ())
    {
      CO_SetArticleMwStMode (1);
      CO_SetOrderMwStMode (1);
      CO_SetInvoiceMwStMode (1);
    }


  /* MwSt-Sätze für Cycle-Gadget erstellen */
  PrintMonetary (CYA_MwSt1_buffer, CO_GetMwSt1New ());
  PrintMonetary (CYA_MwSt2_buffer, CO_GetMwSt2New ());
  strcat (CYA_MwSt1_buffer, "%");
  strcat (CYA_MwSt2_buffer, "%");

  /* lokalisiere ein paar Strings */

  menu = MenuData1;
  while (menu->nm_Type != NM_END)
    {
      if (menu->nm_Label && menu->nm_Label != NM_BARLABEL)
	menu->nm_Label = CatCompArray[(ULONG) menu->nm_Label].cca_Str;
      if (menu->nm_CommKey)
	menu->nm_CommKey = CatCompArray[(ULONG) menu->nm_CommKey].cca_Str;
      menu++;
    }

  DecodeString (Benutzer);	/* registrierter Benutzer: String dekodieren */

  menu = ConfigMenu;
  while (menu->nm_Type != NM_END)
    {
      if (menu->nm_Label && menu->nm_Label != NM_BARLABEL)
	menu->nm_Label = CatCompArray[(ULONG) menu->nm_Label].cca_Str;
      if (menu->nm_CommKey)
	menu->nm_CommKey = CatCompArray[(ULONG) menu->nm_CommKey].cca_Str;
      menu++;
    }

  for (str = CYA_BruttoNetto; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = artPages; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = RAA_AP_mode; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = CYA_Anrede; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = CustomerModePages; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = CustomerInputPages; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = RAA_CP_mode; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = RAA_CP_list; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  for (str = ConfigPages; *str; str++)
    *str = CatCompArray[(ULONG) * str].cca_Str;
  strcpy (cashcust.Adresse2, STRING (MSG_STRING_CASH));


  app = ApplicationObject,
    MUIA_Application_Title, "MUI-Rechnung",
    MUIA_Application_Version, ProgVersion + 1,
    MUIA_Application_Copyright, "©1993,94,95 Stefan Scherer",
    MUIA_Application_Author, "Stefan Scherer",
    MUIA_Application_Description, STRING (MSG_MUI_SHORT_DESCRIPTION),
    MUIA_Application_Base, "MUIRECH",
    MUIA_Application_HelpFile, "PROGDIR:MUI-Rechnung.guide",

/* Unterfenster "Hauptfenster" */

    SubWindow, WI_main = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_MAIN),
    MUIA_Window_Menustrip, strip = MUI_MakeObject (MUIO_MenustripNM,
                                                   MenuData1, 0),
    MUIA_Window_ID, MAKE_ID ('R', 'E', 'M', 'A'),
    MUIA_HelpNode, "main-window",

    WindowContents, ColGroup (2),
    Child, BT_M_ordlist = KeyButton (STRING (MSG_MAIN_BUTTON_ORDER),
                                     CHAR (MSG_MAIN_BUTTON_ORDER_KEY)),
         Child, BT_M_invlist = KeyButton (STRING (MSG_MAIN_BUTTON_INVOICE),
                                          CHAR (MSG_MAIN_BUTTON_INVOICE_KEY)),
    Child, BT_M_artlist = KeyButton (STRING (MSG_MAIN_BUTTON_ARTICLE),
                                     CHAR (MSG_MAIN_BUTTON_ARTICLE_KEY)),
         Child, BT_M_custlist = KeyButton (STRING (MSG_MAIN_BUTTON_ADDRESS),
                                           CHAR (MSG_MAIN_BUTTON_ADDRESS_KEY)),
    Child, BT_M_letlist = KeyButton (STRING (MSG_MAIN_BUTTON_LETTER),
                                     CHAR (MSG_MAIN_BUTTON_LETTER_KEY)),
         Child, BT_M_label = KeyButton (STRING (MSG_MAIN_BUTTON_LABEL),
                                        CHAR (MSG_MAIN_BUTTON_LABEL_KEY)),
    Child, BT_M_prefs = KeyButton (STRING (MSG_MAIN_BUTTON_CONFIG),
                                   CHAR (MSG_MAIN_BUTTON_CONFIG_KEY)),
         Child, BT_M_quit = KeyButton (STRING (MSG_MAIN_BUTTON_QUIT),
                                       CHAR (MSG_MAIN_BUTTON_QUIT_KEY)),
    End,
    End,

/* Unterfenster "Angebotsliste" */

    SubWindow, WI_letlist = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_LETTERLIST),
    MUIA_Window_ID, MAKE_ID ('L', 'E', 'L', 'I'),
    MUIA_HelpNode, "letterlist-window",
    WindowContents, MUI_BuildLetterList (),
    End,

/* Unterfenster "Auftragsliste" */

    SubWindow, WI_ordlist = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_ORDERLIST),
    MUIA_Window_ID, MAKE_ID ('O', 'R', 'L', 'I'),
    MUIA_HelpNode, "orderlist-window",
    WindowContents, MUI_BuildOrderList (),
    End,

/* Unterfenster "Rechnungsliste" */

    SubWindow, WI_invlist = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_INVOICELIST),
    MUIA_Window_ID, MAKE_ID ('I', 'N', 'L', 'I'),
    MUIA_HelpNode, "invoicelist-window",
    WindowContents, MUI_BuildInvoiceList (),
    End,

/* Unterfenster "Kundenliste" */

    SubWindow, WI_customer = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_CUSTOMER),
    MUIA_Window_ID, MAKE_ID ('K', 'U', 'N', 'D'),
    MUIA_HelpNode, "customer-window",
    WindowContents, MUI_BuildCustomer (),
    End,

/* Unterfenster "Kundenlistendruck" */

    SubWindow, WI_customerprint = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_CUSTOMERPRINT),
    MUIA_Window_ID, MAKE_ID ('K', 'U', 'N', 'P'),
    MUIA_HelpNode, "customerprint-window",
    WindowContents, MUI_BuildCustomerPrint (),
    End,

/* Unterfenster "Auftrag" */

    SubWindow, WI_order = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_ORDER),
    MUIA_Window_ID, MAKE_ID ('A', 'U', 'F', 'T'),
    MUIA_HelpNode, "order-window",
    WindowContents, MUI_BuildOrder (),
    End,

/* Unterfenster "Rechnung" */

    SubWindow, WI_invoice = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_INVOICE),
    MUIA_Window_ID, MAKE_ID ('R', 'E', 'C', 'H'),
    MUIA_HelpNode, "invoice-window",
    WindowContents, MUI_BuildInvoice (),
    End,

/* Unterfenster "Artikelliste" */

    SubWindow, WI_article = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_ARTICLE),
    MUIA_Window_ID, MAKE_ID ('A', 'R', 'T', 'I'),
    MUIA_HelpNode, "article-window",
    WindowContents, MUI_BuildArticleList (),
    End,

/* Unterfenster "Artikellistendruck" */

    SubWindow, WI_articleprint = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_ARTICLEPRINT),
    MUIA_Window_ID, MAKE_ID ('A', 'R', 'T', 'P'),
    MUIA_HelpNode, "articleprint-window",
    WindowContents, MUI_BuildArticlePrint (),
    End,

/* Unterfenster "Konfiguration" */

    SubWindow, WI_config = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_CONFIG),
    MUIA_Window_Menustrip, MUI_MakeObject (MUIO_MenustripNM, ConfigMenu, 0),
    MUIA_Window_ID, MAKE_ID ('C', 'O', 'N', 'F'),
    MUIA_HelpNode, "config-window",
    WindowContents, MUI_BuildConfig (),
    End,

/* Unterfenster "Etikettendruck" */

    SubWindow, WI_label = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_LABEL),
    MUIA_Window_ID, MAKE_ID ('E', 'T', 'I', 'K'),
    MUIA_HelpNode, "label-window",
    WindowContents, VGroup,

    Child, VGroup, GroupFrameT (STRING (MSG_LABEL_GROUP_ADDRESS)),
    Child, BT_E_customer = KeyButton (STRING (MSG_LABEL_BUTTON_CHOOSE),
                                      CHAR (MSG_LABEL_BUTTON_CHOOSE_KEY)),
    Child, ColGroup (2),
    Child, KeyLabel2 (STRING (MSG_LABEL_STRING_ANREDE),
                      CHAR (MSG_LABEL_STRING_ANREDE_KEY)),
           Child, ST_E_adr1 = KeyString ("", 80,
                                         CHAR (MSG_LABEL_STRING_ANREDE_KEY)),
    Child, KeyLabel2 (STRING (MSG_LABEL_STRING_ADDRESS),
                      CHAR (MSG_LABEL_STRING_ADDRESS_KEY)),
           Child, ST_E_adr2 = KeyString ("", 80,
                                         CHAR (MSG_LABEL_STRING_ADDRESS_KEY)),
    Child, Label2 (""), Child, ST_E_adr3 = String ("", 80),
    Child, Label2 (""), Child, ST_E_adr4 = String ("", 80),
    Child, Label2 (""), Child, ST_E_adr5 = String ("", 80),
    End,
    End,

    Child, ColGroup (2), GroupFrameT (STRING (MSG_LABEL_GROUP_LABEL)),
    Child, KeyLabel2 (STRING (MSG_LABEL_SLIDER_COLUMN),
                      CHAR (MSG_LABEL_SLIDER_COLUMN_KEY)),
           Child, SL_E_col = KeySlider (1, CO_GetLabelX (), 1,
                                        CHAR (MSG_LABEL_SLIDER_COLUMN_KEY)),
    Child, KeyLabel2 (STRING (MSG_LABEL_SLIDER_ROW),
                      CHAR (MSG_LABEL_SLIDER_ROW_KEY)),
           Child, SL_E_line = KeySlider (1, CO_GetLabelY (), 1,
                                         CHAR (MSG_LABEL_SLIDER_ROW_KEY)),
    Child, Label2 (""),
        Child, BT_E_print = KeyButton (STRING (MSG_LABEL_BUTTON_PRINTLABEL),
                                       CHAR (MSG_LABEL_BUTTON_PRINTLABEL_KEY)),
    Child, Label2 (""),
        Child, BT_E_visprint = KeyButton (STRING (MSG_LABEL_BUTTON_PRINTVISIT),
                                       CHAR (MSG_LABEL_BUTTON_PRINTVISIT_KEY)),
    End,

    End,
    End,

/* Unterfenster "Briefe, Angebote" */

    SubWindow, WI_letter = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_LETTER),
    MUIA_Window_ID, MAKE_ID ('L', 'E', 'T', 'T'),
    MUIA_HelpNode, "letter-window",
    WindowContents, MUI_BuildLetter (),
    End,

/* Unterfenster "Befehle für Brief" */

    SubWindow, WI_letcomm = WindowObject,
    MUIA_Window_Title, STRING (MSG_WINDOW_TITLE_LETTCOMM),
    MUIA_Window_ID, MAKE_ID ('L', 'E', 'T', 'C'),
    MUIA_HelpNode, "letcomm-window",
    WindowContents, VGroup,
    Child, LV_LC_commands = ListviewObject,
    MUIA_Listview_List, ListObject,
    InputListFrame,
    MUIA_List_AdjustWidth, TRUE,
    MUIA_List_SourceArray, LVA_LC_commands,
    End,
    End,
    End,
    End,

/* weitere Fenster */


    End;

#ifdef DEBUG
  printf ("WI_customerprint=%lx\n", WI_customerprint);
  printf ("WI_articleprint=%lx\n", WI_articleprint);
  printf ("WI_customer=%lx\n", WI_customer);
  printf ("WI_order=%lx\n", WI_order);
  printf ("WI_invoice=%lx\n", WI_invoice);
  printf ("WI_article=%lx\n", WI_article);
  printf ("WI_main=%lx\n", WI_main);
  printf ("WI_config=%lx\n", WI_config);
  printf ("WI_letlist=%lx\n", WI_letlist);
  printf ("WI_invlist=%lx\n", WI_invlist);
  printf ("WI_ordlist=%lx\n", WI_ordlist);
  printf ("WI_article=%lx\n", WI_article);
#endif

  if (!app)
    {
      sprintf (muierrbuf, "MUI (%ld)", MUI_Error ());
      Quit (app, muierrbuf, STRING (MSG_ERR_MUIAPP_TEXT));
    }

  /* Hauptfenster */

  DoMethod (WI_main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_QUIT);
  DoMethod (BT_M_quit, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_QUIT);
  DoMethod (BT_M_letlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_LETLIST);
  DoMethod (BT_M_prefs, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_MEN_PREFS);
  DoMethod (BT_M_invlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_INVLIST);
  DoMethod (BT_M_ordlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_ORDLIST);
  DoMethod (BT_M_artlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_ARTLIST);
  DoMethod (BT_M_custlist, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_CUSTLIST);
  DoMethod (BT_M_label, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_M_LABEL);


  /* für die externen MUI-Module auch DoMethod() aufrufen */

  DoOrderMethods ();
  DoInvoiceMethods ();
  DoLetterMethods ();

  /* Artikelliste */

  DoMethod (WI_article, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift right", REG_A_mode, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Next);
  DoMethod (WI_article, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift left", REG_A_mode, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Prev);
  DoMethod (WI_article, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_A_CANCEL);
  DoMethod (WI_article, MUIM_Notify, MUIA_Window_ActiveObject, LV_A_list, app, 2, MUIM_Application_ReturnID, ID_A_LIST);
  DoMethod (BT_A_print, MUIM_Notify, MUIA_Pressed, FALSE, WI_articleprint, 3, MUIM_Set, MUIA_Window_Open, TRUE);
  DoMethod (BT_A_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_OK);
  DoMethod (BT_A_cancel, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_CANCEL);
  DoMethod (LV_A_list, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app, 2, MUIM_Application_ReturnID, ID_A_OKcheck);
  DoMethod (LV_A_list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_LIST);
  DoMethod (BT_A_insert, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_INSERT);
  DoMethod (BT_A_change, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_CHANGE);
  DoMethod (BT_A_delete, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_DELETE);
  DoMethod (BT_A_popinsert, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_POPINSERT);
  DoMethod (BT_A_popchange, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_POPCHANGE);
  DoMethod (BT_A_popdelete, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_POPDELETE);
  DoMethod (BT_A_clear, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_CLEAR);
  DoMethod (BT_A_sclear, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_SCLEAR);
  DoMethod (BT_A_sall, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_SALL);
  DoMethod (BT_A_search, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_SEARCH);
  DoMethod (BT_A_today, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_A_TODAY);
  DoMethod (ST_A_EKeinzel, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_INPUT);
  DoMethod (ST_A_EKversand, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_INPUT);
  DoMethod (ST_A_zuschlag, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_INPUT);
  DoMethod (ST_A_VKeinzel, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_INPUT);
//   DoMethod(REG_A_mode,MUIM_Notify,MUIA_Group_ActivePage,MUIV_EveryTime,WI_article,3,MUIM_Set,MUIA_Window_ActiveObject,LV_A_list);
  DoMethod (CY_A_mwst, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_INPUT);
  DoMethod (LV_A_pop, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, POP_A_mode, 2, MUIM_Popstring_Close, TRUE);
  DoMethod (ST_A_pop, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_LISTMODE);
  DoMethod (CY_A_mode, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_A_BRUTTONETTO);
  set (CY_A_mode, MUIA_Cycle_Active, CO_GetArticleMwStMode ());
  /* 16.4.95: ghost the cycle gadget */
  if (CO_GetIsNetto ())
    set (CY_A_mode, MUIA_Disabled, TRUE);
  DoMethod (WI_article, MUIM_Window_SetCycleChain, LV_A_list, ST_A_number, ST_A_article, ST_A_menge,
	    ST_A_EKeinzel, ST_A_EKversand,
	    CY_A_mwst, ST_A_VKeinzel, ST_A_zuschlag, ST_A_VGLeinzel, ST_A_date, ST_A_firma, ST_A_note,
	    ST_A_snumber, ST_A_sbezeichnung,
	    NULL);

  /* Artikellistendruck */

  DoMethod (WI_articleprint, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, WI_articleprint, 3, MUIM_Set, MUIA_Window_Open, FALSE);
  DoMethod (BT_AP_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_AP_OK);
  DoMethod (BT_AP_cancel, MUIM_Notify, MUIA_Pressed, FALSE, WI_articleprint, 3, MUIM_Set, MUIA_Window_Open, FALSE);

  set (WI_article, MUIA_Window_ActiveObject, LV_A_list);
  Redraw_A_List ();

  /* Kundenliste */

  DoMethod (WI_customer, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift right", REG_C_input, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Next);
  DoMethod (WI_customer, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift left", REG_C_input, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Prev);
  DoMethod (BT_C_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_OK);
  DoMethod (BT_C_print, MUIM_Notify, MUIA_Pressed, FALSE, WI_customerprint, 3, MUIM_Set, MUIA_Window_Open, TRUE);
  DoMethod (LV_C_list, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, app, 2, MUIM_Application_ReturnID, ID_C_OKcheck);
  DoMethod (BT_C_cancel, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_CANCEL);
  DoMethod (WI_customer, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_C_CANCEL);
  DoMethod (WI_customer, MUIM_Notify, MUIA_Window_ActiveObject, LV_C_list, app, 2, MUIM_Application_ReturnID, ID_C_LIST);
  DoMethod (LV_C_list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_C_LIST);
  DoMethod (BT_C_insert, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_INSERT);
  DoMethod (BT_C_change, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_CHANGE);
  DoMethod (BT_C_delete, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_DELETE);
  DoMethod (BT_C_clear, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_CLEAR);
  DoMethod (BT_C_popinsert, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_POPINSERT);
  DoMethod (BT_C_popchange, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_POPCHANGE);
  DoMethod (BT_C_popdelete, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_POPDELETE);
  DoMethod (BT_C_sclear, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_SCLEAR);
  DoMethod (BT_C_sall, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_SALL);
  DoMethod (BT_C_search, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_C_SEARCH);
  DoMethod (ST_C_patadr, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_C_INPUT);
  DoMethod (ST_C_patadr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, WI_customer, 3, MUIM_Set, MUIA_Window_ActiveObject, LV_C_list);
  DoMethod (LV_C_pop, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, POP_C_mode, 2, MUIM_Popstring_Close, TRUE);
  DoMethod (ST_C_pop, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_C_LISTMODE);
  DoMethod (WI_customer, MUIM_Window_SetCycleChain, LV_C_list, ST_C_patadr, CY_C_anrede, ST_C_zeichen, ST_C_adr2, ST_C_adr3, ST_C_adr4, ST_C_adr5,
	    ST_C_phone, ST_C_fax, ST_C_remark1, ST_C_remark2,
   ST_C_snumber, CY_C_sanrede, ST_C_szeichen, ST_C_sadr, ST_C_sphone, NULL);
  set (CY_C_sanrede, MUIA_Cycle_Active, 3);	/* auf leere Anrede stellen */
  Redraw_C_List ();

  /* Kundenlistendruck */

  DoMethod (WI_customerprint, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, WI_customerprint, 3, MUIM_Set, MUIA_Window_Open, FALSE);
  DoMethod (BT_CP_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CP_OK);
  DoMethod (BT_CP_cancel, MUIM_Notify, MUIA_Pressed, FALSE, WI_customerprint, 3, MUIM_Set, MUIA_Window_Open, FALSE);

  /* Konfiguration */

  DoMethod (WI_config, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift right", REG_CO_pages, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Next);
  DoMethod (WI_config, MUIM_Notify, MUIA_Window_InputEvent, "rawkey -capslock -shift left", REG_CO_pages, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_Group_ActivePage_Prev);
  DoMethod (BT_CO_ok, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CO_OK);
  DoMethod (BT_CO_cancel, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CO_CANCEL);
  DoMethod (BT_CO_offset, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CO_OFFSET);
  DoMethod (WI_config, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_CO_CANCEL);
  DoMethod (WI_config, MUIM_Window_SetCycleChain, ST_CO_firmaname, ST_CO_inhaber, ST_CO_str, ST_CO_ort,
	    ST_CO_zeichen, ST_CO_bankname, ST_CO_blz, ST_CO_konto, ST_CO_phonevorwahl, ST_CO_phone, ST_CO_faxvorwahl, ST_CO_fax, ST_CO_kopf1,
	    ST_CO_kopf2, ST_CO_fuss1, ST_CO_fuss2, ST_CO_fuss3, ST_CO_fuss4, CY_CO_prt, SL_CO_voff, SL_CO_hoff, NULL);


  /* Etikettenfenster */

  DoMethod (WI_label, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, ID_E_OK);
  DoMethod (BT_E_print, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_E_PRINT);
  DoMethod (BT_E_visprint, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_E_PRINTVISIT);
  DoMethod (BT_E_customer, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_E_CUSTOMER);
  DoMethod (WI_label, MUIM_Window_SetCycleChain, ST_E_adr1, ST_E_adr2, ST_E_adr3, ST_E_adr4, ST_E_adr5, NULL);


/*
** Input loop...
*/

  set (WI_main, MUIA_Window_Open, TRUE);
  set (WI_main, MUIA_Window_ActiveObject, BT_M_invlist);

  while (running)
    {
      event = DoMethod (app, MUIM_Application_Input, &signals);

      if (event >= ID_LL_BASE)
	{
	  HandleLetterEvents (event);
	}
      if (event >= ID_OL_BASE)
	{
	  HandleOrderEvents (event);
	}
      else if (event >= ID_IL_BASE)
	{
	  HandleInvoiceEvents (event);
	}
      else
	switch (event)
	  {
	  case ID_QUIT:
	    if (C_CheckAbort (FALSE) && A_CheckAbort (FALSE) &&
	        I_CheckAbort (FALSE) && O_CheckAbort (FALSE) &&
	        CO_CheckAbort (FALSE) && LE_CheckAbort (FALSE))
	      running = FALSE;
	    break;

	  case ID_ABSQUIT:
	    running = FALSE;
	    break;

	    /* Hauptfenster (Dock) */

	  case ID_M_LETLIST:
	    /* Angebotsliste öffnen */
	    set (WI_letlist, MUIA_Window_Open, TRUE);
	    break;

	  case ID_M_INVLIST:
	    /* Rechnungsliste öffnen */
	    set (WI_invlist, MUIA_Window_Open, TRUE);
	    break;

	  case ID_M_ORDLIST:
	    /* Auftragsliste öffnen */
	    set (WI_ordlist, MUIA_Window_Open, TRUE);
	    break;

	  case ID_M_CUSTLIST:
	    /* Kundenliste öffnen */
	    if (C_CheckAbort (FALSE))
	      {
		closeCustomerAction = CCA_MAIN;
		InitCustomerWin (0);
		set (WI_customer, MUIA_Window_Title,
		     STRING (MSG_WINDOW_TITLE_CUSTOMER));
		set (WI_customer, MUIA_Window_Open, TRUE);
	      }
	    break;

	  case ID_M_ARTLIST:
	    /* Artikelliste öffnen */
	    if (A_CheckAbort (FALSE))
	      {
		closeArticleAction = CAA_MAIN;
		InitArticleWin ();
		set (WI_article, MUIA_Window_Title,
		     STRING (MSG_WINDOW_TITLE_ARTICLE));
		set (WI_article, MUIA_Window_Open, TRUE);
	      }
	    break;

	  case ID_M_LABEL:
	    /* Etikettenfenster öffnen */
	    set (WI_label, MUIA_Window_Open, TRUE);
	    break;

	    /* Menü */

	  case ID_ABOUT:
	    switch (MUI_Request (app, WI_main, 0, STRING (MSG_ABOUT_REQ_TITLE),
	                         STRING (MSG_ABOUT_REQ_BUTTONS),
				 STRING (MSG_ABOUT_REQ_BODY),
				 ProgVersion + 7, oldchecksum, Benutzer))
	      {
	      case 2:
		MUI_Request (app, WI_main, 0, STRING (MSG_AUTHOR_REQ_TITLE),
		             STRING (MSG_AUTHOR_REQ_BUTTONS),
			     STRING (MSG_AUTHOR_REQ_BODY),
			     "Stefan Scherer\n"
			     "An der Fehdenwiese 1\n"
			     "91334 Hemhofen\n"
			     "Tel: 09195/994970\n"
			     "EMail: bf110@fim.uni-erlangen.de");
		break;

	      default:
		break;
	      }
	    break;

	  case ID_MEN_HELP:
	    DoMethod (app, MUIM_Application_ShowHelp, WI_main,
	              "MUI-Rechnung.guide", "Main", 1);
	    break;

	  case ID_MEN_HELP_INDEX:
	    DoMethod (app, MUIM_Application_ShowHelp, WI_main,
	              "MUI-Rechnung.guide", "Index", 1);
	    break;

	  case ID_MEN_HELP_NEWS:
	    DoMethod (app, MUIM_Application_ShowHelp, WI_main,
	              "MUI-Rechnung.guide", "news", 1);
	    break;

	  case ID_MEN_PREFS:
	    InitConfigWin ();
	    set (WI_config, MUIA_Window_Open, TRUE);
	    break;


	    /* Kundenliste */

	  case ID_C_LISTMODE:
	    /* die Kategorie wurde verändert. Liste neu aufbauen */
	    {
	      Redraw_C_List ();
	    }
	    break;

	  case ID_C_POPINSERT:
	    /* neue Kategorie in Liste einfügen */
	    {
	      STRPTR str;

	      get (ST_C_pop, MUIA_String_Contents, &str);
	      C_AddCategory (str);
	      DoMethod (LV_C_pop, MUIM_List_InsertSingle, str,
	                MUIV_List_Insert_Sorted);
	      set (LV_C_pop, MUIA_List_Active, C_GetCurrentCategoryNumber ());
	    }
	    break;

	  case ID_C_POPCHANGE:
	    /* Kategorie in Liste ändern */
	    {
	      STRPTR str;
	      LONG num;

	      if (C_GetCategoryCount () > 0)
		{
		  get (LV_C_pop, MUIA_List_Active, &num);
		  if (num != MUIV_List_Active_Off)
		    {
		      C_SetCurrentCategory (num);
		      DoMethod (LV_C_pop, MUIM_List_Remove,
		                MUIV_List_Remove_Active);

		      get (ST_C_pop, MUIA_String_Contents, &str);
		      C_ChangeCategory (str);
		      DoMethod (LV_C_pop, MUIM_List_InsertSingle, str,
		                MUIV_List_Insert_Sorted);
		      set (LV_C_pop, MUIA_List_Active,
		           C_GetCurrentCategoryNumber ());
		    }
		}
	    }
	    break;

	  case ID_C_POPDELETE:
	    /* Kategorie aus Liste löschen */
	    {
	      LONG num;

	      if (C_GetCategoryCount () > 0)
		{
		  get (LV_C_pop, MUIA_List_Active, &num);
		  C_SetCurrentCategory (num);

		  C_DelCategory ();
		  DoMethod (LV_C_pop, MUIM_List_Remove,
		            MUIV_List_Remove_Active);

		  set (LV_C_pop, MUIA_List_Active,
		       C_GetCurrentCategoryNumber ());
		}
	    }
	    break;

	  case ID_C_LIST:
	    /* Benutzer wählt einen Kunden aus der Liste aus
	    ** Es kann aber auch sein, daß wir softwaremäßig einen Kunden
	    ** in der Liste selektiert haben. Dann soll zunächst nichts
	    ** passieren -- wenn dies geht :-)
	    */
	    {
	      struct Customer *active;
	      struct Customer cust;
	      APTR obj;

	      get (WI_customer, MUIA_Window_ActiveObject, &obj);
	      DoMethod (LV_C_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  LONG num;
		  char buf[10];

		  get (LV_C_list, MUIA_List_Active, &num);
		  C_SetCurrentCustomer (active->KundenNummer);

		  C_GetCurrentCustomer (&cust);

		  set (ST_C_adr2, MUIA_String_Contents, cust.Adresse2);
		  set (ST_C_adr3, MUIA_String_Contents, cust.Adresse3);
		  set (ST_C_adr4, MUIA_String_Contents, cust.Adresse4);
		  set (ST_C_adr5, MUIA_String_Contents, cust.Adresse5);
		  set (ST_C_zeichen, MUIA_String_Contents, cust.Zeichen);
		  if (cust.KundenNummer)
		    sprintf (buf, "%d", cust.KundenNummer);
		  else
		    buf[0] = 0;
		  set (ST_C_number, MUIA_String_Contents, buf);
		  set (ST_C_phone, MUIA_String_Contents, cust.Telefon);
		  set (ST_C_fax, MUIA_String_Contents, cust.Fax);
		  set (ST_C_remark1, MUIA_String_Contents, cust.Kommentar1);
		  set (ST_C_remark2, MUIA_String_Contents, cust.Kommentar2);

		  num = SearchAnrede (cust.Adresse1);
		  set (CY_C_anrede, MUIA_Cycle_Active, num);
		}
	      else
		Clear_C_Inputs ();
	      set (REG_C_mode, MUIA_Group_ActivePage,
	           MUIV_Group_ActivePage_First);
	    }
	    break;

	  case ID_C_INPUT:
	    /* Name wurde verändert -> Liste dorthin bewegen */
	    {
	      struct Customer cust;
	      LONG num;
	      STRPTR str;
	      APTR obj;

	      get (WI_customer, MUIA_Window_ActiveObject, &obj);
	      if (obj == ST_C_patadr)
		{
		  /* ok, das Stringgadget ist aktiv, also muß die Liste
		  ** auf eine neue Position gebracht werden.
		  */

		  get (ST_C_patadr, MUIA_String_Contents, &str);
		  strcpy (cust.Adresse2, str);
		  C_SetCurrentCustomerNumber (
		     C_GetNearestCustomerNumber (&cust));
		  get (LV_C_list, MUIA_List_Entries, &num);

		  if (num != C_GetCustomerCount ())
		    Redraw_C_List ();	/* alle Adressen darstellen */
		  else
		    set (LV_C_list, MUIA_List_Active,
		         C_GetCurrentCustomerNumber ());
		}
	    }
	    break;

	  case ID_C_INSERT:
	    /* neuen Kunden in Liste einfügen */
	    {
	      struct Customer cust;
	      LONG num;
	      STRPTR str;

	      get (CY_C_anrede, MUIA_Cycle_Active, &num);
	      strcpy (cust.Adresse1, CYA_Anrede[num]);
	      get (ST_C_adr2, MUIA_String_Contents, &str);
	      strcpy (cust.Adresse2, str);
	      get (ST_C_adr3, MUIA_String_Contents, &str);
	      strcpy (cust.Adresse3, str);
	      get (ST_C_adr4, MUIA_String_Contents, &str);
	      strcpy (cust.Adresse4, str);
	      get (ST_C_adr5, MUIA_String_Contents, &str);
	      strcpy (cust.Adresse5, str);
	      get (ST_C_zeichen, MUIA_String_Contents, &str);
	      strcpy (cust.Zeichen, str);
	      get (ST_C_phone, MUIA_String_Contents, &str);
	      strcpy (cust.Telefon, str);
	      get (ST_C_fax, MUIA_String_Contents, &str);
	      strcpy (cust.Fax, str);
	      get (ST_C_remark1, MUIA_String_Contents, &str);
	      strcpy (cust.Kommentar1, str);
	      get (ST_C_remark2, MUIA_String_Contents, &str);
	      strcpy (cust.Kommentar2, str);
	      get (ST_C_pop, MUIA_String_Contents, &str);
	      strcpy (cust.Kategorie, str);
	      get (ST_C_number, MUIA_String_Contents, &str);
	      if (strchr (str, '?'))
	        {
		/* -1 = neue Kundennummer suchen lassen */
		cust.KundenNummer = 0xffff;
	        }
	      else
	        {
		cust.KundenNummer = atol (str);
	        }
	      C_AddCustomer (&cust);

	      Redraw_C_List ();
	    }
	    break;

	  case ID_C_DELETE:
	    /* Kunden aus Liste löschen */
	    {
	      struct Customer *active;

	      DoMethod (LV_C_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  C_DelCustomer ();
		  DoMethod (LV_C_list, MUIM_List_Remove,
		            MUIV_List_Remove_Active);
		  DoMethod (LV_C_list, MUIM_List_GetEntry,
		            MUIV_List_GetEntry_Active, &active);
		  if (!active)
		    Clear_C_Inputs ();
		}
	    }
	    break;

	  case ID_C_CHANGE:
	    /* Kunden in Liste ändern */
	    {
	      struct Customer cust;
	      struct Customer *active;
	      STRPTR str;
	      LONG num;

	      DoMethod (LV_C_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  /* alte Daten lesen */
		  C_GetCurrentCustomer (&cust);

		  /* und mit neuen Daten überschreiben */
		  get (LV_C_list, MUIA_List_Active, &active);

		  get (CY_C_anrede, MUIA_Cycle_Active, &num);
		  strcpy (cust.Adresse1, CYA_Anrede[num]);
		  get (ST_C_adr2, MUIA_String_Contents, &str);
		  strcpy (cust.Adresse2, str);
		  get (ST_C_adr3, MUIA_String_Contents, &str);
		  strcpy (cust.Adresse3, str);
		  get (ST_C_adr4, MUIA_String_Contents, &str);
		  strcpy (cust.Adresse4, str);
		  get (ST_C_adr5, MUIA_String_Contents, &str);
		  strcpy (cust.Adresse5, str);
		  get (ST_C_zeichen, MUIA_String_Contents, &str);
		  strcpy (cust.Zeichen, str);
		  get (ST_C_phone, MUIA_String_Contents, &str);
		  strcpy (cust.Telefon, str);
		  get (ST_C_fax, MUIA_String_Contents, &str);
		  strcpy (cust.Fax, str);
		  get (ST_C_remark1, MUIA_String_Contents, &str);
		  strcpy (cust.Kommentar1, str);
		  get (ST_C_remark2, MUIA_String_Contents, &str);
		  strcpy (cust.Kommentar2, str);
		  get (ST_C_pop, MUIA_String_Contents, &str);
		  strcpy (cust.Kategorie, str);
		  get (ST_C_number, MUIA_String_Contents, &str);
		  cust.KundenNummer = atol (str);
		  C_ChangeCustomer (&cust);

		  Redraw_C_List ();
		}
	    }
	    break;

	  case ID_C_CLEAR:
	    if (C_CheckAbort (TRUE))
	      {
		Clear_C_Inputs ();
		set (REG_C_input, MUIA_Group_ActivePage,
		     MUIV_Group_ActivePage_First);
		set (WI_customer, MUIA_Window_ActiveObject, ST_C_adr2);
	      }
	    break;

	  case ID_C_SCLEAR:
	    Clear_C_SInputs ();
	    set (WI_customer, MUIA_Window_ActiveObject, ST_C_snumber);
	    break;

	  case ID_C_SEARCH:
	    Redraw_C_SList ();
	    break;

	  case ID_C_SALL:
	    Redraw_C_List ();
	    break;

	  case ID_C_OKcheck:
	    if (closeCustomerAction == CCA_MAIN)
	      break;
	    /* else fall trough ... */
	  case ID_C_OK:
	    if (C_CheckAbort (TRUE))
	      {
		switch (closeCustomerAction)
		  {

		  case CCA_MAIN:
		    break;

		  case CCA_INVOICE:
		    {
		      struct Customer cust;
		      char buffer[20];

		      C_GetCurrentCustomer (&cust);
		      I_SetInvoiceAddress ((struct MinCustomer *) &cust);

		      set (ST_I_adr1, MUIA_String_Contents, cust.Adresse1);
		      set (ST_I_adr2, MUIA_String_Contents, cust.Adresse2);
		      set (ST_I_adr3, MUIA_String_Contents, cust.Adresse3);
		      set (ST_I_adr4, MUIA_String_Contents, cust.Adresse4);
		      set (ST_I_adr5, MUIA_String_Contents, cust.Adresse5);

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

		      set (ST_I_zeichen, MUIA_String_Contents, cust.Zeichen);
		    }
		    break;

		  case CCA_LETTER:
		    {
		      struct Customer cust;
		      char buffer[20];

		      C_GetCurrentCustomer (&cust);
		      LE_SetLetterAddress ((struct MinCustomer *) &cust);

		      set (ST_LE_adr1, MUIA_String_Contents, cust.Adresse1);
		      set (ST_LE_adr2, MUIA_String_Contents, cust.Adresse2);
		      set (ST_LE_adr3, MUIA_String_Contents, cust.Adresse3);
		      set (ST_LE_adr4, MUIA_String_Contents, cust.Adresse4);
		      set (ST_LE_adr5, MUIA_String_Contents, cust.Adresse5);
		      if (cust.KundenNummer)
			{
			  sprintf (buffer, "%d", cust.KundenNummer);
			  set (ST_LE_kundennr, MUIA_String_Contents, buffer);
			}
		      else
			set (ST_LE_kundennr, MUIA_String_Contents, "");

		      set (ST_LE_zeichen, MUIA_String_Contents, cust.Zeichen);
		    }
		    break;

		  case CCA_ORDER:
		    /* gewählten Kunden in Auftrag übernehmen */
		    {
		      struct Customer cust;
		      char buffer[20];

		      C_GetCurrentCustomer (&cust);
		      O_SetOrderAddress ((struct MinCustomer *) &cust);

		      set (ST_O_adr1, MUIA_String_Contents, cust.Adresse1);
		      set (ST_O_adr2, MUIA_String_Contents, cust.Adresse2);
		      set (ST_O_adr3, MUIA_String_Contents, cust.Adresse3);
		      set (ST_O_adr4, MUIA_String_Contents, cust.Adresse4);
		      set (ST_O_adr5, MUIA_String_Contents, cust.Adresse5);
		      if (cust.KundenNummer)
			{
			  sprintf (buffer, "%d", cust.KundenNummer);
			  set (ST_O_kundennr, MUIA_String_Contents, buffer);
			}
		      else
			set (ST_O_kundennr, MUIA_String_Contents, "");

		      set (ST_O_zeichen, MUIA_String_Contents, cust.Zeichen);
		    }
		    break;

		  case CCA_LABEL:
		    {
		      struct Customer cust;
		      C_GetCurrentCustomer (&cust);
		      set (ST_E_adr1, MUIA_String_Contents, cust.Adresse1);
		      set (ST_E_adr2, MUIA_String_Contents, cust.Adresse2);
		      set (ST_E_adr3, MUIA_String_Contents, cust.Adresse3);
		      set (ST_E_adr4, MUIA_String_Contents, cust.Adresse4);
		      set (ST_E_adr5, MUIA_String_Contents, cust.Adresse5);
		    }
		    break;
		  }
		if (C_SaveCustomerList ())
		  MUI_Request (app, WI_main, 0, STRING (MSG_ERR_REQ_TITLE),
		               STRING (MSG_ERR_REQ_BUTTONS),
		               STRING (MSG_CUSTOMERERR_SAVE_REQ_BODY),
		               C_GetErrorMsg ());
		set (WI_customerprint, MUIA_Window_Open, FALSE);
		set (WI_customer, MUIA_Window_Open, FALSE);
	      }
	    break;

	  case ID_C_CANCEL:
	    if (C_CheckAbort (FALSE))
	      {
		switch (closeCustomerAction)
		  {
		  case CCA_MAIN:
		  case CCA_INVOICE:
		  case CCA_LETTER:
		  case CCA_ORDER:
		  case CCA_LABEL:
		    break;
		  }
		set (WI_customerprint, MUIA_Window_Open, FALSE);
		set (WI_customer, MUIA_Window_Open, FALSE);
	      }
	    break;

	  case ID_CP_OK:
	    {
	      /* Ausdruck der Kundenliste, je nach Einstellungen */

	      ULONG mode, list;
	      STRPTR str;
	      STRPTR name;
	      struct Screen *scr;

	      get (WI_main, MUIA_Window_Screen, &scr);
	      name = GetPublicScreenName (scr);

	      get (RA_CP_mode, MUIA_Radio_Active, &mode);
	      get (RA_CP_list, MUIA_Radio_Active, &list);
	      get (ST_C_pop, MUIA_String_Contents, &str);

#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, TRUE);
#endif
	      P_PrintCust (mode, list, str, name);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, FALSE);
#endif
	    }
	    break;


	    /* Konfiguration */

	  case ID_CO_OFFSET:
	    /* Druckeroffsets testen */
	    {
	      STRPTR name;
	      struct Screen *scr;
	      LONG num;
	      LONG hbuf, vbuf;
	      char prtbuf[80];

	      get (WI_main, MUIA_Window_Screen, &scr);
	      name = GetPublicScreenName (scr);

	      hbuf = CO_GetDVIHoffset ();
	      vbuf = CO_GetDVIVoffset ();
	      strcpy (prtbuf, CO_GetDVIprinter ());

	      get (CY_CO_prt, MUIA_Cycle_Active, &num);
	      CO_SetDVIprinter (CYA_printers[num]);
	      get (SL_CO_voff, MUIA_Slider_Level, &num);
	      CO_SetDVIVoffset (num);
	      get (SL_CO_hoff, MUIA_Slider_Level, &num);
	      CO_SetDVIHoffset (num);

#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, TRUE);
#endif
	      P_PrintTest (name);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, FALSE);
#endif
	      /* Zunächst wieder die alten Werte intern speichern. Beim
	      ** späteren OK können dann die Werte erneut übernommen werden.
	      */
	      CO_SetDVIprinter (prtbuf);
	      CO_SetDVIHoffset (hbuf);
	      CO_SetDVIVoffset (vbuf);
	    }
	    break;

	  case ID_CO_OK:
	    /* Konfiguration übernehmen */
	    {
	      STRPTR s;
	      LONG num;
	      double d;

	      get (ST_CO_bankname, MUIA_String_Contents, &s);
	      CO_SetBankName (s);
	      get (ST_CO_blz, MUIA_String_Contents, &s);
	      CO_SetBLZ (s);
	      get (ST_CO_konto, MUIA_String_Contents, &s);
	      CO_SetKontonr (s);
	      get (ST_CO_phonevorwahl, MUIA_String_Contents, &s);
	      CO_SetPhoneVorwahl (s);
	      get (ST_CO_phone, MUIA_String_Contents, &s);
	      CO_SetPhone (s);
	      get (ST_CO_faxvorwahl, MUIA_String_Contents, &s);
	      CO_SetFaxVorwahl (s);
	      get (ST_CO_fax, MUIA_String_Contents, &s);
	      CO_SetFax (s);
	      get (ST_CO_zeichen, MUIA_String_Contents, &s);
	      CO_SetZeichen (s);
	      get (ST_CO_firmaname, MUIA_String_Contents, &s);
	      CO_SetFirma (s);
	      get (ST_CO_inhaber, MUIA_String_Contents, &s);
	      CO_SetInhaber (s);
	      get (ST_CO_str, MUIA_String_Contents, &s);
	      CO_SetStrasse (s);
	      get (ST_CO_ort, MUIA_String_Contents, &s);
	      CO_SetOrt (s);
	      get (CY_CO_prt, MUIA_Cycle_Active, &num);
	      CO_SetDVIprinter (CYA_printers[num]);
	      get (SL_CO_voff, MUIA_Slider_Level, &num);
	      CO_SetDVIVoffset (num);
	      get (SL_CO_hoff, MUIA_Slider_Level, &num);
	      CO_SetDVIHoffset (num);

	      get (ST_CO_mwst1, MUIA_String_Contents, &s);
	      d = ScanMonetary (s);
	      CO_SetMwSt1 (d);
	      get (ST_CO_mwst2, MUIA_String_Contents, &s);
	      d = ScanMonetary (s);
	      CO_SetMwSt2 (d);

	      get (ST_CO_kopf1, MUIA_String_Contents, &s);
	      CO_SetKopf1 (s);
	      get (ST_CO_kopf2, MUIA_String_Contents, &s);
	      CO_SetKopf2 (s);

	      get (ST_CO_fuss1, MUIA_String_Contents, &s);
	      CO_SetFuss1 (s);
	      get (ST_CO_fuss2, MUIA_String_Contents, &s);
	      CO_SetFuss2 (s);
	      get (ST_CO_fuss3, MUIA_String_Contents, &s);
	      CO_SetFuss3 (s);
	      get (ST_CO_fuss4, MUIA_String_Contents, &s);
	      CO_SetFuss4 (s);
	    }
	    CO_SaveAllConfigs ();
	    set (WI_config, MUIA_Window_Open, FALSE);
	    break;

	  case ID_CO_CANCEL:
	    /* Konfiguration abbrechen */
	    if (CO_CheckAbort (FALSE))
	      {
		set (WI_config, MUIA_Window_Open, FALSE);
	      }
	    break;

	  case ID_CO_MEN_LOAD:
	    /* Konfiguration wieder laden */
	    CO_LoadAllConfigs ();
	    break;

	  case ID_CO_MEN_SAVE:
	    /* Konfiguration sofort speichern */
	    CO_SaveAllConfigs ();
	    break;


	    /* Etikettenfenster */

	  case ID_E_OK:
	    /* Etikettenfenster schließen */
	    set (WI_label, MUIA_Window_Open, FALSE);
	    if (closeCustomerAction == CCA_LABEL)
	      {
		set (WI_customer, MUIA_Window_Title,
		     CHAR (MSG_WINDOW_TITLE_CUSTOMER));
		closeCustomerAction = CCA_MAIN;
	      }
	    break;

	  case ID_E_CUSTOMER:
	    /* Kunde für Etikett wählen */
	    if (C_CheckAbort (FALSE))
	      {
		closeCustomerAction = CCA_LABEL;
		InitCustomerWin (0);
		set (WI_customer, MUIA_Window_Title,
		     STRING (MSG_WINDOW_TITLE_CUSTOMER_LABEL));
		set (WI_customer, MUIA_Window_Open, TRUE);
	      }
	    break;

	  case ID_E_PRINT:
	    /* Etikett ausdrucken */
	    {
	      LONG col, line;
	      STRPTR s1, s2, s3, s4, s5, name;
	      struct Screen *scr;

	      get (SL_E_col, MUIA_Slider_Level, &col);
	      get (SL_E_line, MUIA_Slider_Level, &line);
	      get (ST_E_adr1, MUIA_String_Contents, &s1);
	      get (ST_E_adr2, MUIA_String_Contents, &s2);
	      get (ST_E_adr3, MUIA_String_Contents, &s3);
	      get (ST_E_adr4, MUIA_String_Contents, &s4);
	      get (ST_E_adr5, MUIA_String_Contents, &s5);

	      get (WI_main, MUIA_Window_Screen, &scr);
	      name = GetPublicScreenName (scr);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, TRUE);
#endif
	      P_PrintLabel (name, col, line, s1, s2, s3, s4, s5);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, FALSE);
#endif
	    }
	    break;

	  case ID_E_PRINTVISIT:
	    /* Visitenkarte ausdrucken */
	    {
	      LONG col, line;
	      STRPTR name;
	      struct Screen *scr;

	      get (SL_E_col, MUIA_Slider_Level, &col);
	      get (SL_E_line, MUIA_Slider_Level, &line);

	      get (WI_main, MUIA_Window_Screen, &scr);
	      name = GetPublicScreenName (scr);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, TRUE);
#endif
	      P_PrintVisit (name, col, line);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, FALSE);
#endif
	    }
	    break;

	    /* Artikelliste */

	  case ID_A_LIST:
	    /* Benutzer wählt einen Artikel aus der Liste aus */
	    {
	      struct Article *active;
	      struct Article article;
	      DoMethod (LV_A_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  char buf[20];

		  A_SetCurrentArticle (active);

		  A_GetCurrentItem (&article);

		  set (ST_A_number, MUIA_String_Contents,
		       article.Artikelnummer);
		  set (ST_A_article, MUIA_String_Contents,
		       article.Bezeichnung);
		  PrintMonetary (buf, article.Menge);
		  set (ST_A_menge, MUIA_String_Contents, buf);
		  DisplayBetrag (buf, article.Betrag,
		                 CO_GetMwSt (article.Preistabelle),
		                 CO_GetArticleMwStMode ());
		  set (ST_A_VKeinzel, MUIA_String_Contents, buf);
		  PrintCurrency (buf, article.EKBetrag);
		  set (ST_A_EKeinzel, MUIA_String_Contents, buf);
		  PrintCurrency (buf, article.EKVersand);
		  set (ST_A_EKversand, MUIA_String_Contents, buf);
		  DisplayBetrag (buf, article.VGLBetrag,
		                 CO_GetMwSt (article.Preistabelle),
		                 CO_GetArticleMwStMode ());
		  set (ST_A_VGLeinzel, MUIA_String_Contents, buf);
		  set (ST_A_date, MUIA_String_Contents, article.Datum);
		  set (ST_A_firma, MUIA_String_Contents, article.Lieferfirma);
		  set (ST_A_note, MUIA_String_Contents, article.Notiz);
		  set (CY_A_mwst, MUIA_Cycle_Active, article.Preistabelle - 1);
		}
	      else
		Clear_A_Inputs ();

	      set (REG_A_inputmode, MUIA_Group_ActivePage,
	           MUIV_Group_ActivePage_First);
	    }
	    break;

	  case ID_A_LISTMODE:
	    /* die Kategorie wurde verändert. Liste neu aufbauen */
	    {
	      Redraw_A_List ();
	    }
	    break;

	  case ID_A_BRUTTONETTO:
	    /* Darstellung Brutto/Netto ändern */
	    {
	      LONG num, newmode;
	      char buffer[20];
	      double betrag;
	      STRPTR str;
	      UWORD preistab;

	      get (CY_A_mode, MUIA_Cycle_Active, &newmode);

	      get (CY_A_mwst, MUIA_Cycle_Active, &num);
	      preistab = num + 1;

	      /* den minimalen Verkaufspreis wandeln */
	      get (TX_A_brutto, MUIA_Text_Contents, &str);
	      betrag = ScanMonetary (str);
	      if (CO_GetArticleMwStMode ())
		{
		  /* Bruttobetrag in Netto wandeln */
		  betrag = Brutto2Netto (betrag, CO_GetMwSt (preistab));
		}
	      DisplayBetrag (buffer, betrag, CO_GetMwSt (preistab), newmode);
	      set (TX_A_brutto, MUIA_Text_Contents, buffer);

	      /* den Verkaufspreis wandeln */
	      get (ST_A_VKeinzel, MUIA_String_Contents, &str);
	      betrag = ScanMonetary (str);
	      if (CO_GetArticleMwStMode ())
		{
		  /* Bruttobetrag in Netto wandeln */
		  betrag = Brutto2Netto (betrag, CO_GetMwSt (preistab));
		}
	      DisplayBetrag (buffer, betrag, CO_GetMwSt (preistab), newmode);
	      set (ST_A_VKeinzel, MUIA_String_Contents, buffer);

	      /* den empfohlenen Preis wandeln */
	      get (ST_A_VGLeinzel, MUIA_String_Contents, &str);
	      betrag = ScanMonetary (str);
	      if (CO_GetArticleMwStMode ())
		{
		  /* Bruttobetrag in Netto wandeln */
		  betrag = Brutto2Netto (betrag, CO_GetMwSt (preistab));
		}
	      DisplayBetrag (buffer, betrag, CO_GetMwSt (preistab), newmode);
	      set (ST_A_VGLeinzel, MUIA_String_Contents, buffer);

	      /* neuen Darstellungsmodus einstellen */
	      CO_SetArticleMwStMode (newmode);
	    }
	    break;

	  case ID_A_POPINSERT:
	    /* neue Kategorie in Liste einfügen */
	    {
	      STRPTR str;

	      get (ST_A_pop, MUIA_String_Contents, &str);
	      A_AddCategory (str);
	      DoMethod (LV_A_pop, MUIM_List_InsertSingle, str,
	                MUIV_List_Insert_Sorted);
	      set (LV_A_pop, MUIA_List_Active, A_GetCurrentCategoryNumber ());
	    }
	    break;

	  case ID_A_POPCHANGE:
	    /* Kategorie in Liste ändern */
	    {
	      STRPTR str;
	      LONG num;

	      if (A_GetCategoryCount () > 0)
		{
		  get (LV_A_pop, MUIA_List_Active, &num);
		  if (num != MUIV_List_Active_Off)
		    {
		      A_SetCurrentCategory (num);
		      DoMethod (LV_A_pop, MUIM_List_Remove,
		                MUIV_List_Remove_Active);

		      get (ST_A_pop, MUIA_String_Contents, &str);
		      A_ChangeCategory (str);

		      DoMethod (LV_A_pop, MUIM_List_InsertSingle, str,
		                MUIV_List_Insert_Sorted);
		      set (LV_A_pop, MUIA_List_Active,
		           A_GetCurrentCategoryNumber ());
		    }

		}
	    }
	    break;

	  case ID_A_POPDELETE:
	    /* Kategorie aus Liste löschen */
	    {
	      LONG num;

	      if (A_GetCategoryCount () > 0)
		{
		  get (LV_A_pop, MUIA_List_Active, &num);
		  A_SetCurrentCategory (num);

		  A_DelCategory ();
		  DoMethod (LV_A_pop, MUIM_List_Remove,
		            MUIV_List_Remove_Active);

		  set (LV_A_pop, MUIA_List_Active,
		       A_GetCurrentCategoryNumber ());
		}
	    }
	    break;


	  case ID_A_INSERT:
	    /* neuen Artikel in Liste einfügen */
	    {
	      struct Article article;
	      LONG num;
	      STRPTR str;

	      set (WI_article, MUIA_Window_ActiveObject, LV_A_list);

	      get (ST_A_number, MUIA_String_Contents, &str);

	      /* "?" = neue Artikelnummer suchen lassen */
	      if (strchr (str, '?'))
		strcpy (article.Artikelnummer, "?");
	      else
		strcpy (article.Artikelnummer, str);

	      get (ST_A_article, MUIA_String_Contents, &str);
	      strcpy (article.Bezeichnung, str);
	      get (CY_A_mwst, MUIA_Cycle_Active, &num);
	      article.Preistabelle = num + 1;

	      get (ST_A_menge, MUIA_String_Contents, &str);
	      article.Menge = ScanMonetary (str);

	      get (ST_A_VKeinzel, MUIA_String_Contents, &str);
	      article.Betrag = ScanMonetary (str);
	      /* Bruttobetrag in Netto wandeln */
	      if (CO_GetArticleMwStMode ())
		{
		  article.Betrag = Brutto2Netto (article.Betrag,
		                       CO_GetMwSt (article.Preistabelle));
		}

	      get (ST_A_VGLeinzel, MUIA_String_Contents, &str);
	      article.VGLBetrag = ScanMonetary (str);
	      /* Bruttobetrag in Netto wandeln */
	      if (CO_GetArticleMwStMode ())
		{
		  article.VGLBetrag = Brutto2Netto (article.VGLBetrag,
		                         CO_GetMwSt (article.Preistabelle));
		}

	      get (ST_A_EKeinzel, MUIA_String_Contents, &str);
	      article.EKBetrag = ScanMonetary (str);
	      get (ST_A_EKversand, MUIA_String_Contents, &str);
	      article.EKVersand = ScanMonetary (str);
	      get (ST_A_date, MUIA_String_Contents, &str);
	      strcpy (article.Datum, str);
	      get (ST_A_firma, MUIA_String_Contents, &str);
	      strcpy (article.Lieferfirma, str);
	      get (ST_A_note, MUIA_String_Contents, &str);
	      strcpy (article.Notiz, str);
	      get (ST_A_pop, MUIA_String_Contents, &str);
	      strcpy (article.Kategorie, str);
	      A_AddItem (&article);

	      Redraw_A_List ();
	    }
	    break;

	  case ID_A_DELETE:
	    /* Artikel aus Liste löschen */
	    {
	      struct Article *active;

	      set (WI_article, MUIA_Window_ActiveObject, LV_A_list);
	      DoMethod (LV_A_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  A_DelItem ();
		  DoMethod (LV_A_list, MUIM_List_Remove,
		            MUIV_List_Remove_Active);
		  DoMethod (LV_A_list, MUIM_List_GetEntry,
		            MUIV_List_GetEntry_Active, &active);
		  if (!active)
		    Clear_A_Inputs ();
		}
	    }
	    break;

	  case ID_A_CHANGE:
	    /* Artikel in Liste ändern */
	    {
	      struct Article article;
	      struct Article *active;
	      STRPTR str;
	      LONG num;

	      set (WI_article, MUIA_Window_ActiveObject, LV_A_list);
	      DoMethod (LV_A_list, MUIM_List_GetEntry,
	                MUIV_List_GetEntry_Active, &active);
	      if (active)
		{
		  /* alte Daten lesen */
		  A_GetCurrentItem (&article);

		  /* und mit neuen Daten überschreiben */
		  get (LV_C_list, MUIA_List_Active, &active);

		  get (ST_A_number, MUIA_String_Contents, &str);
		  strcpy (article.Artikelnummer, str);
		  get (ST_A_article, MUIA_String_Contents, &str);
		  strcpy (article.Bezeichnung, str);
		  get (CY_A_mwst, MUIA_Cycle_Active, &num);
		  article.Preistabelle = num + 1;

		  get (ST_A_menge, MUIA_String_Contents, &str);
		  article.Menge = ScanMonetary (str);

		  get (ST_A_VKeinzel, MUIA_String_Contents, &str);
		  article.Betrag = ScanMonetary (str);
		  /* Bruttobetrag in Netto wandeln */
		  if (CO_GetArticleMwStMode ())
		    {
		      article.Betrag = Brutto2Netto (article.Betrag,
		                          CO_GetMwSt (article.Preistabelle));
		    }

		  get (ST_A_VGLeinzel, MUIA_String_Contents, &str);
		  article.VGLBetrag = ScanMonetary (str);
		  /* Bruttobetrag in Netto wandeln */
		  if (CO_GetArticleMwStMode ())
		    {
		      article.VGLBetrag = Brutto2Netto (article.VGLBetrag,
		                           CO_GetMwSt (article.Preistabelle));
		    }

		  get (ST_A_EKeinzel, MUIA_String_Contents, &str);
		  article.EKBetrag = ScanMonetary (str);
		  get (ST_A_EKversand, MUIA_String_Contents, &str);
		  article.EKVersand = ScanMonetary (str);
		  get (ST_A_date, MUIA_String_Contents, &str);
		  strcpy (article.Datum, str);
		  get (ST_A_firma, MUIA_String_Contents, &str);
		  strcpy (article.Lieferfirma, str);
		  get (ST_A_note, MUIA_String_Contents, &str);
		  strcpy (article.Notiz, str);
		  get (ST_A_pop, MUIA_String_Contents, &str);
		  strcpy (article.Kategorie, str);
		  A_ChangeItem (&article);

		  Redraw_A_List ();
		}
	    }
	    break;

	  case ID_A_SCLEAR:
	    Clear_A_SInputs ();
	    set (WI_customer, MUIA_Window_ActiveObject, ST_A_snumber);
	    break;

	  case ID_A_SEARCH:
	    Redraw_A_SList ();
	    break;

	  case ID_A_SALL:
	    Redraw_A_List ();
	    break;

	  case ID_A_TODAY:
	    /* heutiges Datum in Zahldatum-Gadget eintragen */
	    {
	      char buffer[12];
	      buffer[0] = 0;
	      CorrectDate (buffer);
	      set (ST_A_date, MUIA_String_Contents, buffer);
	    }
	    break;

	  case ID_A_CLEAR:
	    if (A_CheckAbort (TRUE))
	      {
		Clear_A_Inputs ();
		set (REG_A_mode, MUIA_Group_ActivePage,
		     MUIV_Group_ActivePage_First);
		set (WI_article, MUIA_Window_ActiveObject, ST_A_article);
	      }
	    break;

	  case ID_A_INPUT:
	    /* Eingabefelder wurden verändert. Aus dem Bruttopreis die
	    ** Prozente berechnen und darstellen.
	    */
	    {
	      LONG cyc;
	      char buf[20];
	      double betrag, zus;
	      STRPTR str;
	      APTR obj;

	      get (WI_article, MUIA_Window_ActiveObject, &obj);

	      /* Nettopreise aus Gadgets einlesen */
	      get (ST_A_EKeinzel, MUIA_String_Contents, &str);
	      betrag = ScanMonetary (str);

	      get (ST_A_EKversand, MUIA_String_Contents, &str);
	      betrag += zus = ScanMonetary (str);

	      /* minimalen Verkaufspreis berechnen */
	      get (CY_A_mwst, MUIA_Cycle_Active, &cyc);
	      DisplayBetrag (buf, betrag, CO_GetMwSt (cyc + 1),
	                     CO_GetArticleMwStMode ());
	      get (TX_A_brutto, MUIA_Text_Contents, &str);
	      if (strcmp (str, buf))
		set (TX_A_brutto, MUIA_Text_Contents, buf);

	      betrag = ScanMonetary (buf);
	      /* pre: betrag ist der minimale Bruttobetrag */

/* 28.12.94    if( obj == ST_A_VKeinzel || obj == LV_A_list ) */
	      if (obj != ST_A_zuschlag)
		{
		  /* der Bruttopreis wurde verändert. Hier den
		  ** Zuschlag also aus dem Bruttobetrag berechnen.
		  */

		  get (ST_A_VKeinzel, MUIA_String_Contents, &str);
		  zus = ScanMonetary (str);

		  if (abs (betrag) > 0.01)
		    zus = (double) ((LONG) ((zus - betrag) /
		          betrag * 10000 + .5)) / 100;
		  else
		    zus = 0.0;

		  if (zus < 0.0)
		    zus = 0.0;
		  PrintMonetary (buf, zus);  /* MUSS PrintMonetary bleiben ! */

		  strcat (buf, " %");
		  set (ST_A_zuschlag, MUIA_String_Contents, buf);
		}
	      else
		{
		  /* Zuschlag wurde eingegeben, also Bruttopreis
		  ** neu berechnen.
		  */
		  get (ST_A_zuschlag, MUIA_String_Contents, &str);
		  zus = ScanMonetary (str);

		  betrag *= 1 + zus / 100;
		  PrintCurrency (buf, betrag);

		  set (ST_A_VKeinzel, MUIA_String_Contents, buf);
		}
	    }
	    break;

	  case ID_A_OKcheck:
	    if (closeArticleAction == CAA_MAIN)
	      break;
	    /* else fall trough ... */
	  case ID_A_OK:
	    if (A_CheckAbort (TRUE))
	      {
		switch (closeArticleAction)
		  {

		  case CAA_MAIN:
		    break;

		  case CAA_INVOICE:
		    /* Artikel in Rechnung übernehmen */
		    {
		      struct Article article;
		      char buffer[20];

		      A_GetCurrentItem (&article);
		      set (ST_I_artnum, MUIA_String_Contents,
		           article.Artikelnummer);
		      set (ST_I_article, MUIA_String_Contents,
		           article.Bezeichnung);
		      DisplayBetrag (buffer, article.Betrag,
		                     I_GetMwSt (article.Preistabelle),
		                     CO_GetInvoiceMwStMode ());
		      set (ST_I_einzel, MUIA_String_Contents, buffer);
		      set (ST_I_menge, MUIA_String_Contents, "1");
		      set (CY_I_mwst, MUIA_Cycle_Active,
		           article.Preistabelle - 1);
		    }
		    break;

		  case CAA_LETTER:
		    /* Artikel in Brief übernehmen */
		    {
		      struct Article article;
		      char buffer[20];

		      A_GetCurrentItem (&article);
		      buffer[0] = ' ';
		      DisplayBetrag (&buffer[1], article.Betrag,
		                     CO_GetMwSt (article.Preistabelle), 1);
		      Insert_LE_Text (article.Bezeichnung);
		      Insert_LE_Text (buffer);
		    }
		    break;

		  case CAA_ORDER:
		    /* gewählten Artikel in Auftrag übernehmen */
		    {
		      struct Article article;
		      char buffer[20];

		      A_GetCurrentItem (&article);
		      set (ST_O_artnum, MUIA_String_Contents,
		           article.Artikelnummer);
		      set (ST_O_article, MUIA_String_Contents,
		           article.Bezeichnung);
		      DisplayBetrag (buffer, article.Betrag,
		                     O_GetMwSt (article.Preistabelle),
		                     CO_GetOrderMwStMode ());
		      set (ST_O_VKeinzel, MUIA_String_Contents, buffer);
#ifdef ORDER_EK
		      DisplayBetrag (buffer, article.EKBetrag,
		                     O_GetMwSt (article.Preistabelle),
		                     CO_GetOrderMwStMode ());
		      set (ST_O_EKeinzel, MUIA_String_Contents, buffer);
#endif
		      set (ST_O_firma, MUIA_String_Contents,
		           article.Lieferfirma);
		      set (ST_O_note, MUIA_String_Contents, article.Notiz);
		      set (ST_O_menge, MUIA_String_Contents, "1");
		      set (CY_O_mwst, MUIA_Cycle_Active,
		           article.Preistabelle - 1);
		    }
		    break;

		  }
		if (A_SaveArticles ())
		  MUI_Request (app, WI_main, 0, STRING (MSG_ERR_REQ_TITLE),
		               STRING (MSG_ERR_REQ_BUTTONS),
		               STRING (MSG_ARTICLEERR_SAVE_REQ_BODY),
		               A_GetErrorMsg ());
		set (WI_articleprint, MUIA_Window_Open, FALSE);
		set (WI_article, MUIA_Window_Open, FALSE);
	      }
	    break;

	  case ID_A_CANCEL:
	    if (A_CheckAbort (FALSE))
	      {
		switch (closeArticleAction)
		  {
		  case CAA_MAIN:
		  case CAA_INVOICE:
		  case CAA_LETTER:
		  case CAA_ORDER:
		    break;
		  }
		set (WI_articleprint, MUIA_Window_Open, FALSE);
		set (WI_article, MUIA_Window_Open, FALSE);
	      }
	    break;

	  case ID_AP_OK:
	    {
	      /* Ausdruck der Artikelliste, je nach Einstellungen */

	      ULONG mode;
	      struct Screen *scr;
	      STRPTR name;
	      STRPTR str;

	      get (WI_main, MUIA_Window_Screen, &scr);
	      name = GetPublicScreenName (scr);

	      get (RA_AP_mode, MUIA_Radio_Active, &mode);
	      get (ST_A_pop, MUIA_String_Contents, &str);

#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, TRUE);
#endif
	      P_PrintArticle (mode, str, name);
#ifndef OUTPUTWIN
	      set (app, MUIA_Application_Sleep, FALSE);
#endif
	    }
	    break;

	  }

      if (running && signals)
	Wait (signals);
    }

  /* vor dem Ende noch die offenen Fenster abfragen und in
  ** der Grundeinstellung speichern, damit sie beim nächsten
  ** Programmstart automatisch geöffnet werden.
  ** VORERST NOCH NICHT BERÜCKSICHTIGT!
  */

  set (WI_customerprint, MUIA_Window_Open, FALSE);
  set (WI_customer, MUIA_Window_Open, FALSE);
  set (WI_invoice, MUIA_Window_Open, FALSE);
  set (WI_invlist, MUIA_Window_Open, FALSE);
  set (WI_order, MUIA_Window_Open, FALSE);
  set (WI_ordlist, MUIA_Window_Open, FALSE);
  set (WI_letcomm, MUIA_Window_Open, FALSE);
  set (WI_letter, MUIA_Window_Open, FALSE);
  set (WI_letlist, MUIA_Window_Open, FALSE);
  set (WI_articleprint, MUIA_Window_Open, FALSE);
  set (WI_article, MUIA_Window_Open, FALSE);
  set (WI_label, MUIA_Window_Open, FALSE);
  set (WI_main, MUIA_Window_Open, FALSE);


/*
** Shut down...
*/

  Quit (app, NULL, NULL);
}


static void 
Quit (APTR app, char *str, char *str2)
{
  DestructLetterList ();
  DestructInvoiceList ();
  DestructOrderList ();
  DestructLetter ();
  DestructInvoice ();
  DestructOrder ();
  DestructCustomer ();
  DestructArticle ();
  DestructLocale ();

  if (MUIMasterBase)
    {
      if (app)
	MUI_DisposeObject (app);
      CloseLibrary (MUIMasterBase);
      MUIMasterBase = NULL;
    }

  if (TextFieldBase)
    {
      CloseLibrary (TextFieldBase);
      TextFieldClass = NULL;
      TextFieldBase = NULL;
    }

  if (IFFParseBase)
    {
      if (undo_handle)
	CloseClipboard (undo_handle);

      if (clip_handle)
	CloseClipboard (clip_handle);

      CloseLibrary (IFFParseBase);
    }

  if (str)
    {
      if (str2)
	printf ("%s: %s\n", str, str2);
      else
	puts (str);
      exit (20);
    }
  exit (0);
}
