#include <intuition/intuition.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <graphics/clip.h>
#include <graphics/layers.h>
#include <graphics/text.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/diskfont.h>
#include "ArpBase.h"
#include "LabelDef.h"


struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct LayersBase *LayersBase;
struct DiskfontBase *DiskfontBase;
struct ArpBase *ArpBase;
struct Process *LabelProcess;
struct AvailFontsHeader *MyAvlFntsHeader;
struct Screen *CtrlScreen;
struct Window *CtrlWindow, *EditWindow, *OldReqWindow;
struct RastPort *crp, *erp, *wrp, *prp, *brp;
struct ViewPort *cvp;
struct Preferences OldPrefs, NewPrefs;

struct LabelText *FirstText, *CurrText, *SelectedText;

struct FileRequester *MyFileReq;

extern struct NewScreen LabelScreenData;
extern struct NewWindow EditWinData, LabelWinData;
extern struct NewWindow MessWinData, BoolWinData, SetUpWinData;
extern struct Image CtrlMenuImage, EditMenuImage, TitleStripImage;
extern struct Image LMessTextImage, DefaultMenuImage;
extern struct Gadget TextGadg, ContinueGadg, GirlGadg, WholeTextGadg;
extern struct Gadget NoGadg, YesGadg, LabelGapGadg;
extern struct StringInfo TextInfo, LabelGapInfo, PrintWidthInfo;
extern struct StringInfo PrintHeightInfo;
extern UWORD MyColorMap[16], DefaultMap[16], GirlCMap[16];
extern USHORT Pointer[3][41];
extern BYTE InformationText[2][14][51], WholeText[257];


int NumberOfFonts, IsArc, Last_Data, rm, LabelSkip;
int PrintWidth, PrintHeight, FontBufferSize;

UWORD FullColorMap[32];

LONG PicLeftEdge, PicTopEdge, PicWidth, PicHeight, PicOn;

BYTE FileName[34], DirName[34];

#define NO_FAULT 0
#define NO_INTUI 1
#define NO_GRAFX 2
#define NO_LAYER 3
#define NO_DISKF 4
#define NO_LSCRN 5
#define NO_WRAST 6
#define NO_PRAST 7
#define NO_BRAST 8
#define NO_LWIND 9
#define NO_FONTS 10
#define NO_FONTO 11
#define NO_MEMOR 12
#define NO_ARPLB 13
#define NO_EWIND 14


struct LabelText DefaultLabelText =
{
 0,0,
 "topaz",9,
 LTS_PLAIN,
 LTA_LEFT,
 LTP_FREE,
 LTB_NONE,
 1,0,
 "...",
 NULL,
 NULL,
 NULL
};



int
MouseState()
{
 struct IntuiMessage *MyMess;
 LONG Art, back, Ort;
 APTR *Wo;
 struct Gadget *NoWarnGadg;

 back =0;
 if ( MyMess = (struct IntuiMessage *) GetMsg( CtrlWindow->UserPort))
   {
    Art = MyMess->Class;
    Wo = MyMess->IAddress;
    ReplyMsg( MyMess);
    if ( Art == GADGETUP)
      {
       NoWarnGadg = (struct Gadget *) Wo;
       Ort = NoWarnGadg->GadgetID;
       if ( Ort == 16)
         {
          back = 1;
         }
      }
   }
 return( back);
}



int
StrICmp( a, b)
char *a, *b;
{
 while (( *a)&&( toupper( *a) == toupper( *b)))
   {
    a++;
    b++;
   }
  return( toupper( *a) - toupper( *b));
}



int
CompareAvailFonts(FirstA, SecondA)
struct AvailFonts *FirstA, *SecondA;
{
 int back;
 struct TextAttr *First  = &FirstA->af_Attr;
 struct TextAttr *Second = &SecondA->af_Attr;

 if (!(back = StrICmp( (char *)First->ta_Name, (char*)Second->ta_Name)))
   {
    back = ( First->ta_YSize < Second->ta_YSize)? -1:
           ( First->ta_YSize == Second->ta_YSize)? 0 :1;
   }
 return( back);
}



struct RastPort
*OpenRastPort( Width, Height, Depth)
int Width, Height, Depth;
{
 struct BitMap *MyBM;
 struct RastPort *MyRP;
 struct Layer_Info *MyLI;
 struct Layer *MyLR;
 PLANEPTR The_Planes[8];
 int t, i, PlaneSize, fault, Planes_OK;
 int MemSize;


 MemSize = AvailMem( MEMF_PUBLIC);
 MyBM = NULL;
 MyRP = NULL;
 MyLI = NULL;
 MyLR = NULL;
 PlaneSize = RASSIZE( Width, Height);
 Planes_OK =1;
 fault =1;
 t =0;
 while((t < Depth)&& Planes_OK)
   {
    Planes_OK = (The_Planes[t] = (PLANEPTR) AllocMem( PlaneSize,
                                   MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR))? 1: 0;
    t++;
   }
 t--;
 if ( Planes_OK)
   {
    MyBM = (struct BitMap *)
            AllocMem( sizeof( struct BitMap), MEMF_PUBLIC|MEMF_CLEAR);
    if ( MyBM)
      {
       InitBitMap( MyBM, Depth, Width, Height);
       for( i =0; i < Depth; i++)
         {
          MyBM->Planes[i] = The_Planes[i];
         }
       MyLI = (struct Layer_Info *)NewLayerInfo();
       if (MyLI)
         {
          MyLR = (struct Layer *)
                  CreateUpfrontLayer( MyLI, MyBM, 0, 0, Width -1, Height -1,
                                      LAYERSIMPLE, NULL);
          if (MyLR)
            {
             MyRP = MyLR->rp;
             fault = 0;
            }
         }
      }
   }
 if ( fault)
   {
    if (MyLI) DisposeLayerInfo( MyLI);
    if (MyBM) FreeMem( MyBM, sizeof( struct BitMap));
    i =0;
    while((i < t) && The_Planes[i])
      {
       FreeMem( The_Planes[i], PlaneSize);
       i++;
      }
   }
 MemSize -= AvailMem( MEMF_PUBLIC);
 return( MyRP);
}



void
CloseRastPort( The_RP)
struct RastPort *The_RP;
{
 struct Layer_Info *MyLI;
 struct Layer *MyLR;
 struct BitMap *MyBM;
 int t, Depth, PlaneSize;
 int MemSize;


 MemSize = AvailMem( MEMF_PUBLIC);
 MyBM = The_RP->BitMap;
 MyLR = The_RP->Layer;
 MyLI = MyLR->LayerInfo;
 Depth = MyBM->Depth;
 PlaneSize = MyBM->BytesPerRow * MyBM->Rows;
 DeleteLayer( MyLI, MyLR);
 DisposeLayerInfo( MyLI);
 for( t=0; t < Depth; t++)
   {
    FreeMem( MyBM->Planes[t], PlaneSize);
   }
 FreeMem( MyBM, sizeof( struct BitMap));
 MemSize = AvailMem( MEMF_PUBLIC) - MemSize;
}



