/*
   ***************************************************************************
   *
   * Datei:
   *      RSysShowFont.c
   *
   * Inhalt:
   *
   *      --- Globale Routinen ---
   *
   *    void ShowFont ( TEXTFONT *tf );
   *
   *      --- Lokale  Routinen ---
   *
   *    static int BoldCGadClicked ( void );
   *    static int HandleShowFontIDCMP ( void );
   *    static int ItalicCGadClicked ( void );
   *    static int NormalCGadClicked ( void );
   *    static int OpenShowFontWindow ( void );
   *    static int UnderlineCGadClicked ( void );
   *    static void clipWindow ( WINDOW *win , LONG minX , LONG minY , LONG maxX , LONG maxY );
   *    static void IsNoAttrib ( void );
   *    static void Set ( int num , int checked );
   *    static void SetAttr ( int attrib );
   *    static void ShowFontRender ( TEXTATTR *tfont );
   *    static void unclipWindow ( WINDOW *win );
   *
   * Bemerkungen:
   *      Enthält die Routinen zur Darstellung eines beliebig
   *      großen Fonts. Benutzt Clip-Routinen der Layers-Library.
   *
   * Erstellungsdatum:
   *      12-Jul-93     Rolf Böhme
   *
   * Änderungen:
   *      12-Jul-93     Rolf Böhme        Erstellung
   *
   ***************************************************************************
 */

#include "RSys.h"
#include "protos.h"

static int NormalCGadClicked (void);
static int ItalicCGadClicked (void);
static int BoldCGadClicked (void);
static int UnderlineCGadClicked (void);
static int HandleShowFontIDCMP (void);

static WINDOW *ShowFontWnd = NULL;
static GADGET *ShowFontGList = NULL;
static INTUIMESSAGE ShowFontMsg;
static GADGET *ShowFontGadgets[4];
static UWORD ShowFontLeft = 0;
static UWORD ShowFontTop = 0;
static UWORD ShowFontWidth = 500;
static UWORD ShowFontHeight = 120;
static UBYTE *ShowFontWdt = (UBYTE *) NAME " - Show Font";
static char *testtext;
static INTUITEXT ShowFontIText[] =
{
  1, 2, JAM2, 76, 11, NULL, NULL, NULL
};

static TEXTATTR testfont;

static UWORD ShowFontGTypes[] =
{
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  BUTTON_KIND
};

static NEWGADGET ShowFontNGad[] =
{
  12, 104, 26, 11, (UBYTE *) "Normal", NULL, GD_NormalCGad, PLACETEXT_RIGHT, NULL, (APTR) NormalCGadClicked,
  141, 104, 26, 11, (UBYTE *) "Italic", NULL, GD_ItalicCGad, PLACETEXT_RIGHT, NULL, (APTR) ItalicCGadClicked,
  270, 104, 26, 11, (UBYTE *) "Bold", NULL, GD_BoldCGad, PLACETEXT_RIGHT, NULL, (APTR) BoldCGadClicked,
  400, 104, 26, 11, (UBYTE *) "Underl", NULL, GD_UnderlineCGad, PLACETEXT_RIGHT, NULL, (APTR) UnderlineCGadClicked,
};

static ULONG *ShowFontGTags[] =
{
  (ULONG *) (GTCB_Checked), (ULONG *) TRUE, (ULONG *) (TAG_DONE),
  (ULONG *) (TAG_DONE),
  (ULONG *) (TAG_DONE),
  (ULONG *) (TAG_DONE),
};

static long bevelbox[4];

LIBRARY *LayersBase = NULL;

static void
unclipWindow (WINDOW * win)
{
  REGION *old_region;

  if (NULL != (old_region = InstallClipRegion (win->WLayer, NULL)))
    DisposeRegion (old_region);
}

static void
clipWindow (WINDOW * win, LONG minX, LONG minY, LONG maxX, LONG maxY)
{
  REGION *new_region;
  RECTANGLE my_rectangle;

  my_rectangle.MinX = minX;
  my_rectangle.MinY = minY;
  my_rectangle.MaxX = maxX;
  my_rectangle.MaxY = maxY;

  /* get a new region and OR in the limits. */
  if ((new_region = NewRegion ()) != NULL)
    {
      if (OrRectRegion (new_region, &my_rectangle) == FALSE)
	{
	  DisposeRegion (new_region);
	  new_region = NULL;
	}
    }

  InstallClipRegion (win->WLayer, new_region);

  return;
}

