/*
 * DP - Komfortables Font-Assign
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Mit "<---" markierte Stellen evtl. ändern
 *
 * Copyright © 1989  Oo
 * by		    o.·°
 * Walter Dörwald ·°·o·.o
 *		      O
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/text.h>
#include <string.h>
#include <libraries/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>
#include <proto/exec.h>

/* Kurz für MedResBorder */
#define KASTL(x1,y1,x2,y2) x1,y1,x1,y2,x2,y2,x2,y1,x1-1,y1,x1-1,y2,x2+1,y2,x2+1,y1
#define KASTLSIZE 8

/* max. Anzahl der Dir's */
#define MAXDIR 50

extern UWORD OpenGad_Image_Data[];

struct Window *MyWindow = NULL;
struct IntuiMessage *IMessage;
struct RastPort *RP;

ULONG MessageClass;

UBYTE  Command[58] = "C:Assign Fonts: SYS:Fonts/";  /* <--- */

/* Alles mögliche zum Stringspeichern */
UBYTE Daten[MAXDIR][31];
UBYTE FileBuf[31];

struct FileInfoBlock *FIB;

BYTE Anzahl;
BYTE Count;

/* Jetzt kommt das große StrukturenChaos */

struct TextAttr TA_FETT =
{
   (UBYTE *)"topaz.font",TOPAZ_SIXTY,FSF_BOLD,FPF_ROMFONT
};

struct TextAttr TA_NORM =
{
   (UBYTE *)"topaz.font",TOPAZ_EIGHTY,FSF_BOLD,FPF_ROMFONT
};

SHORT End_Border2_Data [] =
{
   KASTL(-1,-1,37,9)
};

struct Border End_Border2 =
{
   0,0,0,31,JAM1,KASTLSIZE,End_Border2_Data,NULL
};

SHORT End_Border_Data [] =
{
   KASTL(-5,-3,41,11)
};

struct Border End_Border =
{
   0,0,0,31,JAM1,KASTLSIZE,End_Border_Data,&End_Border2
};

struct IntuiText GadText[] =
{
   {0,1,JAM1,8,1,&TA_FETT,(UBYTE *)"OK",(struct IntuiText *)NULL},
   {0,1,JAM1,3,1,&TA_FETT,(UBYTE *)"Nix",(struct IntuiText *)NULL}
};

struct Image OpenGad_6_Image =
{
   -2,-1,14,10,1,OpenGad_Image_Data,1,0,NULL
};

struct Image OpenGad_8_Image =
{
   -2,-1,14,10,1,OpenGad_Image_Data+10,1,0,NULL
};

struct Image OpenGad_7_Image;
struct PropInfo OpenGad_7_Info =
{
   AUTOKNOB|FREEVERT|PROPBORDERLESS,0,0,0,0xFFFF,0,0,0,0,0,0
};

struct Gadget OpenGad [] =
{
   {NULL,11,14,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,0,NULL},
   {&OpenGad[0],11,22,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,1,NULL},
   {&OpenGad[1],11,30,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,2,NULL},
   {&OpenGad[2],11,38,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,3,NULL},
   {&OpenGad[3],11,46,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,4,NULL},
   {&OpenGad[4],11,54,213,8,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,NULL,NULL,NULL,0L,NULL,5,NULL},
   {&OpenGad[5],232,24,10,28,GADGHNONE,GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE,PROPGADGET|REQGADGET,(APTR)&OpenGad_7_Image,NULL,NULL,0L,(APTR)&OpenGad_7_Info,7,NULL},
   {&OpenGad[6],232,13,10,8,GADGHCOMP|GADGIMAGE,RELVERIFY,BOOLGADGET|REQGADGET,(APTR)&OpenGad_6_Image,NULL,NULL,0L,NULL,6,NULL},
   {&OpenGad[7],232,55,10,8,GADGHCOMP|GADGIMAGE,RELVERIFY,BOOLGADGET|REQGADGET,(APTR)&OpenGad_8_Image,NULL,NULL,0L,NULL,8,NULL},
   {&OpenGad[8],201,68,37,9,GADGHCOMP,RELVERIFY|ENDGADGET,BOOLGADGET|REQGADGET,(APTR)&End_Border,NULL,&GadText[0],0L,NULL,100,NULL},
   {&OpenGad[9],15,68,37,9,GADGHCOMP,RELVERIFY|ENDGADGET,BOOLGADGET|REQGADGET,(APTR)&End_Border,NULL,&GadText[1],0L,NULL,101,NULL}
};