void
LMMessage( The_Message)
BYTE *The_Message;
{
 struct Window *MessWindow;
 struct RastPort *mrp;
 struct ViewPort *mvp;
 struct IntuiMessage *MyMess;
 int MessLength, TitlePos;
 LONG Art;
 BYTE Nu_Message[79];

 strncpy( Nu_Message, The_Message, 78);
 Nu_Message[78] =0;
 MessLength = strlen( Nu_Message)*8 + 16;
 if (MessLength < 171 ) MessLength = 171;
 TitlePos = ( MessLength - 155)/2;
 MessWinData.Width  = MessLength;
 MessWinData.Height = 50;
 MessWinData.LeftEdge = (640- MessLength)/2;
 MessWinData.TopEdge = 70;
 MessWinData.Screen = CtrlScreen;
 if (MessWindow = (struct Window *) OpenWindow(&MessWinData))
   {
    mrp = MessWindow->RPort;
    mvp = &CtrlScreen->ViewPort;
    LoadRGB4( mvp, DefaultMap, 16);
    SetDrMd( mrp, JAM2);
    SetAPen( mrp, 1);
    RectFill( mrp, 0, 0, MessLength -1, 49);
    SetAPen( mrp, 0);
    RectFill( mrp, 2, 1, MessLength -3, 48);
    SetAPen( mrp, 1);
    RectFill( mrp, 4, 2, MessLength -5, 47);
    SetAPen( mrp, 0);
    RectFill( mrp, 2, 15, MessLength -3, 15);
    SetAPen( mrp, 1);
    DrawImage( mrp, &LMessTextImage, TitlePos, 2);
    SetAPen( mrp, 0);
    SetBPen( mrp, 1);
    Move( mrp, 8, 24);
    Text( mrp, Nu_Message, strlen( Nu_Message));
    SetAPen( mrp, 1);
    RefreshGadgets( &ContinueGadg, MessWindow, NULL);
    Art = NULL;
    while ( Art != GADGETUP)
      {
       if (MyMess = (struct IntuiMessage *) GetMsg( MessWindow->UserPort))
         {
          Art = MyMess->Class;
          ReplyMsg( MyMess);
         }
      }
    LoadRGB4( mvp, MyColorMap, 16);
    CloseWindow( MessWindow);
   }
}



int
LMDecision( The_Message)
BYTE *The_Message;
{
 struct Window *BoolWindow;
 struct RastPort *brp;
 struct ViewPort *bvp;
 struct IntuiMessage *MyMess;
 int MessLength, TitlePos;
 LONG Art, Ort;
 BYTE Nu_Message[79];

 strncpy( Nu_Message, The_Message, 78);
 Nu_Message[78] =0;
 MessLength = strlen( Nu_Message)*8 + 16;
 if (MessLength < 171 ) MessLength = 171;
 TitlePos = ( MessLength - 155)/2;
 BoolWinData.Width  = MessLength;
 BoolWinData.Height = 50;
 BoolWinData.LeftEdge = (640- MessLength)/2;
 BoolWinData.TopEdge = 70;
 BoolWinData.Screen = CtrlScreen;
 if (BoolWindow = (struct Window *) OpenWindow(&BoolWinData))
   {
    brp = BoolWindow->RPort;
    bvp = &CtrlScreen->ViewPort;
    LoadRGB4( bvp, DefaultMap, 16);
    SetDrMd( brp, JAM2);
    SetAPen( brp, 1);
    RectFill( brp, 0, 0, MessLength -1, 49);
    SetAPen( brp, 0);
    RectFill( brp, 2, 1, MessLength -3, 48);
    SetAPen( brp, 1);
    RectFill( brp, 4, 2, MessLength -5, 47);
    SetAPen( brp, 0);
    RectFill( brp, 2, 15, MessLength -3, 15);
    SetAPen( brp, 1);
    DrawImage( brp, &LMessTextImage, TitlePos, 2);
    SetAPen( brp, 0);
    SetBPen( brp, 1);
    Move( brp, 8, 24);
    Text( brp, Nu_Message, strlen( Nu_Message));
    SetAPen( brp, 1);
    RefreshGadgets( &YesGadg, BoolWindow, NULL);
    RefreshGadgets( &NoGadg, BoolWindow, NULL);
    Art = NULL;
    Ort = 0;
    while (( Ort != 1)&&(Ort != 2))
      {
       if (MyMess = (struct IntuiMessage *) GetMsg( BoolWindow->UserPort))
         {
          Art = MyMess->Class;
          if ( Art == GADGETUP)
            {
             Ort = MyMess->IAddress->GadgetID;
            }
          ReplyMsg( MyMess);
         }
      }
    LoadRGB4( bvp, MyColorMap, 16);
    CloseWindow( BoolWindow);
   }
 return( (Ort == 1) ? 1: 0);
}



int
LMFilePatch( The_Message)
BYTE *The_Message;
{
 struct Window *BoolWindow;
 struct RastPort *brp;
 struct ViewPort *bvp;
 struct IntuiMessage *MyMess;
 int MessLength, TitlePos;
 LONG Art, Ort;
 BYTE Nu_Message[79];

 strncpy( Nu_Message, The_Message, 78);
 Nu_Message[78] =0;
 MessLength = strlen( Nu_Message)*8 + 16;
 if (MessLength < 304 ) MessLength = 304;
 if (MessLength > 630 ) MessLength = 630;
 TitlePos = ( MessLength - 155)/2;
 BoolWinData.Width  = MessLength;
 BoolWinData.Height = 60;
 BoolWinData.LeftEdge = (640- MessLength)/2;
 BoolWinData.TopEdge = 75;
 BoolWinData.Screen = CtrlScreen;
 YesGadg.NextGadget = &WholeTextGadg;
 if (BoolWindow = (struct Window *) OpenWindow(&BoolWinData))
   {
    brp = BoolWindow->RPort;
    bvp = &CtrlScreen->ViewPort;
    LoadRGB4( bvp, DefaultMap, 16);
    SetDrMd( brp, JAM2);
    SetAPen( brp, 1);
    RectFill( brp, 0, 0, MessLength -1, 59);
    SetAPen( brp, 0);
    RectFill( brp, 2, 1, MessLength -3, 58);
    SetAPen( brp, 1);
    RectFill( brp, 4, 2, MessLength -5, 57);
    SetAPen( brp, 0);
    RectFill( brp, 2, 15, MessLength -3, 15);
    SetAPen( brp, 1);
    DrawImage( brp, &LMessTextImage, TitlePos, 2);
    SetAPen( brp, 0);
    SetBPen( brp, 1);
    Move( brp, 8, 24);
    Text( brp, Nu_Message, strlen( Nu_Message));
    SetAPen( brp, 1);
    RefreshGadgets( &YesGadg, BoolWindow, NULL);
    RefreshGadgets( &NoGadg, BoolWindow, NULL);
    ActivateGadget( &WholeTextGadg, BoolWindow, NULL);
    Art = NULL;
    Ort = 0;
    while (( Ort != 1)&&(Ort != 2))
      {
       if (MyMess = (struct IntuiMessage *) GetMsg( BoolWindow->UserPort))
         {
          Art = MyMess->Class;
          if ( Art == GADGETUP)
            {
             Ort = MyMess->IAddress->GadgetID;
            }
          ReplyMsg( MyMess);
         }
      }
    LoadRGB4( bvp, MyColorMap, 16);
    CloseWindow( BoolWindow);
   }
 YesGadg.NextGadget = NULL;
 return( (Ort == 1) ? 1: 0);
}



void
LMInformation()
{
 struct Window *MessWindow;
 struct RastPort *mrp;
 struct ViewPort *mvp;
 struct IntuiMessage *MyMess;
 LONG Art, Ort;
 int MessLength, t, TitlePos, ScreenShown;

 MessLength = strlen( &InformationText[0][0])*8 + 16 +115;
 if (MessLength < 171 ) MessLength = 171;
 if (MessLength > 626 ) MessLength = 626;
 TitlePos = (MessLength - 155)/2;
 MessWinData.Width  = MessLength;
 MessWinData.Height = 148;
 MessWinData.LeftEdge = (640- MessLength)/2;
 MessWinData.TopEdge = 25;
 MessWinData.Screen = CtrlScreen;
 ContinueGadg.NextGadget = &GirlGadg;
 if (MessWindow = (struct Window *) OpenWindow(&MessWinData))
   {
    mrp = MessWindow->RPort;
    mvp = &CtrlScreen->ViewPort;
    LoadRGB4( mvp, GirlCMap, 16);
    SetDrMd( mrp, JAM2);
    SetAPen( mrp, 1);
    RectFill( mrp, 0, 0, MessLength -1, 147);
    SetAPen( mrp, 0);
    RectFill( mrp, 2, 1, MessLength -3, 146);
    SetAPen( mrp, 1);
    RectFill( mrp, 4, 2, MessLength -5, 145);
    SetAPen( mrp, 0);
    RectFill( mrp, 2, 15, MessLength -3, 15);
    SetAPen( mrp, 1);
    DrawImage( mrp, &LMessTextImage, TitlePos, 2);
    SetAPen( mrp, 0);
    SetBPen( mrp, 1);
    for ( t=0; t < 14; t++)
      {
       Move( mrp, 8, 24 + t*9);
       Text( mrp, &InformationText[0][t][0],
                  strlen( &InformationText[0][t][0]));
      }
    RefreshGList( &ContinueGadg, MessWindow, NULL, 1);
    ScreenShown = 0;
    Art = NULL;
    Ort = 0;
    while ( Ort != 2)
      {
       if (MyMess = (struct IntuiMessage *) GetMsg( MessWindow->UserPort))
         {
          Art = MyMess->Class;
          if (Art == GADGETUP)
            {
             Ort = MyMess->IAddress->GadgetID;
            }
          ReplyMsg( MyMess);
          if ((Ort == 1)&&(Art == GADGETUP))
            {
             ScreenShown ^= 1;
             for ( t=0; t < 14; t++)
               {
                Move( mrp, 8, 24 + t*9);
                Text( mrp, &InformationText[ScreenShown][t][0],
                           strlen( &InformationText[ScreenShown][t][0]));
               }
             RefreshGadgets( &GirlGadg, MessWindow, NULL);
            }
         }
      }
    LoadRGB4( mvp, MyColorMap, 16);
    CloseWindow( MessWindow);
    ContinueGadg.NextGadget = NULL;
   }
}



