/**
 * Scout - The Amiga System Monitor
 *
 *------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * You must not use this source code to gain profit of any kind!
 *
 *------------------------------------------------------------------
 *
 * @author Andreas Gelhausen
 * @author Richard Körber <rkoerber@gmx.de>
 */



#include "system_headers.h"

APTR BT_FontUpdate,BT_FontPrint,BT_FontClose,BT_FontRemove,BT_FontExit;
APTR fonttext,fontlist,LB_FontExample;

APTR fontcount;
int  fontcnt;

static APTR FontPool = NULL;

__asm __saveds LONG fontlist_dspfunc(register __a2 char **array, register __a1 struct FontEntry *fontentry, register __a0 struct Hook *hook)
{
    if (fontentry) {
        *array++ = fontentry->font_address;
        *array++ = fontentry->font_ysize;
        *array++ = fontentry->font_xsize;
        *array++ = fontentry->font_style;
        *array++ = fontentry->font_flags;
        *array++ = fontentry->font_count;
        *array++ = fontentry->font_lochar;
        *array++ = fontentry->font_hichar;
        *array++ = fontentry->font_place;
        *array++ = fontentry->font_name;
        *array   = NULL;
    } else {
        *array++ = ESC "bAddress";
        *array++ = ESC "bYSize";
        *array++ = ESC "bXSize";
        *array++ = ESC "bStyle";
        *array++ = ESC "bFlags";
        *array++ = ESC "bCount";
        *array++ = ESC "bLoChar";
        *array++ = ESC "bHiChar";
        *array++ = ESC "bType";
        *array++ = ESC "bName";
        *array   = NULL;
    }
    return(0);
}

struct Hook fontlist_dsphook = {
 {NULL, NULL},
 (ULONG (* )())fontlist_dspfunc,
 NULL, NULL
};

__asm __saveds LONG fontlist_cmpfunc(register __a1 struct FontEntry *fontentry1, register __a2 struct FontEntry *fontentry2)
{
    LONG cmp;

    cmp = strcmpi(fontentry1->font_name, fontentry2->font_name);
    if (cmp == 0) cmp = strcmpi(fontentry1->font_ysize, fontentry2->font_ysize);
    if (cmp == 0) cmp = strcmpi(fontentry1->font_xsize, fontentry2->font_xsize);

    return cmp;
}

struct Hook fontlist_cmphook = {
 {NULL, NULL},
 (ULONG (* )())fontlist_cmpfunc,
 NULL, NULL
};

void FreeFonts (void)
{
    MyFreePoolStructs(&FontPool, fonttext, NULL, fontlist);
}

void FlushFonts (void) {
    struct TextFont *font, *next;

    font = FIRSTFONT;

    Forbid();
    while (next = (struct TextFont *)font->tf_Message.mn_Node.ln_Succ) {
        if ((! font->tf_Accessors) && (font->tf_Flags & FPF_DISKFONT)) {
            RemFont (font);
            Remove ((struct Node *) font);
        }
        font = next;
    }
    Permit();
}

int GetFonts (struct FontEntry **first) {
   struct   FontEntry   *fontentry,*previous = NULL;
   struct   TextFont    *font;

   int fontcnt = 0;
   *first = 0;

   if (!FontPool) FontPool = tbCreatePool(MEMF_CLEAR, 4096, 4096);

   if (clientstate) {
      if (SendDaemon ("GetFontList")) {
         while ((fontentry = tbAllocPooled(FontPool, sizeof(struct FontEntry))) \
           && (ReceiveDecodedEntry ((UBYTE *) fontentry, sizeof (struct FontEntry)))) {
            IsHex (fontentry->font_address, (long *) &fontentry->font_adr);

            if (! *first)
               *first = fontentry;
            if (previous)
               previous->font_next = fontentry;

            fontcnt++;
            previous = fontentry;
         }
      }
   } else {
      font = FIRSTFONT;

      while ((font->tf_Message.mn_Node.ln_Succ != 0) && (fontentry = tbAllocPooled(FontPool, sizeof(struct FontEntry)))) {
         if (! *first)
            *first = fontentry;
         if (previous)
            previous->font_next = fontentry;

                fontentry->font_adr = font;

                _sprintf (fontentry->font_address, "$%08lx", font);
                _sprintf (fontentry->font_xsize, "%3ld ", font->tf_XSize);
                _sprintf (fontentry->font_ysize, "%3ld ", font->tf_YSize);
                _sprintf (fontentry->font_style, " $%02lx", font->tf_Style);
                _sprintf (fontentry->font_flags, " $%02lx", font->tf_Flags);
                _sprintf (fontentry->font_lochar, "%4ld ", font->tf_LoChar);
                _sprintf (fontentry->font_hichar, "%4ld ", font->tf_HiChar);
                _sprintf (fontentry->font_count, "%3ld ", font->tf_Accessors);
                if (font->tf_Flags & FPF_ROMFONT) {
                        strcpy (fontentry->font_place, "ROMFONT ");
                } else {
                        strcpy (fontentry->font_place, "DISKFONT");
                }
                strcpy (fontentry->font_name, font->tf_Message.mn_Node.ln_Name);
         fontcnt++;
   
         previous = fontentry;
         font = (struct TextFont *) font->tf_Message.mn_Node.ln_Succ;
      }
   }
   return (fontcnt);
}