SHORT Open_Border2_Data [] =
{
   KASTL(226,12,237,41)
};

struct Border Open_Border2 =
{
   0,0,0,31,JAM1,KASTLSIZE,Open_Border2_Data,NULL
};

SHORT Open_Border_Data [] =
{
   KASTL(5,1,219,52)
};

struct Border Open_Border =
{
   0,0,0,31,JAM1,KASTLSIZE,Open_Border_Data,&Open_Border2
};

struct NewWindow MyNewWindow =
{
   226,62,252,85,0,1,GADGETUP|GADGETDOWN,
   WINDOWDRAG|NOCAREREFRESH|SMART_REFRESH|ACTIVATE,
   &OpenGad[10],NULL," Font-Directories ",NULL,NULL,0,0,0,0,WBENCHSCREEN
};

/* Brauch ma niat */
void MemCleanup(){}

/* Deklarationen */
void FillIn(void);
void SetTx(ULONG,ULONG,UBYTE *,UBYTE);

void _main()

{
   register struct Lock   *DirLock;
   register UWORD	   Gad_ID;
   register BYTE	   sel = -1;
   register UBYTE	   Changed = 0;
   register WORD Help;
   register UBYTE Merk;


   if (!(IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library",0L)))
   goto Fehler;

   if (!(GfxBase = (struct GfxBase *)
      OpenLibrary("graphics.library",0L)))
   goto Fehler;

   /* FileInfoSpeicher holen */
   if (!(FIB = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR)))
      goto Fehler;

   /* Fenster auf */
   if (!(MyWindow = (struct Window *)OpenWindow(&MyNewWindow)))
      goto Fehler;

   /* Macht die Sache kürzer */
   RP = MyWindow->RPort;

   /* Vorbereitungen */
   SetAPen(RP,1);
   RectFill(RP,5,11,246,81);
   SetAPen(RP,0);
   SetBPen(RP,1);
   SetFont(RP,OpenFont(&TA_NORM));
   Count = 0;
   DrawBorder(RP,&Open_Border,5,11);
   Move(RP,67L,71L);
   Text(RP,"Gewählte Fonts:",15);
   RefreshGList(&OpenGad[10],MyWindow,NULL,5);

   /* Fonts-Verzeichnis */
   if (DirLock = (struct Lock *)Lock("SYS:Fonts",ACCESS_READ)) /* <--- */
   {
      if (Examine((BPTR)DirLock,FIB))
      {
	 /* Einlesen und merken */
	 for (Anzahl = 0;ExNext((BPTR)DirLock,FIB);Anzahl++)
	 {
	    strcpy(Daten[Anzahl],FIB->fib_FileName);
	    /* Bei MAXDIR ist Schluß */
	    if (Anzahl == MAXDIR)
	       break;
	 }
	 UnLock((BPTR)DirLock);
	 /* PropGad setzen */
	 OpenGad_7_Info.VertBody = (Anzahl>6) ? (WORD)((LONG)(MAXBODY*6L)/(LONG)Anzahl) : MAXBODY;
	 OpenGad_7_Info.VertPot  = 0;
	 /* Ausgeben */
	 FillIn();
      }
   }

   do
   {
      /* Warten auf Nachricht */
      WaitPort(MyWindow->UserPort);
      while (IMessage = (struct IntuiMessage *)GetMsg(MyWindow->UserPort))
      {
	 /* Wichtigstes merken; Nachricht beantworten */
	 MessageClass = IMessage->Class;
	 Gad_ID = ((struct Gadget *)IMessage->IAddress)->GadgetID;
	 ReplyMsg((struct Message *)IMessage);

	 switch (Gad_ID)
	 {
	    /* Dir angeklickt */
	    case 0:
	    case 1:
	    case 2:
	    case 3:
	    case 4:
	    case 5:
	       if (Gad_ID < Anzahl)
		  SetTx(62L,79L,Daten[sel = Count+Gad_ID],16);
	       break;
	    /* Rauf angeklickt */
	    case 6:
	       if (Count)
	       {
		  Count--;
		  goto PropEin;
	       }
	    case 7:
	       if ((OpenGad_7_Info.Flags & KNOBHIT) && Anzahl > 6)
	       {
		  /* Maus verfolgen */
		  ModifyIDCMP(MyWindow,MOUSEMOVE|DELTAMOVE|GADGETUP);
		  do
		  {
		     WaitPort(MyWindow->UserPort);
		     while ((IMessage = (struct IntuiMessage *)
			   GetMsg(MyWindow->UserPort)) &&
			   (MessageClass = IMessage->Class) != GADGETUP)
		     {
			/* Maus bewegt ? */
			Help = IMessage->MouseY;
			ReplyMsg((struct Message *)IMessage);
			if (!Help)
			   continue;
			/* Test ob Bewegung weit genug */
			Merk = Count;
			Count = OpenGad_7_Info.VertPot * (Anzahl-6) / MAXPOT;
			/* Wenn, ja dann neu ausgeben */
			if (Count != Merk)
			   FillIn();
		     } /* while */
		  } /* do */
		  while (MessageClass != GADGETUP);
	       } /* if */
	       /* Maus wieder loslassen */
	       ModifyIDCMP(MyWindow,GADGETDOWN|GADGETUP);
	       Count = OpenGad_7_Info.VertPot * (Anzahl-6) / MAXPOT;
	       FillIn();
	       break;
	    /* Runter angeklickt */
	    case 8:
	       if (Count < Anzahl-6)
	       {
		  Count++;
PropEin:
		  OpenGad_7_Info.VertPot = MAXPOT*Count/(Anzahl-6);
		  FillIn();
	       }
	       break;
	    /* Ende */
	    case 100:
	       Changed = 2;
	       break;
	    default:
	       Changed = 1;
	       break;
	 }
      }
   } while (!Changed);

   /* Ende: Aufräumen */
   Fehler:
   if (MyWindow)
      CloseWindow(MyWindow);
   if (FIB)
      FreeMem((UBYTE *)FIB,sizeof(struct FileInfoBlock));
   if (IntuitionBase)
      CloseLibrary((struct Library *)IntuitionBase);
   if (GfxBase)
      CloseLibrary((struct Library *)GfxBase);

   /* Ist was zu tun ? */
   if ((Changed == 2) && (sel >= 0))
   {
      register BPTR FH;
      /* Dir anhängen */
      strcpy(Command+26L,Daten[sel]);
      /* CLI auf */
      if (FH = (BPTR)Open("CON:284/99/103/10/ ... ",MODE_NEWFILE))
      {
	 /* die nachfolgende Zeile ist der ganze Zweck des Programms */
	 Execute(Command,(BPTR)0L,(BPTR)FH);
	 Close((BPTR)FH);
      }
   }
}


void FillIn()

{
   register ULONG i,
		  Pos;

   /* Alle durch */
   for (i = 0;i<6;i++)
   {
      Pos = (ULONG)((i<<3)+20L);
      /* Noch Text da ? */
      if (i<Anzahl)
      {
	 /* Text ausgeben */
	 SetTx(13,Pos,Daten[Count+i],26);
      }
      else
	 /* Leerzeile */
	 SetTx(13,Pos,NULL,26);
   }
   /* Neu zeichnen */
   RefreshGadgets(&OpenGad[6],MyWindow,NULL);
}

void SetTx(x,y,text,maxlen)

ULONG  x,
       y;
UBYTE *text;
UBYTE  maxlen;

{
   register UBYTE len = 0;
   /* Text schreiben */
   if (text)
   {
      len = ((len = strlen(text)) > maxlen) ? maxlen : len;
      SetDrMd(RP,JAM2);
      Move(RP,x,y);
      Text(RP,text,len);
   }
   /* Rest löschen */
   SetDrMd(RP,JAM2|INVERSVID);
   RectFill(RP,x+(len<<3),y-6,x+1+(maxlen<<3),y+1);
}

/*    //
    \X/   */