void
PointerState( Which)
int Which;
{
 if (( Which > -1)&&( Which < 3))
   {
    CopyMem( &Pointer[Which][0], &NewPrefs.PointerMatrix[0], 72);
    CopyMem( MyColorMap, FullColorMap, 32);
    NewPrefs.XOffset = Pointer[Which][36];
    NewPrefs.YOffset = Pointer[Which][37];
    FullColorMap[17] = Pointer[Which][38];
    FullColorMap[18] = Pointer[Which][39];
    FullColorMap[19] = Pointer[Which][40];
    SetPrefs( &NewPrefs, sizeof( struct Preferences), FALSE);
    LoadRGB4( cvp, FullColorMap, 32);
   }
}



int
OpenEnvironment()
{
 int fault, PointerBack;

 FontBufferSize =0;
 PointerBack =0;
 OldReqWindow = NULL;
 fault = (IntuitionBase = (struct IntuitionBase *)
          OpenLibrary("intuition.library",0L))? NO_FAULT: NO_INTUI;
 if (!fault)
   {
    fault = (GfxBase =(struct GfxBase *)OpenLibrary("graphics.library",0L))?
            NO_FAULT: NO_GRAFX;
   }
 if (!fault)
   {
    fault = (LayersBase =(struct LayersBase *)OpenLibrary("layers.library",0L))?
             NO_FAULT: NO_LAYER;
   }
 if (!fault)
   {
    fault = (DiskfontBase = OpenLibrary("diskfont.library",0L))?
             NO_FAULT: NO_DISKF;
   }
 if (!fault)
   {
    fault = (CtrlScreen = (struct Screen *) OpenScreen( &LabelScreenData))?
            NO_FAULT: NO_LSCRN;
   }
 if (!fault)
   {
    ShowTitle( CtrlScreen, FALSE);
    fault = (wrp = (struct RastPort *) OpenRastPort( 320, 184, 4))?
            NO_FAULT: NO_WRAST;
   }
 if (!fault)
   {
    fault = (prp = (struct RastPort *) OpenRastPort( 320, 184, 4))?
            NO_FAULT: NO_PRAST;
   }
 if (!fault)
   {
    fault = (brp = (struct RastPort *) OpenRastPort( 320, 184, 4))?
            NO_FAULT: NO_BRAST;
   }
 if (!fault)
   {
    LabelWinData.Screen = CtrlScreen;
    fault = (CtrlWindow = (struct Window *) OpenWindow( &LabelWinData))?
            NO_FAULT:NO_LWIND;
   }
 if (!fault)
   {
    if (ArpBase = (struct Library *) OpenLibrary("arp.library",0L))
      {
       if (!(MyFileReq = ArpAllocFreq()))
         {
          CloseLibrary( ArpBase);
          ArpBase = NULL;
         }
      }
    GetPrefs( &OldPrefs, sizeof( struct Preferences));
    GetPrefs( &NewPrefs, sizeof( struct Preferences));
    cvp = &CtrlScreen->ViewPort;
    crp = CtrlWindow->RPort;
    LoadRGB4( cvp, &MyColorMap[0], 16L);
    DrawImage( crp, &TitleStripImage, 0, 0);
    DrawImage( crp, &CtrlMenuImage, 512, 14);
    CopyMem( MyColorMap, FullColorMap, 32);
    PointerState( 2);
    PointerBack =2;
   }
 if (!fault)
   {
    fault = (FontBufferSize = AvailFonts( NULL, 0, AFF_DISK | AFF_MEMORY))?
            NO_FAULT: NO_FONTO;
   }
 if (!fault)
   {
    fault = (MyAvlFntsHeader = (struct AvailFontsHeader *)
               AllocMem( FontBufferSize, MEMF_CLEAR | MEMF_PUBLIC))?
            NO_FAULT: NO_MEMOR;
   }
 if (!fault)
   {
    fault = (!(AvailFonts( MyAvlFntsHeader, FontBufferSize, AFF_DISK | AFF_MEMORY)))?
            NO_FAULT: NO_FONTS;
   }
 if (!fault)
   {
    NumberOfFonts = MyAvlFntsHeader->afh_NumEntries;
    qsort( &MyAvlFntsHeader[1], NumberOfFonts, sizeof( struct AvailFonts),
           CompareAvailFonts);
    if (LabelProcess = (struct Process *) FindTask(NULL))
      {
       OldReqWindow = (struct Window *) LabelProcess->pr_WindowPtr;
       LabelProcess->pr_WindowPtr = CtrlWindow;
      }
    if ( ArpBase == NULL) LMMessage("You really should use the ARP.LIBRARY");
   }
 if (PointerBack) PointerState( 0);
 return( fault);
}



void
CloseEnvironment( How_Far)
int How_Far;
{
 switch( How_Far)
   {
    case NO_FAULT: if (OldReqWindow && LabelProcess)
                     {
                      LabelProcess->pr_WindowPtr = OldReqWindow;
                     }
    case NO_FONTS: if ( ArpBase) CloseLibrary( ArpBase);
                   FreeMem( MyAvlFntsHeader, FontBufferSize);
    case NO_MEMOR: SetPrefs( &OldPrefs, sizeof( struct Preferences), FALSE);
    case NO_FONTO: CloseWindow( CtrlWindow);
    case NO_LWIND: CloseRastPort( brp);
    case NO_BRAST: CloseRastPort( prp);
    case NO_PRAST: CloseRastPort( wrp);
    case NO_WRAST: CloseScreen( CtrlScreen);
    case NO_LSCRN: CloseLibrary( DiskfontBase);
    case NO_DISKF: CloseLibrary( LayersBase);
    case NO_LAYER: CloseLibrary( GfxBase);
    case NO_GRAFX: CloseLibrary( IntuitionBase);
                   break;
    case NO_INTUI: puts("Someone has stolen your ROMs !!!");
                   break;
    default:       puts("Illegal shutdown code received.");
                   break;
   }
}



int
FindAttrNo( The_Font, The_Size)
BYTE *The_Font;
int  The_Size;
{
 int count, found;
 BYTE buffer[50];
 struct AvailFonts *FirstAvail;
 struct TextAttr *MyAttr;
 BYTE errBuff[80];

 count = 0;
 found = 0;
 FirstAvail = &MyAvlFntsHeader[1];
 while ((count < NumberOfFonts)&&(found ==0))
   {
    strcpy( buffer, The_Font);
    strcat( buffer, ".font");
    MyAttr = &(FirstAvail + count)->af_Attr;
    found = (strcmp( buffer, MyAttr->ta_Name) == 0)? 1: 0;
    if ( The_Size != MyAttr->ta_YSize)
      {
       found = 0;
      }
    count++;
   }
 if (found == 0)
   {
    strcpy( errBuff, The_Font);
    sprintf(buffer,"%d", The_Size);
    strcat( errBuff, buffer);
    strcat( errBuff, " not available!");
    LMMessage( errBuff);
   }
 return( count -1);
}



