/*---------------------------------------------------------------*/
/* Routinen zur Ausgabe von Texten, Infos und UMS-Messages       */
/*---------------------------------------------------------------*/
/*
 * DisplayTxt
 * GetTxt
 * FreeTxt(STRPTR txtbuffer)
 * InfoBarClear
 * TextfieldMethods
 * InfoBarUpdate
 * DisplayMsg -- Hauptroutine
 */

#define RP win->RPort

/*
 * DisplayTxt -- Gibt Message-Text in einem Textfield aus
 *
 * INPUTS
 *   txtfld  - Zeiger auf Textfield-Gadget
 *   win - Zeiger auf aktuelles Fenster
 *   text  - STRPTR auf Messagetext
 *
 * RESULT
 *   TRUE - Ausage OK
 */

BOOL
DisplayTxt (Gadget * txtfld, Window * win, STRPTR text)
{
  BOOL success = FALSE;

  /* Übergebe Textstring an Textfield-Gadget */

  success = (BOOL) (SetGadgetAttrsX (txtfld, win, NULL,
				     TEXTFIELD_Text, text,
				     TAG_END));
  return (success);
}



/*
 * GetTxt -- hole Textstring aus Textfeld. 
 *
 * INPUTS
 *   Gadget * txtfld -- Textfieldgadget
 *   Window * win    -- Window
 *
 * RESULT
 *   STRPTR -- Nullterminierter Text. Mit free() deallozieren!
 *             Oder NULL bei Fehler.
 */

STRPTR
GetTxt(Gadget * txtfld, Window * win)
{
  /* Textfield-Handling Puffer und Pointer */
  ULONG txtbuffer = NULL;		/* Textbuffer */
  ULONG txtsize = 0;		/* Länge Textbuffers (byte) */
  STRPTR buffer = NULL;		/* dynamisch allozierter Textpuffer */

  if (txtfld && win)
    {
      SetGadgetAttrsX (txtfld, win, NULL,
		       TEXTFIELD_ReadOnly, TRUE,	/* sperren */
		       TAG_DONE);

      GetAttr (TEXTFIELD_Text, txtfld, &txtbuffer);	/* Bufferadresse lesen */
      GetAttr (TEXTFIELD_Size, txtfld, &txtsize);	/* Bufferlänge lesen */

      if (txtsize && txtbuffer)	/* ist wirklich Text im Buffer? */
	if (buffer = malloc (txtsize + 1))	/* kann Speicher reserviert werden? */
	  {
	    /* Text aus Textfield-Puffer kopieren */
	    memcpy ((ULONG *) buffer, (ULONG *) txtbuffer, txtsize);

            SetGadgetAttrsX (txtfld, win, NULL,
		       TEXTFIELD_ReadOnly, FALSE,
		       TAG_DONE);
           }
    }
  return ((STRPTR) txtbuffer); /* diesen Pointer zum Deallozieren in free() einsetzen! */
}

void
FreeTxt(STRPTR txtbuffer)
{
if (txtbuffer)
 {
 free(txtbuffer);
 }
}


/*
 * InfoBarClear - löscht die Info-Bar.
 *
 * INPUTS
 *   win- Zeiger auf aktuelles Fenster
 *   height  - Info-Bar Höhe
 *
 * RESULT
 *   void
 */

void
InfoBarClear (Window * win, WORD height)	/* todo: region/rectangle */
{
  SetABPenDrMd (RP, pens[FILLPEN], pens[FILLTEXTPEN], JAM1);
  RectFill (RP,
	    win->BorderLeft,
	    win->BorderTop,
	    win->Width - win->BorderRight - win->BorderLeft + 3,
	    win->BorderTop + height);

  SetABPenDrMd (RP, pens[SHINEPEN], pens[FILLTEXTPEN], JAM1);
  Move (RP, win->BorderLeft, win->BorderTop + height);
  Draw (RP, win->Width - win->BorderRight, win->BorderTop + height);
}

/*---------------------------------------------------------*/
/* Variablen für Display-Feld */
/*---------------------------------------------------------*/