void PrintFonts (char *filename) {
   int i=1;
   BPTR handle;
   struct FontEntry *entryp = NULL;

   handle = HandlePrintStart (filename);
   if ((handle) && (PrintOneLine (handle, "\n  Address  XSize YSize Style Flags Count LoChar HiChar Type     Name\n\n"))) {
      if (! WI_Fonts) {
         i = GetFonts (&entryp);
      }
      if (i) {
         for (i=0;;i++) {
            if (WI_Fonts)
               DoMethod (fontlist,MUIM_List_GetEntry,i,&entryp);
            if (!entryp) break;

            _sprintf (tmpstr2, " %s  %3s %3s %s  %s   %3s  %4s  %4s %-8s %s\n", entryp->font_address, entryp->font_xsize, entryp->font_ysize, entryp->font_style, entryp->font_flags, entryp->font_count, entryp->font_lochar, entryp->font_hichar, entryp->font_place, entryp->font_name);
            if (! (PrintOneLine (handle, tmpstr2)))
               break;

            if (! WI_Fonts)
               entryp = entryp->font_next;
         }
      }
   }
   HandlePrintStop();
}

void ShowFonts (void) {
   struct   FontEntry   *font;

        ApplicationSleep();
        set(fontlist,MUIA_List_Quiet,TRUE);
        set(BT_FontClose, MUIA_Disabled, TRUE);
        set(BT_FontRemove, MUIA_Disabled, TRUE);

   fontcnt = GetFonts (&font);

   while (font) {
      InsertSortedEntry (fontlist, (APTR *) &font);
      font = font->font_next;
   }

   SetCountText (fontcount, fontcnt);
        AwakeApplication();
        set(fontlist,MUIA_List_Quiet,FALSE);
}

void SendFontList (void) {
   struct   FontEntry   *font;

   fontcnt = GetFonts (&font);

   while (font) {
      SendEncodedEntry ((UBYTE *) font, sizeof (struct FontEntry));
      font = font->font_next;
   }
   FreeFonts();
}


char fonts_title[WINDOWTITLELEN];

void FontsWindow (BOOL state) {
   if (state) {
      if (WI_Fonts) {
         ShowFonts();
      } else {
         WI_Fonts = WindowObject,
         MUIA_Window_Title, MyGetWindowTitle (fonts_title, "FONTS"),
         MUIA_HelpNode, FontsText,
         MUIA_Window_ID, MakeListID('F','O','N','T'),
         WindowContents, VGroup,
            Child, fontlist = MySortedListviewObject ("COL=0 DELTA=8,COL=1 DELTA=8 P=\33r,COL=2 DELTA=8 P=\33r,COL=3 DELTA=8,COL=4 DELTA=8,COL=5 DELTA=8 P=\33r,COL=6 DELTA=8 P=\33r,COL=7 DELTA=8 P=\33r,COL=8 DELTA=8,COL=9",&fontlist_dsphook, &fontlist_cmphook),
            Child, MyBelowListview (&fonttext, &fontcount),
            Child, MyVSpace(2),
            Child, LB_FontExample = NewObject(FontDisplayClass->mcc_Class, NULL, TextFrame, MUIA_Background, MUII_BACKGROUND, FDATTR_Font, NULL, TAG_DONE),
            Child, MyVSpace(2),
            Child, HGroup, MUIA_Group_SameSize, TRUE,
               Child, BT_FontUpdate  = KeyButtonA (UpdateText,ID_FONTUPDATE),
               Child, BT_FontPrint   = KeyButtonA (PrintText ,ID_FONTPRINT),
               Child, BT_FontClose   = KeyButtonA (CloseText,ID_FONTCLOSE),
               Child, BT_FontRemove  = KeyButtonA (RemoveText,ID_FONTREMOVE),
               Child, BT_FontExit    = KeyButtonA (ExitText  ,ID_FONTEXIT),
            End,
         End, End;

         DoMethod (AP_Scout,OM_ADDMEMBER,WI_Fonts);
         DoMethod (WI_Fonts,MUIM_Window_SetCycleChain,fontlist,BT_FontUpdate,BT_FontPrint,BT_FontClose,BT_FontRemove,BT_FontExit,NULL);

         SetCloseRequest (WI_Fonts,ID_FONTEXIT);
         SetListActive (fontlist,ID_FONTLV_ACTIVE);

         ShowFonts();

         SetWindowOpen (WI_Fonts,fontlist,ID_FONTEXIT);
      }
   } else if ((! state) && (WI_Fonts)) {
      SetWindowClose (WI_Fonts,TRUE);

      FreeFonts();

      DoMethod (AP_Scout,OM_REMMEMBER,WI_Fonts);
      MUI_DisposeObject (WI_Fonts);
      WI_Fonts = NULL;
      fontlist = NULL;
   }
}