static void
ShowFontRender (TEXTATTR * tfont)
{
  INTUITEXT it;
  int ilen;

  EraseRect (ShowFontWnd->RPort,
	     bevelbox[0] + 2, bevelbox[1] + 1,
	     bevelbox[0] + bevelbox[2] - 3, bevelbox[1] + bevelbox[3] - 2);

  CopyMem ((char *) &ShowFontIText[0], (char *) &it, (long) sizeof (INTUITEXT));

  it.IText = (STRPTR) testtext;
  it.ITextFont = tfont;

  ilen = IntuiTextLength (&it);

  it.LeftEdge = bevelbox[0] + ((bevelbox[2] - ilen) / 2);
  it.LeftEdge = (it.LeftEdge < bevelbox[0]) ? bevelbox[0] + 2 : it.LeftEdge;

  it.TopEdge = bevelbox[1] + ((bevelbox[3] - tfont->ta_YSize) / 2);
  it.TopEdge = (it.TopEdge < bevelbox[1]) ? bevelbox[1] + 1 : it.TopEdge;

  PrintIText (ShowFontWnd->RPort, &it, 0, 0);

  return;
}

static int
OpenShowFontWindow (void)
{
  NEWGADGET ng;
  GADGET *g;
  UWORD lc, tc;
  UWORD wleft = ShowFontLeft, wtop = ShowFontTop, ww, wh;
  int gl[] =
  {0};

  AdjustWindowDimensions (Scr, ShowFontLeft, ShowFontTop, ShowFontWidth, ShowFontHeight,
			  &wleft, &wtop, &ww, &wh);

  if (!(g = CreateContext (&ShowFontGList)))
    return 1L;

  for (lc = 0, tc = 0; lc < 4; lc++)
    {
      CopyMem ((char *) &ShowFontNGad[lc], (char *) &ng,
	       (long) sizeof (NEWGADGET));

      ng.ng_VisualInfo = VisualInfo;
      ng.ng_TextAttr = Font;
      ng.ng_LeftEdge = OffX + ComputeX (ng.ng_LeftEdge);
      ng.ng_TopEdge = OffY + ComputeY (ng.ng_TopEdge);
      ng.ng_Width = ComputeX (ng.ng_Width);
      ng.ng_Height = ComputeY (ng.ng_Height);

      ShowFontGadgets[lc] = g = CreateGadgetA ((ULONG) ShowFontGTypes[lc], g, &ng, (TAGITEM *) & ShowFontGTags[tc]);
      makelabelvisible (ShowFontGadgets[lc]);

      while (ShowFontGTags[tc])
	tc += 2;

      tc++;

      if (NOT g)
	return 2L;
    }

  bevelbox[0] = OffX + ComputeX ((UWORD) 12);
  bevelbox[1] = OffY + ComputeY ((UWORD) 5);
  bevelbox[2] = (long) ComputeX ((UWORD) 477);
  bevelbox[3] = (long) ComputeY ((UWORD) 93);

  sprintf (testtext, "(%ld) %s", testfont.ta_YSize, testfont.ta_Name);

  if (!(ShowFontWnd = OpenWindowTags (NULL,
				      WA_Left, wleft,
				      WA_Top, wtop,
				      WA_Width, ww,
				      WA_Height, wh,
				      WA_IDCMP,
	       TEXTIDCMP | CHECKBOXIDCMP | BUTTONIDCMP | IDCMP_CLOSEWINDOW |
				      IDCMP_REFRESHWINDOW | VANILLAKEY,
	      WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
			  WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP,
				      WA_Title, ShowFontWdt,
				      WA_PubScreenFallBack, TRUE,
				      WA_PubScreen, Scr,
				      TAG_DONE)))
    return 4L;

  RefreshRastPort (ShowFontWnd, ShowFontGadgets, gl, 0, FALSE, ShowFontGList);

  EraseRect (ShowFontWnd->RPort,
	     bevelbox[0] + 2, bevelbox[1] + 1,
	     bevelbox[0] + bevelbox[2] - 3, bevelbox[1] + bevelbox[3] - 2);

  DrawBevelBox (ShowFontWnd->RPort,
		bevelbox[0], bevelbox[1],
		bevelbox[2], bevelbox[3],
		GT_VisualInfo, VisualInfo,
		GTBB_Recessed, TRUE,
		TAG_DONE);

  clipWindow (ShowFontWnd, bevelbox[0] + 4, bevelbox[1] + 2,
	      bevelbox[0] + bevelbox[2] - 6, bevelbox[1] + bevelbox[3] - 4);

  ShowFontRender (&testfont);

  GT_RefreshWindow (ShowFontWnd, NULL);

  return 0L;
}

static int flags[4] =
{TRUE, FALSE, FALSE, FALSE}, defflags[4] =
{TRUE, FALSE, FALSE, FALSE};
static int attributes[4] =
{FS_NORMAL, FSF_ITALIC, FSF_BOLD, FSF_UNDERLINED};

static void
SetAttr (int attrib)
{
  int i;
  int newattr;

  if (attrib != FS_NORMAL)
    {
      newattr = 0;

      for (i = 0; i < 4; i++)
	newattr |= (flags[i] == TRUE) ? attributes[i] : 0;
    }
  else
    newattr = FS_NORMAL;

  testfont.ta_Style = newattr;

  ShowFontRender (&testfont);

  return;
}