int
FindBottom( Start, The_Text)
struct LabelText *Start, *The_Text;
{
 struct LabelText *Curr, *MaxText;
 int MaxPos, CurrPos;

 Curr = FindStart( FirstText);
 if ( Curr != NULL)
   {
    MaxPos = 0;
    MaxText = NULL;
    while ( Curr != NULL)
      {
       CurrPos = (Curr->TopEdge) +(Curr->Width);
       if (( CurrPos > MaxPos)&&(The_Text != Curr))
         {
          MaxPos = CurrPos;
          MaxText = Curr;
         }
       Curr = Curr->NextText;
      }
   }
 return( MaxPos);
}



int
ReadASC( fh, Data, how)
struct FileHandle *fh;
BYTE *Data;
int how;
{
 int Back;

 if (how == 0)
   {
    Back = 1;
    *Data = Last_Data;
    rm = 1;
   }
 else
   {
    Back = Read( fh, Data, 1L);
    Last_Data = *Data;
   }
 return( Back);
}



void
ReadASCText( fh, Text, confirm)
struct FileHandle *fh;
BYTE *Text;
int *confirm;
{
 BYTE data;
 int count;

 data = 0;
 while((data != 34)&&((*confirm) == 1))
   {
    *confirm = ReadASC( fh, &data, rm);
   }
 count =0;
 data = 0;
 while((data != 34)&&((*confirm) == 1)&&(count < 60))
   {
    *confirm = ReadASC( fh, &data, rm);
    if (data != 34)
      {
       Text[count] = data;
       count++;
      }
   }
 Text[count] =0;
}



int
ReadASCNumber( fh, confirm)
struct FileHandle *fh;
int *confirm;
{
 int So_far, ok;
 BYTE data;

 So_far =0;
 ok = 1;
 while(((*confirm) ==1)&&(ok != 0))
   {
    *confirm = ReadASC( fh, &data, rm);
    if ((data > 47)&&(data < 58))
      {
       So_far *= 10;
       So_far += data - 48;
       ok = 1;
      }
    else
      {
       ok =0;
      }
   }
 rm = 0;
 return( So_far);
}



struct LabelText
*ReadTextFile( TextFileName)
BYTE *TextFileName;
{
 struct FileHandle *InFile;
 struct LabelText *Curr;
 int StillMore;
 int The_Place, The_Style, The_Align, The_Top, The_Size, The_BgCol;
 int The_FgCol, The_Border;
 int The_AttrNo, Text_Finished, MissTries;
 BYTE The_Font[21], The_Text[61];
 BYTE Data, MyBuffer[80];

 Curr = NULL;
 MissTries =0;
 if (InFile = (struct FileHandle *) Open( TextFileName, MODE_OLDFILE))
   {
    PointerState( 2);
    DeleteAllTexts( FindStart( FirstText));
    FirstText = NULL;
    StillMore = 1;
    rm = 1;
    while (( StillMore == 1)&&(MissTries < 25))
      {
       The_Top = 0;
       strcpy(The_Font,"topaz");
       The_Text[0] =0;
       The_Size    = 9;
       The_Style   = LTS_PLAIN;
       The_Place   = LTP_FREE;
       The_Align   = LTA_LEFT;
       The_Border  = LTB_NONE;
       The_BgCol   = 1;
       The_FgCol   = 0;
       The_AttrNo  = 0;
       Text_Finished = 0;
       while (( StillMore ==1)&&(Text_Finished == 0)&&(MissTries < 25))
         {
          StillMore = ReadASC( InFile, &Data, rm);
          if (( Data > 96)&&( Data < 123))
            {
             Data = Data - 32;
            }
          switch (Data)
            {
             case 'U': The_Style |= LTS_UNDERLINED;
                       break;
             case 'B': The_Style |= LTS_BOLD;
                       break;
             case 'I': The_Style |= LTS_ITALIC;
                       break;
             case 'L': The_Align = LTA_LEFT;
                       break;
             case 'R': The_Align = LTA_RIGHT;
                       break;
             case 'M': The_Align = LTA_CENTERED;
                       break;
             case 'O': The_Border = LTB_TOP;
                       break;
             case 'G': The_Border = LTB_BOTTOM;
                       break;
             case 'S': The_Border = LTB_SIDES;
                       break;
             case 'V': The_Top = FindBottom( FindStart( FirstText), NULL);
                       if (The_Top > LABEL_BOTTOM) The_Top = 0;
                       The_Place =0;
                       break;
             case 'D': The_Top = ReadASCNumber( InFile, &StillMore);
                       The_Place =1;
                       break;
             case 'P': The_BgCol = ReadASCNumber( InFile, &StillMore);
                       break;
             case 'C': The_FgCol = ReadASCNumber( InFile, &StillMore);
                       break;
             case 'F': ReadASCText( InFile, MyBuffer, &StillMore);
                       strncpy( The_Font, MyBuffer, 21);
                       The_Size = ReadASCNumber( InFile, &StillMore);
                       break;
             case 'T': ReadASCText( InFile, MyBuffer, &StillMore);
                       strncpy( The_Text, MyBuffer, 61);
                       break;
             case  32:
             case  10:
             case  13:
             case  44:
             case 127: break;
             case  59: Text_Finished = 1;
                       break;
             default:  MissTries++;
                       break;
            }
          if( Text_Finished == 1)
            {
             The_AttrNo = FindAttrNo( The_Font, The_Size);
             Curr = CreateText( The_Font, The_Size, The_Style, The_Align,
                                The_Place, The_Border, The_BgCol,
                                The_FgCol,  The_Text, The_AttrNo);
             if ( Curr != NULL)
               {
                ChangeCoords( Curr, The_Top);
               }
             if ( FirstText == NULL) FirstText = Curr;
             AddText( FindEnd( FirstText), Curr);
            }
         }
      }
    Close( InFile);
    PointerState( 0);
   }
 if ( MissTries > 24)
   {
    LMMessage("I've read too many illegal characters");
   }
 return( Curr);
}



ClearLabelArea()
{
 SetAPen( crp, 0);
 RectFill( crp, LABEL_LEFT,  LABEL_BACK +1,
                LABEL_RIGHT, LABEL_BACK +1);
 RectFill( crp, LABEL_LEFT,  LABEL_STRIP_END +1,
                LABEL_RIGHT, LABEL_STRIP_END +1);
 SetAPen( crp, 1);
 RectFill( crp, LABEL_LEFT,  LABEL_TOP,
                LABEL_RIGHT, LABEL_BACK);
 RectFill( crp, LABEL_LEFT,  LABEL_STRIP_START,
                LABEL_RIGHT, LABEL_STRIP_END);
 RectFill( crp, LABEL_LEFT,  LABEL_START,
                LABEL_RIGHT, LABEL_BOTTOM);
}



void
ComplRect( rstprt, LeftEdge, TopEdge, Width, Height)
struct RastPort *rstprt;
int LeftEdge, TopEdge, Width, Height;
{
 int RightEdge, BottomEdge;

 SetAPen( rstprt, 7);
 SetDrMd( rstprt, JAM2|COMPLEMENT);
 RightEdge  = ( Width < 1)? LeftEdge: LeftEdge + Width -1;
 BottomEdge = (Height < 1)? TopEdge : TopEdge + Height -1;
 RectFill( rstprt, LeftEdge, TopEdge, RightEdge, BottomEdge);
 SetDrMd( rstprt, JAM2);
 SetAPen( rstprt, 1);
}



MakeADOSStr( Dir, Name, Full)
BYTE *Dir, *Name , *Full;
{
 int l;

 strcpy( Full, Dir);
 l = strlen( Full);
 if ((strlen( Dir) != 0)&&(Full[l -1] != 58))
   {
    Full[l]    = 47;
    Full[l +1] = 0;
   }
 strcat( Full, Name);
}



