/*
***************************************************************************
*
* Datei:
*    RSysShowFont.c
*
* Inhalt:
*    void ShowFont(struct TextFont *tf);
*
* 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 <clib/layers_protos.h>

#include "RSysDebug.h"
#include "RSysFunc.h"

enum
{
   GD_NormalCGad,
   GD_ItalicCGad,
   GD_BoldCGad,
   GD_UnderlineCGad
};

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

static struct Window *ShowFontWnd = NULL;
static struct Gadget *ShowFontGList = NULL;
static struct IntuiMessage ShowFontMsg;
static struct 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 struct IntuiText ShowFontIText[]=
{
   1, 2, JAM2, 76, 11, NULL, NULL, NULL
};

#define ShowFont_TNUM 1

static struct TextAttr testfont;

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

static struct 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];

struct Library *LayersBase = NULL;

static void
unclipWindow(struct Window *win)
{
   struct Region *old_region;

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

static void
clipWindow(struct Window *win, LONG minX, LONG minY, LONG maxX, LONG maxY)
{
   struct Region *new_region;
   struct 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 (NULL != (new_region = NewRegion()))
   {
      if (FALSE == OrRectRegion(new_region, &my_rectangle))
      {
         DisposeRegion(new_region);
         new_region = NULL;
      }
   }

   InstallClipRegion(win->WLayer, new_region);

   return;
}

static void
ShowFontRender(struct TextAttr *tfont)
{
   struct 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(struct 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)
{
   struct NewGadget ng;
   struct Gadget *g;
   UWORD lc,
         tc;
   UWORD wleft = ShowFontLeft,
         wtop = ShowFontTop,
         ww,
         wh;
   int   gl[] = {0};

   ComputeFont(Scr, ShowFontWidth, ShowFontHeight);

   ww = compute((UWORD) 0, FontX, (int)ShowFontWidth);
   wh = compute((UWORD) 0, FontY, (int)ShowFontHeight);

   if ((wleft + ww + OffX + Scr->WBorRight) > Scr->Width)
      wleft = Scr->Width - ww;
   if ((wtop + wh + OffY + Scr->WBorBottom) > Scr->Height)
      wtop = Scr->Height - wh;

   ww = compute((UWORD) (OffX + Scr->WBorRight), FontX, (int)ShowFontWidth);
   wh = compute((UWORD) (OffY + Scr->WBorBottom), FontY, (int)ShowFontHeight);

   CenterWindow(Scr, &wtop, &wleft, ww, wh);

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

   for (lc = 0, tc = 0; lc < 4; lc++)
   {

      CopyMem((char *)&ShowFontNGad[lc], (char *)&ng, (long)sizeof(struct 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, (struct 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_Gadgets, ShowFontGList,
                                      WA_Title, ShowFontWdt,
                                      WA_PubScreenFallBack, TRUE,
                                      WA_PubScreen, Scr,
                                      TAG_DONE)))
      return (4L);

   RefreshRastPort(ShowFontWnd, ShowFontGadgets, gl, 0);

   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] = checked;

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

   return;
}

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

   return;
}

static int
NormalCGadClicked(void)
{
   int   i;

   if (!flags[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] = (flags[GD_ItalicCGad] == 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] = (flags[GD_BoldCGad] == 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] = (flags[GD_UnderlineCGad] == TRUE) ? FALSE : TRUE;

   SetAttr(attributes[3]);

   IsNoAttrib();

   return TRUE;
}

static int
HandleShowFontIDCMP(void)
{
   struct IntuiMessage *m;
   int   (*func) (void);
   BOOL  running = TRUE;

   while (m = GT_GetIMsg(ShowFontWnd->UserPort))
   {

      CopyMem((char *)m, (char *)&ShowFontMsg, (long)sizeof(struct 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:
            func = (void *)((struct Gadget *) ShowFontMsg.IAddress)->UserData;
            running = func();
            break;
      }
   }
   return (running);
}

void
ShowFont(struct TextFont *tf)
{
   int   i;
   APTR  req;

   DPOS;

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

   if (LayersBase = OpenLibrary((STRPTR) "layers.library", 36))
   {
      req = LockWindow(SysWnd);

      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);
      }

      UnlockWindow(req);

      CloseLibrary(LayersBase);
      LayersBase = NULL;
   }
   else
      ErrorHandle(LIBRARY_ERR, OPEN_FAIL, KILL);

   PrintStatistics();

   return;
}