static void
Set (int num, int checked)
{
  flags[num - GD_NormalCGad] = checked;

  GT_SetGadgetAttrs (ShowFontGadgets[num - GD_NormalCGad], ShowFontWnd,
		     NULL,
		     GTCB_Checked, flags[num - GD_NormalCGad],
		     TAG_DONE);

  return;
}

static void
IsNoAttrib (void)
{
  if (!flags[1] && !flags[2] && !flags[3])
    Set ((int) GD_NormalCGad, TRUE);

  return;
}

static int
NormalCGadClicked (void)
{
  int i;

  if (!flags[GD_NormalCGad - GD_NormalCGad])
    SetAttr (attributes[0]);

  Set ((int) GD_NormalCGad, TRUE);

  for (i = GD_ItalicCGad; i <= GD_UnderlineCGad; i++)
    Set (i, FALSE);

  return TRUE;
}

static int
ItalicCGadClicked (void)
{
  /* routine when gadget "Italic" is clicked. */
  Set ((int) GD_NormalCGad, FALSE);

  flags[GD_ItalicCGad - GD_NormalCGad] = (flags[GD_ItalicCGad - GD_NormalCGad] == TRUE) ? FALSE : TRUE;

  SetAttr (attributes[1]);

  IsNoAttrib ();

  return TRUE;
}

static int
BoldCGadClicked (void)
{
  /* routine when gadget "Bold" is clicked. */
  Set ((int) GD_NormalCGad, FALSE);

  flags[GD_BoldCGad - GD_NormalCGad] = (flags[GD_BoldCGad - GD_NormalCGad] == TRUE) ? FALSE : TRUE;

  SetAttr (attributes[2]);

  IsNoAttrib ();

  return TRUE;
}

static int
UnderlineCGadClicked (void)
{
  /* routine when gadget "Underline" is clicked. */
  Set ((int) GD_NormalCGad, FALSE);

  flags[GD_UnderlineCGad - GD_NormalCGad] = (flags[GD_UnderlineCGad - GD_NormalCGad] == TRUE) ? FALSE : TRUE;

  SetAttr (attributes[3]);

  IsNoAttrib ();

  return TRUE;
}

static int
HandleShowFontIDCMP (void)
{
  INTUIMESSAGE *m;
  int (*func) (void);
  BOOL running = TRUE;
  GADGET *gad;

  while (m = GT_GetIMsg (ShowFontWnd->UserPort))
    {
      CopyMem ((char *) m, (char *) &ShowFontMsg,
	       (long) sizeof (INTUIMESSAGE));

      GT_ReplyIMsg (m);

      switch (ShowFontMsg.Class)
	{
	case IDCMP_REFRESHWINDOW:
	  GT_BeginRefresh (ShowFontWnd);
	  GT_EndRefresh (ShowFontWnd, TRUE);
	  break;

	case IDCMP_VANILLAKEY:
	  if ((char) ShowFontMsg.Code == ESC)
	    running = FALSE;
	  break;

	case IDCMP_CLOSEWINDOW:
	  running = FALSE;
	  break;

	case IDCMP_GADGETUP:
	  gad = (GADGET *) ShowFontMsg.IAddress;
	  HandleHelp ((enum RSysNumbers) gad->GadgetID);

	  func = (int (*)()) (gad->UserData);
	  running = func ();
	  break;
	}
    }

  return running;
}

void
ShowFont (TEXTFONT * tf)
{
  int i;

  DPOS;

  PrintInfo ("Show font", SPEAK, 0);

  if (LayersBase = OpenLibrary ((STRPTR) "layers.library", 36))
    {
      LockMainWindow (WIN_LOCK);

      for (i = 0; i < 4; i++)
	flags[i] = defflags[i];

      testtext = MyAllocVec (strlen (tf->tf_Message.mn_Node.ln_Name) + 10, MEMF_CLEAR, NO_KILL);

      if (testtext)
	{
	  testfont.ta_Name = (STRPTR) tf->tf_Message.mn_Node.ln_Name;
	  testfont.ta_YSize = tf->tf_YSize;
	  testfont.ta_Style = 0;
	  testfont.ta_Flags = 0;

	  if (OpenASysWindow (OpenShowFontWindow, NO_KILL))
	    {
	      while (HandleShowFontIDCMP ());

	      unclipWindow (ShowFontWnd);

	      CloseASysWindow (&ShowFontWnd, &ShowFontGList, NULL);
	    }

	  MyFreeVec (testtext);
	}

      CloseLibrary (LayersBase);
      LayersBase = NULL;

      LockMainWindow (WIN_UNLOCK);
    }
  else
    ErrorHandle ("layers.library", LIBRARY_ERR, OPEN_FAIL, KILL);

  PrintStatistics ();

  return;
}