void
AttrToName( ThatAttr, ThatName)
struct TextAttr *ThatAttr;
UBYTE *ThatName;
{
 int length;

 strcpy( ThatName, ThatAttr->ta_Name);
 length = strlen( ThatName) -5;
 if (length > 13) length = 13;
 if (length < 1) length = 1;
 ThatName[length] = 47;
 sprintf( &ThatName[length +1], "%d", ThatAttr->ta_YSize);
}



void
PaintLabelText( The_Text)
struct LabelText *The_Text;
{
 struct AvailFonts *First_Avail;
 struct TextAttr *The_Attr;
 struct TextFont *The_Font;
 LONG The_Style, The_BgCol, The_Base, The_Length, The_Size, t, Offset;
 LONG The_Enable, The_Border, The_FgCol, The_Width, The_DrawX;

 if ( The_Text != NULL)
   {
    SetAPen( wrp, 1);
    SetBPen( wrp, 1);
    SetDrMd( wrp, JAM2);
    RectFill( wrp, 0, 0, LABEL_WIDTH -1, LABEL_HEIGHT -1);
    First_Avail = &MyAvlFntsHeader[1];
    The_Attr = &(First_Avail + The_Text->AttrNumber)->af_Attr;
    if ((The_Font = (struct TextFont*) OpenDiskFont( The_Attr))!= NULL)
      {
       if (SetFont( wrp, The_Font))
         {
          The_Base   = The_Font->tf_Baseline;
          The_BgCol  = (LONG)(The_Text->BgColor);
          The_FgCol  = (LONG)(The_Text->FgColor);
          The_Border = (LONG)(The_Text->Border);
          The_Width  = (LONG)(The_Text->Width);
          The_Enable = AskSoftStyle( wrp);
          SetSoftStyle( wrp, (LONG)(The_Text->Style), The_Enable);
          The_Length = TextLength( wrp, The_Text->Text,
                                        strlen( The_Text->Text));
          The_DrawX = ( The_Border & LTB_SIDES)? 4: 0;
          The_Base += ( The_Border & LTB_TOP)? 2: 1;
          switch( The_Text->Alignment)
            {
             case LTA_LEFT:     Offset = The_DrawX;
                                break;
             case LTA_RIGHT:    Offset = LABEL_WIDTH - The_Length - The_DrawX;
                                break;
             case LTA_CENTERED: Offset = (LABEL_WIDTH - The_Length )/2;
                                 break;
            }
          SetAPen( wrp, The_BgCol);
          RectFill( wrp, 0, 0, LABEL_WIDTH -1, The_Width -1);
          SetAPen( wrp, 0);
          if ( The_Border & LTB_TOP)    RectFill( wrp, 0, 0,
                                            LABEL_WIDTH -1, 0);
          if ( The_Border & LTB_BOTTOM) RectFill( wrp, 0, The_Width -1,
                                            LABEL_WIDTH -1, The_Width -1);
          if ( The_Border & LTB_SIDES)
            {
             RectFill( wrp, 0, 0, 1, The_Width -1);
             RectFill( wrp, LABEL_WIDTH -2, 0, LABEL_WIDTH -1, The_Width -1);
            }
          SetAPen( wrp, The_FgCol);
          SetBPen( wrp, The_BgCol);
          Move( wrp, Offset, The_Base);
          Text( wrp, The_Text->Text, strlen( The_Text->Text));
          if (The_Text->TopEdge <(LABEL_STRIP_END - LABEL_TOP))
            {
             for ( t=0; t < LABEL_WIDTH; t++)
               {
                ClipBlit( wrp, t, 0,
                          brp, LABEL_WIDTH -1-t, 0,
                               1, The_Width, 0xc0);
               }
             for ( t=0; t < The_Width; t++)
               {
                ClipBlit( brp, 0, t,
                          wrp, 0, The_Width -1 -t, LABEL_WIDTH, 1, 0xc0);
               }
            }
         }
       CloseFont( The_Font);
      }
   }
}



void
DrawLabelText( The_Text)
struct LabelText *The_Text;
{
 if ( The_Text != NULL)
   {
    PaintLabelText( The_Text);
    if ((The_Text->TopEdge + The_Text->Width) > LABEL_HEIGHT)
      {
       The_Text->TopEdge = LABEL_HEIGHT - The_Text->Width;
      }
    ClipBlit( wrp, 0,0,
              crp, LABEL_LEFT, (LONG)(The_Text->TopEdge)+LABEL_TOP,
              LABEL_WIDTH, (LONG)(The_Text->Width), 0xc0);
   }
}



void
DrawLabelPic()
{
 if (PicOn != 0)
   {
    ClipBlit( prp, 0,0, crp, LABEL_LEFT+PicLeftEdge, LABEL_TOP + PicTopEdge,
              PicWidth, PicHeight, 0xc0);
   }
}



ReDrawLabel( StartText)
struct LabelText *StartText;
{
 struct LabelText *One_Text;

 PointerState( 2);
 ClearLabelArea();
 if ( PicOn == 1)
   {
    DrawLabelPic();
   }
 One_Text = FindStart( StartText);
 while ( One_Text != NULL)
   {
    DrawLabelText( One_Text);
    One_Text = One_Text->NextText;
   }
 PointerState( 0);
}



PartialRedraw( StartText, ExcludeText)
struct LabelText *StartText, *ExcludeText;
{
 struct LabelText *One_Text;

 PointerState( 2);
 ClearLabelArea();
 if (( PicOn == 1)&&(ExcludeText))
   {
    DrawLabelPic();
   }
 One_Text = FindStart( StartText);
 while ( One_Text != NULL)
   {
    if ( One_Text != ExcludeText) DrawLabelText( One_Text);
    One_Text = One_Text->NextText;
   }
 PointerState( 0);
}



struct LabelText
*Do_Edit_Text( The_Text)
struct LabelText *The_Text;
{
 int Ort, Art;
 struct LabelText *ReturnText;
 struct IntuiMessage *MyMess;
 struct AvailFonts *FirstAvail;
 struct TextAttr *HelpAttr;
 int CurrAlign, CurrStyle, CurrPlace, CurrFontNo, Wo, CurrBgCol;
 int CurrFgCol, CurrBorder;
 char FontName[40], *FoundSlash;
 int t, FontHeight;