typedef struct myDispType
{
  ULONG FrontPen;
  ULONG BackPen;
  ULONG DrawMode;
  ULONG LeftEdge;
  ULONG TopEdge;
  STRPTR Head;
  ULONG Tag;
  ULONG Len;
};

/* todo: Koords während Laufzeit rechnen */
#define SPALTE1 10
#define SPALTE2 200
#define SPALTE3 350

#define ZEILE1  20 /* y-Koordinate */
#define ZEILE2  29
#define ZEILE3  38

#define BREITE1 200
#define BREITE2 300

/* aus intuition/screens.h */

///erlaubte Pen-Bezeichner:
///DETAILPEN BLOCKPEN TEXTPEN SHINEPEN SHADOWPEN FILLPEN FILLTEXTPEN
///BACKGROUNDPEN HIGHLIGHTTEXTPEN BARDETAILPEN BARBLOCKPEN BARTRIMPEN

#define myDisplayElements 3L	/* Anzahl der Texte in der Infobar. todo: dynamisch */
#define DISPLAY_DONE {0, 0, 0, 0, 0, NULL, 0, 0}

myDispType DisplayStandard[] =
{
  {HIGHLIGHTTEXTPEN, FILLPEN, JAM1, SPALTE1, ZEILE1, "     Von    ", UMSCODE_FromName, BREITE2},
  {HIGHLIGHTTEXTPEN, FILLPEN, JAM1, SPALTE1, ZEILE2, " Betreff    ", UMSCODE_Subject, BREITE2},
  {TEXTPEN, FILLPEN, JAM1, SPALTE1, ZEILE3, "  Gruppe    ", UMSCODE_Group, BREITE2},
  DISPLAY_DONE,
};

myDispType DisplayKurz[] =
{
  {HIGHLIGHTTEXTPEN, FILLPEN, JAM1, SPALTE1, ZEILE1, "S  ", UMSCODE_Subject, SPALTE2 - SPALTE1},
  {HIGHLIGHTTEXTPEN, FILLPEN, JAM1, SPALTE2, ZEILE1, "V  ", UMSCODE_FromName, SPALTE3 - SPALTE2},
  {TEXTPEN, FILLPEN, JAM1, SPALTE3, ZEILE1, "G  ", UMSCODE_Group, BREITE2},
  DISPLAY_DONE,
};

#ifndef MIN
#define MIN(a,b)    ((a)<(b)?(a):(b))
#endif


/*
 * InfoBarUpdate - schreibt neuen Inhalt in die Infobar
 *
 * INPUTS
 *  todo!
 * RESULT
 *  TRUE: erfolgreich
 */

// todo: User-definierbare, plazierbare Felder