 ReturnText = NULL;
 EditWinData.Screen = CtrlScreen;
 if ( EditWindow = (struct Window *) OpenWindow( &EditWinData))
   {
    PointerState( 1);
    erp = EditWindow->RPort;
    FirstAvail = (struct AvailFonts *) &MyAvlFntsHeader[1];
    if ( The_Text != NULL)
      {
       CurrStyle  = The_Text->Style;
       CurrAlign  = The_Text->Alignment;
       CurrPlace  = The_Text->Placement;
       CurrBorder = The_Text->Border;
       CurrBgCol  = The_Text->BgColor;
       CurrFgCol  = The_Text->FgColor;
       CurrFontNo = The_Text->AttrNumber;
       strcpy( TextInfo.Buffer, &(The_Text->Text[0]));
       TextInfo.NumChars = strlen( TextInfo.Buffer);
       TextInfo.BufferPos = 0;
      }
    else
      {
       CurrStyle  = DefaultLabelText.Style;
       CurrAlign  = DefaultLabelText.Alignment;
       CurrPlace  = DefaultLabelText.Placement;
       CurrBorder = DefaultLabelText.Border;
       CurrBgCol  = DefaultLabelText.BgColor;
       CurrFgCol  = DefaultLabelText.FgColor;
       CurrFontNo = DefaultLabelText.AttrNumber;
       strcpy( TextInfo.Buffer, &(DefaultLabelText.Text[0]));
       TextInfo.NumChars = strlen( TextInfo.Buffer);
       TextInfo.BufferPos = 0;
      }
    DrawImage( erp, &EditMenuImage, 0,0);

    for (t=0; t < 16; t++)   /* Draw color tables */
      {
       SetAPen( erp, t);
       RectFill( erp, 48 + t*18, 29, 65+ t*18, 37);
       RectFill( erp, 48 + t*18, 41, 65+ t*18, 49);
      }
    for( t =0; t < 3; t++)   /* Select style fields */
      {
       if (CurrStyle & (1<<t))
         {
          ComplRect( erp, 268 + t*24, 4, 22, 11);
         }
      }
    for( t =0; t < 3; t++)   /* Select border fields */
      {
       if ((CurrBorder & (1<<t)) != 0)
         {
          ComplRect( erp, 268 + t*24, 16, 22, 11);
         }
      }
    ComplRect( erp, 46 + CurrPlace*24, 16, 22, 11);
    ComplRect( erp, 140 + CurrAlign*24, 16, 22, 11);
    ComplRect( erp, 52 + CurrBgCol* 18, 31, 10, 5);
    ComplRect( erp, 52 + CurrFgCol* 18, 43, 10, 5);
    AttrToName(&(FirstAvail +CurrFontNo)->af_Attr, FontName);
    Move( erp, 96, 12);
    Text( erp, FontName, strlen( FontName));
    ActivateGadget( &TextGadg, EditWindow, NULL);
    Ort = 1;
    while ((Ort > 0)&&(Ort < 17))
      {
       if ( MyMess = (struct IntuiMessage *) GetMsg( EditWindow->UserPort))
         {
          Ort = MyMess->IAddress->GadgetID;
          Art = MyMess->Class;
          Wo  = MyMess->MouseX;
          ReplyMsg( MyMess);
          if (( Ort > 2)&&( Ort < 6))
            {
             t = Ort - 3;
             ComplRect( erp, 268 + t*24, 4, 22, 11);
             CurrStyle ^= 1<<t;
            }
          else
            {
             if (( Ort > 5)&&( Ort < 8))
               {
                ComplRect( erp, 46 + CurrPlace*24, 16, 22, 11);
                CurrPlace = Ort -6;
                ComplRect( erp, 46 + CurrPlace*24, 16, 22, 11);
               }
             else
               {
                if (( Ort > 7)&&( Ort < 11))
                  {
                   ComplRect( erp, 140 + CurrAlign*24, 16, 22, 11);
                   CurrAlign = Ort -8;
                   ComplRect( erp, 140 + CurrAlign*24, 16, 22, 11);
                  }
                else
                  {
                   if (( Ort > 10)&&( Ort < 14))
                     {
                      t = Ort - 11;
                      ComplRect( erp, 268 + t*24, 16, 22, 11);
                      CurrBorder ^= 1<<t;
                     }
                   else
                     {
                      switch (Ort)
                        {
                         case 1: if (CurrFontNo > 0)
                                   {
                                    SetAPen( erp, 0);
                                    RectFill( erp, 94, 4, 216, 14);
                                    SetAPen( erp, 1);
                                    CurrFontNo--;
                                    AttrToName(
                                      &(FirstAvail +CurrFontNo)->af_Attr,
                                      FontName);
                                    Move( erp, 96, 12);
                                    Text( erp, FontName, strlen( FontName));
                                   }
                                 break;
                         case 2: if ((CurrFontNo +1) < NumberOfFonts)
                                   {
                                    SetAPen( erp, 0);
                                    RectFill( erp, 94, 4, 216, 14);
                                    SetAPen( erp, 1);
                                    CurrFontNo++;
                                    AttrToName(
                                      &(FirstAvail +CurrFontNo)->af_Attr,
                                      FontName);
                                    Move( erp, 96, 12);
                                    Text( erp, FontName, strlen( FontName));
                                   }
                                 break;
                         case 14: t = (Wo - 48)/18;
                                  if ( t != CurrFgCol)
                                    {
                                     ComplRect( erp, 52 + CurrBgCol* 18, 31,
                                                     10, 5);
                                     CurrBgCol = t;
                                     if (CurrBgCol > 15) CurrBgCol = 15;
                                     if (CurrBgCol < 0)  CurrBgCol = 0;
                                     ComplRect( erp, 52 + CurrBgCol* 18, 31,
                                                     10, 5);
                                    }
                                  break;
                         case 15:
                                  t = (Wo - 48)/18;
                                  if ( t != CurrBgCol)
                                    {
                                     ComplRect( erp, 52 + CurrFgCol* 18, 43,
                                                     10, 5);
                                     CurrFgCol = t;
                                     if (CurrFgCol > 15) CurrFgCol = 15;
                                     if (CurrFgCol < 0)  CurrFgCol = 0;
                                     ComplRect( erp, 52 + CurrFgCol* 18, 43,
                                                     10, 5);
                                    }
                                  break;
                        }
                     }
                  }
               }
            }
         }
      }
    if ( Ort == 17)
      {
       IsArc =0;
       HelpAttr = &(FirstAvail +CurrFontNo)->af_Attr;
       FontHeight = HelpAttr->ta_YSize;
       strcpy( FontName, HelpAttr->ta_Name);
       t = strlen( FontName) -5;
       FontName[t] = 0;
       if ( The_Text == NULL)
         {
          ReturnText = CreateText( FontName, FontHeight, CurrStyle,
                                   CurrAlign, CurrPlace, CurrBorder,
                                   CurrBgCol, CurrFgCol, TextInfo.Buffer,
                                   CurrFontNo);
          if ( ReturnText != NULL)
            {
             if ( FirstText == NULL)
               {
                FirstText = ReturnText;
               }
             else
               {
                InsertText( FindEnd( FirstText), ReturnText, 2);
               }
             CurrText = ReturnText;
            }
         }
       else
         {
          ChangeText( The_Text, FontName, FontHeight, CurrStyle, CurrAlign,
                      CurrPlace, CurrBorder, CurrBgCol, CurrFgCol,
                      TextInfo.Buffer, CurrFontNo);
          CurrText = The_Text;
         }
      }
    PointerState( 0);
    CloseWindow( EditWindow);
   }
 return( ReturnText);
}



void
ToggleText( The_Text)
struct LabelText *The_Text;
{
 if ( The_Text)
   {
    ComplRect( crp, LABEL_LEFT, (long)(The_Text->TopEdge +LABEL_TOP),
                    LABEL_WIDTH, (long)(The_Text->Width) );
   }
}



struct LabelText
*GetSelectedText( y)
int y;
{
 struct LabelText *Curr;
 int t;

 Curr = FindEnd( FirstText);
 if (Curr != NULL)
   {
    while ( (Curr->PrevText != NULL)&&
           (! ((Curr->TopEdge <= y)&&
               ((Curr->TopEdge +Curr->Width) >= y))))
      {
       Curr = Curr->PrevText;
      }
    if ( (Curr->PrevText == NULL)&&
           (! ((Curr->TopEdge <= y)&&
               ((Curr->TopEdge +Curr->Width) >= y))))
      {
       Curr = NULL;
      }
   }
 return( Curr);
}



struct LabelText
*PlaceSelectedText( The_Text)
struct LabelText *The_Text;
{
 struct LabelText *Curr;
 int x, y, y0, yk, YSize, YLimit;
 int CurrPos, MaxPos, YMSize, ExitNow, PosFlag;

 if ( The_Text != NULL)
   {
    PointerState( 1);
    if ( The_Text->Placement == 0)
      {
       MaxPos = FindBottom( FirstText, The_Text);
       if (MaxPos <= (LABEL_HEIGHT -(LONG)(The_Text->Width)))
         {
          ChangeCoords( The_Text, MaxPos);
         }
       else
         {
          The_Text->Placement =1;
         }
      }
    if ( The_Text->Placement != 0)
      {
       The_Text->TopEdge  = LABEL_STRIP_END - LABEL_TOP;
       PosFlag = FALSE;
       PartialRedraw( FindStart( The_Text), The_Text);
       PointerState( 2);
       PaintLabelText( The_Text);
       PointerState( 1);
       YSize = The_Text->Width;
       YMSize = YSize / 2;
       y0 = CtrlScreen->MouseY - YMSize;
       YLimit = LABEL_BOTTOM - YSize +1;
       if ( YLimit < 0)
         {
          YLimit = LABEL_TOP;
          YSize = 8;
         }
       if ( y0 > YLimit) y0 = YLimit;
       if ( y0 < LABEL_TOP) y0 = LABEL_TOP;
       y = y0;
       ExitNow = 0;
       ClipBlit( crp, LABEL_LEFT, y, brp, 0, 0, LABEL_WIDTH, YSize, 0xca);
       ClipBlit( wrp, 0, 0, crp, LABEL_LEFT, y, LABEL_WIDTH, YSize, 0xca);
       while ( ! ExitNow)
         {
          ExitNow = (ExitNow)? 1: MouseState();
          y0 = y;
          while (( y == y0)&&( !ExitNow))
            {
             ExitNow = (ExitNow)? 1: MouseState();
             y = CtrlScreen->MouseY - YMSize;
             if ( y > YLimit) y = YLimit;
             if ( y < LABEL_TOP)  y = LABEL_TOP;
             yk = y - LABEL_TOP;
             if ((yk <(LABEL_STRIP_END - LABEL_TOP))&&(!PosFlag))
               {
                PointerState( 2);
                ClipBlit( brp, 0, 0, crp, LABEL_LEFT, y0,LABEL_WIDTH, YSize, 0xca);
                The_Text->TopEdge  = yk;
                PaintLabelText( The_Text);
                PosFlag = TRUE;
                ClipBlit( crp, LABEL_LEFT, y0, brp, 0, 0, LABEL_WIDTH, YSize, 0xca);
                PointerState( 1);
               }
             else
               {
                if ((yk >=(LABEL_STRIP_END - LABEL_TOP))&&(PosFlag))
                  {
                   PointerState( 2);
                   ClipBlit( brp, 0, 0, crp, LABEL_LEFT, y0,LABEL_WIDTH, YSize, 0xca);
                   The_Text->TopEdge  = yk;
                   PaintLabelText( The_Text);
                   PosFlag = FALSE;
                   ClipBlit( crp, LABEL_LEFT, y0, brp, 0, 0, LABEL_WIDTH, YSize, 0xca);
                   PointerState( 1);
                  }
               }
            }
          ClipBlit( brp, 0, 0, crp, LABEL_LEFT, y0,LABEL_WIDTH, YSize, 0xca);
          ClipBlit( crp, LABEL_LEFT, y, brp, 0, 0, LABEL_WIDTH, YSize, 0xca);
          ClipBlit( wrp, 0, 0, crp, LABEL_LEFT, y, LABEL_WIDTH, YSize, 0xca);
         }
       ChangeCoords( The_Text, y - LABEL_TOP);
      }
    Curr = FindStart( FirstText);
    if (Curr != NULL)
      {
       while ( (Curr->NextText != NULL)&&
              (! ((Curr->TopEdge < y)&&(Curr->NextText->TopEdge > y))))
         {
          Curr = Curr->NextText;
         }
       ReplaceText( CurrText, The_Text, 2);
       ReDrawLabel( FindStart( FirstText));
      }
   }
 while( MouseState() !=0);
 PointerState( 0);
 return( Curr);
}



void
PlacePic()
{
 int x, x0, y, y0, XLimit, YLimit, YMSize, XMSize, ExitNow;

 if (PicOn != 0)
   {
    PartialRedraw( FindStart( FirstText), NULL);
    PointerState( 1);
    XLimit = LABEL_RIGHT - PicWidth +1;
    YLimit = LABEL_BOTTOM - PicHeight +1;
    XMSize = PicWidth / 2;
    YMSize = PicHeight / 2;
    y0 = CtrlScreen->MouseY -YMSize;
    x0 = CtrlScreen->MouseX -XMSize;
    if ( y0 > YLimit)     y0 = YLimit;
    if ( y0 < LABEL_TOP)  y0 = LABEL_TOP;
    if ( x0 > XLimit)     x0 = XLimit;
    if ( x0 < LABEL_LEFT) x0 = LABEL_LEFT;
    y = y0;
    x = x0;
    ClipBlit( crp, x, y, brp, 0, 0, PicWidth, PicHeight, 0xca);
    ClipBlit( prp, 0, 0, crp, x, y, PicWidth, PicHeight, 0xca);
    ExitNow =0;
    while ( !ExitNow)
      {
       ExitNow = (ExitNow)? 1: MouseState();
       y0 = y;
       x0 = x;
       while (( y == y0)&&(x == x0)&&( !ExitNow))
         {
          ExitNow = (ExitNow)? 1: MouseState();
          y = CtrlScreen->MouseY -YMSize;
          x = CtrlScreen->MouseX -XMSize;
          if ( y > YLimit)     y = YLimit;
          if ( y < LABEL_TOP)  y = LABEL_TOP;
          if ( x > XLimit)     x = XLimit;
          if ( x < LABEL_LEFT) x = LABEL_LEFT;
         }
       ClipBlit( brp, 0, 0, crp, x0, y0, PicWidth, PicHeight, 0xca);
       ClipBlit( crp, x, y, brp, 0, 0, PicWidth, PicHeight, 0xca);
       ClipBlit( prp, 0, 0, crp, x, y, PicWidth, PicHeight, 0xca);
      }
    PicTopEdge  = y - LABEL_TOP;
    PicLeftEdge = x - LABEL_LEFT;
    PicOn = 1;
    PointerState( 0);
   }
}



GetMeFileName( The_Message )
BYTE *The_Message;
{
 int ok;
 BYTE *OldDir, *OldFile, *OldHail;

 ok =0;
 if ( ArpBase != NULL)
   {
    OldHail = MyFileReq->fr_Hail;
    OldFile = MyFileReq->fr_File;
    OldDir  = MyFileReq->fr_Dir;
    MyFileReq->fr_Hail = The_Message;
    MyFileReq->fr_File = FileName;
    MyFileReq->fr_Dir = DirName;
    MyFileReq->fr_Window = CtrlWindow;
    ok = FileRequest( MyFileReq);
    MyFileReq->fr_Hail = OldHail;
    MyFileReq->fr_File = OldFile;
    MyFileReq->fr_Dir  = OldDir;
    if (ok != 0)
      {
       MakeADOSStr( DirName, FileName, WholeText);
       ok =1;
      }
   }
 else
   {
    ok = LMFilePatch( The_Message);
   }
 return( ok);
}


int
SetDefaults()
{
 struct Window *SetUpWindow;
 struct RastPort *srp;
 struct ViewPort *svp;
 struct IntuiMessage *MyMess;
 struct Gadget *NoWarnGadg;
 struct LabelText *TempTextBuffer;
 LONG Art, Ort;

 SetUpWinData.Screen = CtrlScreen;
 sprintf(PrintWidthInfo.Buffer, "%d", PrintWidth);
 PrintWidthInfo.BufferPos = 0;
 PrintWidthInfo.DispPos =0;
 PrintWidthInfo.NumChars = strlen( PrintWidthInfo.Buffer);
 PrintWidthInfo.LongInt = PrintWidth;

 sprintf(PrintHeightInfo.Buffer, "%d", PrintHeight);
 PrintHeightInfo.BufferPos = 0;
 PrintHeightInfo.DispPos =0;
 PrintHeightInfo.NumChars = strlen( PrintHeightInfo.Buffer);
 PrintHeightInfo.LongInt = PrintHeight;

 sprintf(LabelGapInfo.Buffer, "%d", LabelSkip);
 LabelGapInfo.BufferPos = 0;
 LabelGapInfo.DispPos =0;
 LabelGapInfo.NumChars = strlen( LabelGapInfo.Buffer);
 LabelGapInfo.LongInt = LabelSkip;

 if (SetUpWindow = (struct Window *) OpenWindow(&SetUpWinData))
   {
    srp = SetUpWindow->RPort;
    svp = &CtrlScreen->ViewPort;
    LoadRGB4( svp, DefaultMap, 16);
    DrawImage( srp, &DefaultMenuImage, 0, 0);
    SetAPen( srp, 1);
    SetBPen( srp, 0);
    RefreshGadgets( &LabelGapGadg, SetUpWindow, NULL);
    ActivateGadget( &LabelGapGadg, SetUpWindow, NULL);
    Art = NULL;
    Ort = 0;
    while (( Ort != 5)&&(Ort != 6))
      {
       if (MyMess = (struct IntuiMessage *) GetMsg( SetUpWindow->UserPort))
         {
          Art = MyMess->Class;
          NoWarnGadg = (struct Gadget *)MyMess->IAddress;
          ReplyMsg( MyMess);
          if ( Art == GADGETUP)
            {
             Ort = NoWarnGadg->GadgetID;
             if ( Ort == 4)
               {
                TempTextBuffer = CurrText;
                Do_Edit_Text( &DefaultLabelText);
                CurrText = TempTextBuffer;
               }
            }
         }
      }
    LoadRGB4( svp, MyColorMap, 16);
    CloseWindow( SetUpWindow);
    if ( Ort == 5)
      {
       LabelSkip   = LabelGapInfo.LongInt;
       PrintWidth  = PrintWidthInfo.LongInt;
       PrintHeight = PrintHeightInfo.LongInt;
      }
   }
}