BOOL
InfoBarUpdate (UMSUserAccount p_account, UMSMsgNum p_num, Window * p_win, WORD p_height)
{
  /* Vorläufer neue Globalstruktur */
  UMSUserAccount acc = p_account;
  UMSMsgNum num = p_num;
  Window *win = p_win;
  WORD height = p_height;
  myDispType *disp = NULL;

  STRPTR myInfo;		/* Stringbuffer */
  int i = 0;			/* Schleifenzähler */

  ULONG fit = 0;		/* TextFit(): Anzahl Zeichen */
  struct TextExtent myExtent;	/* Ergebnis von TextFit() */

  disp = (myDispType *) & DisplayKurz;	/* fieser CAST, todo, check! */
  InfoBarClear (win, height);	/* InfoBar löschen */

  if (num == 0)			/* Messagenummer ist nicht Null? */
    return (FALSE);

  myInfo = malloc (200);	/* Buffer alloziert? */
  if (!myInfo)
    return (FALSE);

  /* hole die Feldinhalte aus UMS: */
  if (!UMSReadMsgTags (acc,
		       UMSTAG_RMsgNum, num,	/* von Message Nr. "num": */
		       UMSTAG_RTextFields, &myFields,	/* Headerfields lesen */
		       UMSTAG_RReadHeader, NULL,	/* nur die Headerfields lesen */
		       UMSTAG_RNoUpdate, 1L,	/* OLD-Flag bleibt wie es ist */
		       TAG_DONE))
    {
      CheckErr ();
    }
  else
    {
      while (i < myDisplayElements)
          {
	  SetABPenDrMd (RP,
			(ULONG) (pens[disp[i].FrontPen]),	/* Stiftfarben und Zeichenmodus setzen */
			(ULONG) (pens[disp[i].BackPen]),
			(ULONG) (disp[i].DrawMode)
	    );

	  Move (RP,
		(ULONG) (disp[i].LeftEdge),	/* Grafikcursor setzen */
		(ULONG) (disp[i].TopEdge)
	    );

	  Text (RP,		/* jetzt: */
		(STRPTR) (disp[i].Head),	/* Feldname schreiben (z.B. "Gruppe") kludgy, todo */
		(ULONG) (strlen ((STRPTR) (disp[i].Head)))
	    );

	  /* Feldinhalt setzen, aus (kludge: Globaler) "myFields[UMSFELDNUMMER]". */

	  /* Ist der Feldinhalt zu lang? */
	  fit = TextFit (RP,	/* Textlänge prüfen */
			 (STRPTR) (myFields[disp[i].Tag]),
			 (ULONG) (strlen ((STRPTR) (myFields[disp[i].Tag]))),
			 &myExtent,	/* myExtent ist eine notwendige Dummy-Struktur (Ergebnis-Extent) */
			 NULL,
			 1,
			 (ULONG) (MIN (disp[i].Len, (win->Width - win->BorderLeft - win->BorderRight - disp[i].LeftEdge))),	/* Länge des Textes, es fehlt Länge Feldname! todo */
			 (ULONG) (RP->TxHeight + 2)	/* Höhe der Schrift */
	    );

	  Text (RP, (STRPTR) (myFields[disp[i].Tag]), fit);	/* Text ausgeben, aber höchstens "fit" Zeichen. */
	  i++;			/* todo Schleife ändern */
	}			/* (while) */

      UMSFreeMsg (acc, num);	/* Messagebuffer zurückgeben */
    }

  if (myInfo)
    {
    free (myInfo);
    }

  return (TRUE);		/* erfolgreich geschrieben */
}


/*****************************************************************
 *                                                               *
 *                           Display Message                     *
 *                             Hauptroutine                      *
 *                                                               *
 *****************************************************************/

/*
 * DisplayMsg - holt Message in Textfeld und setzt Infobar
 *
 * (wichtige Haupt-Routine)
 */

/* todo: zuviele Parameter */

BOOL
DisplayMsg (Gadget * p_txtfld, Window * p_win, WORD p_height, UMSUserAccount p_account, UMSMsgNum p_num)
{
  Gadget *txtfld = p_txtfld;
  Window *win = p_win;
  WORD height = p_height;
  UMSUserAccount acc = p_account;
  UMSMsgNum num = p_num;

  STRPTR text = NULL;
  BOOL success = FALSE;

  UMSReadMsgTags (acc, UMSTAG_RMsgNum, num,
		  UMSTAG_RMsgText, &text,	/* nur den Text lesen */
		  UMSTAG_RNoUpdate, 1L,		/* OLD-Flag bleibt wie es ist */
		  TAG_END);

  if (text)
    {
      DisplayTxt (txtfld, win, text);
      InfoBarUpdate (acc, num, win, height);

      /* UMS-Msgbuffer freigeben */
      UMSFreeMsg (acc, num);
      SetGlobMsgNum (num);	/* Globale setzen (auf die jetzt angezeigte Message)  */
      success = TRUE;
    }
  else
    /* text */
    {
      CheckErr ();		/* Fehlermeldung aus UMS-System */
      InfoBarClear (win, height);	/* falsche Angaben löschen */
      success = FALSE;
    }

  return (success);
}

/*
 * TextfieldMethods -- spezielle Textfield-Attribute setzen
 *
 * INPUTS
 *  method -- TagItem
 *
 */

BOOL
TextfieldMethods(ULONG method)
{
BOOL success = FALSE;

if (txtfld && Mywindow)
   {
   SetGadgetAttrsX (txtfld, Mywindow, NULL, method, 0, TAG_DONE);
   success = TRUE;
   }

return (success);
}