main()
{
 struct IntuiMessage *MyMess;
 struct LabelText *HelpText;
 int Ort, Art, Do_Draw, help, ContOn, AllIsLost;
 int Environment, MsY;


 if (( Environment = OpenEnvironment()) == 0)
   {
    LabelSkip =0;
    PrintWidth = 2666;
    PrintHeight = 2555;
    PicOn = 0;
    PointerState( 0);
    ClearLabelArea();
    FirstText = NULL;
    CurrText = NULL;
    SelectedText = NULL;
    IsArc =1;
    Ort = 1;
    AllIsLost =0;
    while (( Ort > 0)&&( Ort < 17)&&(AllIsLost == 0))
      {
       if ( MyMess = (struct IntuiMessage *)
                     GetMsg( CtrlWindow->UserPort))
         {
          Ort = MyMess->IAddress->GadgetID;
          Art = MyMess->Class;
          MsY = MyMess->MouseY;
          ReplyMsg( MyMess);
          if (Art == GADGETUP)
            {
             switch( Ort)
               {
                case 1: if (IsArc != 1)
                          {
                           ContOn =
                               LMDecision("Discard this label?");
                          }
                        else
                          {
                           ContOn =1;
                          }
                        if (ContOn == 1)
                          {
                           if (SelectedText)
                             {
                              ToggleText( SelectedText);
                              SelectedText = NULL;
                             }
                           help = GetMeFileName("Enter the label to load");
                           if ( help != 0)
                             {
                              CurrText = LoadLabel( WholeText);
                              LoadRGB4( cvp, MyColorMap, 8L);
                              if (CurrText != NULL)
                                {
                                 ReDrawLabel( FindStart( CurrText));
                                }
                             }
                          }
                        break;
                case 2: help = GetMeFileName("Enter the label to save");
                        if ( help != 0)
                          {
                           if (SelectedText)
                             {
                              ToggleText( SelectedText);
                              SelectedText = NULL;
                             }
                           help = SaveLabel( WholeText);
                           if ( help != -1)
                             {
                              ReDrawLabel( FindStart( CurrText));
                              IsArc =1;
                             }
                          }
                        break;
                case 3: if ( PicOn == 1)
                          {
                           ContOn = LMDecision("Discard current picture?");
                          }
                        else
                          {
                           ContOn =1;
                          }
                        if (ContOn == 1)
                          {
                           if (SelectedText)
                             {
                              ToggleText( SelectedText);
                              SelectedText = NULL;
                             }
                           help = GetMeFileName("Enter the picture to load");
                           if ( help != 0)
                             {
                              if (LoadPicture( prp, WholeText)==0)
                                {
                                 LoadRGB4( cvp, MyColorMap, 8L);
                                 PlacePic();
                                 IsArc =0;
                                }
                              ReDrawLabel( FindStart( CurrText));
                             }
                          }
                        break;
                case 4: if ( FirstText != NULL)
                          {
                           ContOn = LMDecision("Discard currents Texts?");
                          }
                        else
                          {
                           ContOn =1;
                          }
                        if (ContOn == 1)
                          {
                           if (SelectedText)
                             {
                              ToggleText( SelectedText);
                              SelectedText = NULL;
                             }
                           help = GetMeFileName("Enter the text to load");
                           if ( help != 0)
                             {
                              HelpText = ReadTextFile( WholeText);
                              if ( HelpText != NULL)
                                {
                                 ReDrawLabel( FindStart( FirstText));
                                 CurrText = FindEnd( FirstText);
                                 IsArc = 0;
                                }
                              else
                                {
                                 DeleteAllTexts( FindStart( FirstText));
                                }
                             }
                          }
                        break;
                case 5: if (SelectedText)
                          {
                           ToggleText( SelectedText);
                           SelectedText = NULL;
                          }
                        if ( CurrText = Do_Edit_Text( NULL))
                          {
                           PlaceSelectedText( CurrText);
                          }
                        break;
                case 6: if ( SelectedText)
                          {
                           ToggleText( SelectedText);
                           Do_Edit_Text( SelectedText);
                           ReDrawLabel( FindStart( SelectedText));
                           SelectedText = NULL;
                          }
                        else
                          {
                           LMMessage("You have to select a text first!");
                          }
                        break;
                case 7: if ( SelectedText)
                          {
                           ToggleText( SelectedText);
                           PlaceSelectedText( SelectedText);
                           SelectedText = NULL;
                           IsArc = 0;
                          }
                        else
                          {
                           LMMessage("You have to select a text first!");
                          }
                        break;
                case 8: PlacePic();
                        ReDrawLabel( FindStart( CurrText));
                        SelectedText = NULL;
                        IsArc =0;
                        break;
                case 9: if ( SelectedText)
                          {
                           ToggleText( SelectedText);
                           CurrText = DeleteText( SelectedText);
                           if ( FirstText == SelectedText)
                             {
                              FirstText = CurrText;
                             }
                           ReDrawLabel( FindStart( CurrText));
                           IsArc =0;
                           SelectedText = NULL;
                          }
                        else
                          {
                           LMMessage("You have to select a text first!");
                          }
                        break;
               case 10: PicOn = 2;
                        if (SelectedText)
                          {
                           ToggleText( SelectedText);
                           SelectedText = NULL;
                          }
                        ReDrawLabel( FindStart( CurrText));
                        IsArc =0;
                        break;
               case 11: if (IsArc != 1)
                          {
                           ContOn = LMDecision("Delete unsaved label?");
                          }
                        else
                          {
                           ContOn =1;
                          }
                        if (ContOn == 1)
                          {
                           DeleteAllTexts( FindStart( FirstText));
                           FirstText = NULL;
                           CurrText = NULL;
                           SelectedText = NULL;
                           PicOn = 0;
                           CopyMem( DefaultMap, MyColorMap, 16L);
                           ClearLabelArea();
                           LoadRGB4( cvp, MyColorMap, 8L);
                           IsArc = 1;
                          }
                        break;
               case 12: ReDrawLabel( FindStart( CurrText));
                        DumpLabel( CtrlScreen);
                        SelectedText = NULL;
                        break;
               case 13: SetDefaults();
                        if (SelectedText)
                          {
                           ToggleText( SelectedText);
                           SelectedText = NULL;
                          }
                        ReDrawLabel( FindStart( CurrText));
                        break;
               case 14: LMInformation();
                        break;
               case 15: if (IsArc != 1)
                          {
                           ContOn = LMDecision("Discard current label?");
                          }
                        else
                          {
                           ContOn =1;
                          }
                        if (ContOn == 1)
                          {
                           ContOn = LMDecision("Really quit this program?");
                           if (ContOn == 1) AllIsLost = 1;
                          }
                        break;
               case 16: HelpText = GetSelectedText( MsY - LABEL_TOP);
                        ToggleText( SelectedText);
                        if (HelpText)
                          {
                           SelectedText = ( HelpText == SelectedText)?
                                          NULL:
                                          HelpText;
                           ToggleText( SelectedText);
                          }
                        else
                          {
                           SelectedText = NULL;
                          }
                        break;
               }
             if ( CurrText == NULL) CurrText = FirstText;
            }
         }
      }
   }
 DeleteAllTexts( FindStart(FirstText));
 CloseEnvironment( Environment);
}

