/*---(FontDesigner)------ File h1.c ---------*/

#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <graphics/gfxmacros.h>

#include "header.h"

/*-------------------- Externe Variablen aus main -----------------------*/

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern ULONG DiskfontBase,DosBase;
extern BYTE *drawmem;
extern long *cmatrix,Ascii;

/*----------------------- Daten für input_zahl() ------------------------*/

unsigned char bmaske[]=
{
   128,64,32,16,8,4,2,1
};

UBYTE rawkey[]={1,2,3,4,5,6,7,8,9,10,57,18,58,68,61,62,63,45,46,47,29,30,31,
          15,60,74,67,70,65,69,79,78};

UBYTE ascii[]={49,50,51,52,53,54,55,56,57,48,46,101,45,13,55,56,57,52,53,54,
         49,50,51,48,46,45,13,1,8,27,2,3};


/*h1.1---------------------- Zeichnet eine Linie -------------------------*/
void Line(rp,xa,ya,xe,ye,co,drmd)
struct RastPort *rp;
short xa,ya,xe,ye;
BYTE co,drmd;
{

   SetAPen(rp,co);SetDrMd(rp,drmd);
   Move(rp,xa,ya);
   Draw(rp,xe,ye);
}
/*h1.2--------------------- Zeichnet ein Rechteck -----------------------*/
void Box(rp,xa,ya,xe,ye,co,drmd)
struct RastPort *rp;
short xa,ya,xe,ye;
BYTE co,drmd;
{

   SetAPen(rp,co);SetDrMd(rp,drmd);
   Move(rp,xa,ya);
   Draw(rp,xe,ya);Draw(rp,xe,ye);
   Draw(rp,xa,ye);Draw(rp,xa,ya);
}
/*h1.3--------------------- Installiert ein Fenster ---------------------*/
ULONG Make_Window (x,y,w,h,name,flags,iflags,screen)

short x,y,w,h;
char *name;
ULONG flags,iflags;
struct Screen *screen;
{
struct Window *wn;
struct NewWindow NewWindow;

   NewWindow.LeftEdge=x;
   NewWindow.TopEdge=y;
   NewWindow.Width=w;
   NewWindow.Height=h;
   NewWindow.DetailPen=0;
   NewWindow.BlockPen=1;
   NewWindow.Title=name;
   NewWindow.Flags=flags;
   NewWindow.IDCMPFlags=iflags;
   if(screen==NULL)
      NewWindow.Type=WBENCHSCREEN;
   else NewWindow.Type=CUSTOMSCREEN;
   NewWindow.FirstGadget=NULL;
   NewWindow.CheckMark=NULL;
   if (screen==NULL)
      NewWindow.Screen=IntuitionBase->FirstScreen;
   else NewWindow.Screen=screen;
   NewWindow.BitMap=NULL;
   NewWindow.MinWidth=w;
   NewWindow.MinHeight=h;
   NewWindow.MaxWidth=w;
   NewWindow.MaxHeight=h;

      wn=OpenWindow(&NewWindow);

      return(wn);

}
/*h1.4------------------- Holt Intuition-Message ------------------------*/
BYTE ExaIntui (wn,class,code)
struct Window *wn;
ULONG *class;
USHORT *code;
{
struct IntuiMessage *mesg;

   mesg=GetMsg(wn->UserPort);
   if (mesg != NULL)
   {
      *class=mesg->Class;
      *code=mesg->Code;
      ReplyMsg(mesg);
      return(1);
   }
   return(0);
}
/*h1.5--------------------- Gibt Text aus ----------------------------*/
void Text_out (rp,x,y,apen,bpen,drmd,text,maxlen)
struct RastPort *rp;
short x,y,maxlen;
BYTE apen,bpen,drmd;
char *text;
{
   Move(rp,x,y+rp->TxBaseline);
   SetAPen(rp,apen);SetBPen(rp,bpen);SetDrMd(rp,drmd);
   if(maxlen==0)Text(rp,text,strlen(text));
   else Text(rp,text,maxlen);
}
/*h1.6------------- Zeichnet ein ausgefülltes Polygon ------------------*/
BYTE FDrawPolygon(rp,koord,co,drmd)
struct RastPort *rp;
short koord[];
BYTE co,drmd;
{
struct AreaInfo ainfo;
ULONG speicher;
short abuffer[250],i;
struct TmpRas tmp;

   speicher=drawmem;
   InitArea(&ainfo,abuffer,50);
   rp->TmpRas=(struct TmpRas *)InitTmpRas(&tmp,speicher,20480);
   rp->AreaInfo=&ainfo;
   SetDrMd(rp,drmd);SetAPen(rp,co);
   AreaMove(rp,koord[0],koord[1]);
   i=2;
   while(koord[i]>=0)
   {
      AreaDraw(rp,koord[i],koord[i+1]);
      i+=2;
   }
   AreaEnd(rp);
   rp->TmpRas=NULL;rp->AreaInfo=NULL;
   return(1);
}
/*h1.7------------------ Ermittelt Mausklickfeld -------------------------*/
BYTE Prurec (mox,moy,feld,anf,end)
register short mox,moy;
short feld[][4];
register BYTE anf,end;
{
register BYTE i;

   for (i=anf;i<=end;i++)
   {
      if (mox >= feld[i][0] && mox <= feld[i][2] && moy >= feld[i][1]
            && moy <= feld[i][3])
         return(i);
   }
   return(-1);
}
/*h1.8------------------ Eingabe einer double Zahl ----------------------*/
double input_zahl(wind,xa,ya,maxlen,defs)
struct Window  *wind;
short xa,ya;
UBYTE maxlen;
char *defs;
{
struct IntuiMessage *msg;
struct RastPort *rp;
ULONG class,iflags;
UBYTE code,i,pruef(),cpos=0;
char ps[31];
double atof();
void crs_out();

iflags=wind->IDCMPFlags;
ModifyIDCMP(wind,MOUSEBUTTONS|RAWKEY);
maxlen--;
rp=wind->RPort;
for (i=0;i<=29;i++)ps[i]=32;
ps[30]=0;

ya+=rp->TxBaseline;
Move(rp,xa,ya);SetDrMd(rp,JAM2);Text(rp,ps,maxlen+1);

if(strlen(defs) !=0)
{
   strcpy(ps,defs);
   cpos=strlen(defs);
   ps[cpos]=32;
}

ps[maxlen+1]=0;

Move(rp,xa,ya);SetDrMd(rp,JAM2);Text(rp,ps,strlen(ps));
crs_out (rp,cpos,xa,ya);

   FOREVER
   {
         while(msg=(struct IntuiMessage *)GetMsg(wind->UserPort))
         {
            class=msg->Class;
            code=msg->Code;
            ReplyMsg(msg);

            switch (class)
            {
               case MOUSEBUTTONS:
                     if(code != SELECTDOWN)break;
                     crs_out(rp,cpos,xa,ya);
                     ModifyIDCMP(wind,iflags);
                     return (atof(ps));

               case RAWKEY:
               code=pruef(code);
               if (code==128)break;
               switch (code)
               {
                  case 1: /* Delete */
                     if(cpos==maxlen)
                     {
                        ps[cpos]=32;ps[cpos+1]=0;break;
                     }
                     for(i=cpos;i<=(maxlen-1);i++)ps[i]=ps[i+1];
                     ps[maxlen]=32;
                     break;

                  case 8: /* Backspace */
                     if(cpos==0)break;
                     cpos--;
                     for(i=cpos;i<=(maxlen-1);i++)ps[i]=ps[i+1];
                     ps[maxlen]=32;
                     break;

                  case 2: /* Cursor left */
                     if(cpos>0)cpos--;
                     break;

                  case 3: /* Cursor right */
                     if(cpos<maxlen)cpos++;
                     break;

                  case 13: /* Carrige Return */
                     crs_out(rp,cpos,xa,ya);
                     ModifyIDCMP(wind,iflags);
                     return (atof(ps));

                  case 27: /* ESC */
                     for(i=0;i<=maxlen;i++)ps[i]=32;
                     cpos=0;
                     break;

                  default:
                     for(i=maxlen;i>=(cpos+1);i--)ps[i]=ps[i-1];
                     ps[cpos]=code;
                     ps[maxlen+1]=0;
                     if (cpos<maxlen)cpos++;
                  }
                  Move(rp,xa,ya);
                  SetDrMd(rp,JAM2);
                  Text(rp,ps,strlen(ps));
                  crs_out(rp,cpos,xa,ya);

            }
         }
      }
}
/*----- Unterfunktionen zu h1.8 ---------*/
void crs_out(rp,cpos,xa,ya)
struct RastPort *rp;
UBYTE cpos;
short xa,ya;
{
register BYTE i;

   Move(rp,xa+TextLength(rp," ",1)*cpos,ya);
   SetDrMd(rp,COMPLEMENT|INVERSVID);
   Text(rp," ",1);
}


UBYTE pruef(code)
USHORT code;
{
register UBYTE i;

   for(i=0;i<=31;i++)
   {
      if(code==rawkey[i]) return(ascii[i]);
   }
   return(128);
}
/*h1.9--------------------- Öffnet Libraries ---------------------------*/
BYTE Oplibs()
{
   IntuitionBase=OpenLibrary("intuition.library",0L);
   GfxBase=OpenLibrary("graphics.library",0L);
   DosBase=OpenLibrary("dos.library",0L);
   DiskfontBase=OpenLibrary("diskfont.library",0L);
   if(DiskfontBase==0)
   {
      Shure(4);
      CloseLibrary(IntuitionBase);
      CloseLibrary(GfxBase);
      exit(0);
   }
   return(0);
}
/*h1.10--------------------- Schließt Libraries ------------------------*/
void Cllibs()
{
   CloseLibrary(DosBase);
   CloseLibrary(DiskfontBase);
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);
}
/*h1.11-------------------- Invertier BS_Bereich -----------------------*/
void Invert(rp,dat)
struct RastPort *rp;
short dat[];
{
   SetDrMd(rp,COMPLEMENT);
   RectFill(rp,dat[0]+1,dat[1]+1,dat[2]-1,dat[3]-1);
}
/*h1.12-------------------- Prüft ob Bit gesetzt -----------------------*/

BYTE TestBit(adr,bioff)
register UBYTE *adr;
register long bioff;
{
   adr+=bioff>>3;
   if((*adr & bmaske[bioff%8]) != 0)
      return(1);
   return(0);
}
/*h1.13--------------------- Bestimmtes Bit setzen ---------------------*/
void SetBit(adr,bioff)
register UBYTE *adr;
register long bioff;
{
   adr+=bioff>>3;
   *adr|=bmaske[bioff%8];
}
/*h1.14-------------------- Bestimmtes Bit löschen ---------------------*/
void ClrBit(adr,bioff)
register UBYTE *adr;
register long bioff;
{
   adr+=bioff>>3;
   *adr&=~bmaske[bioff%8];
}
/*h1.15-------------------- Zeichensatz verschieben --------------------*/
short mdat[][4]=
{
   { 10,16,128,28 },{ 138,16,262,28 },{ 86,33,188,45 },
   { 10,50,64,62 },{ 208,50,262,62 },
};
char *mtxt[]=
{
   "FROM ASCII:","UNTIL ASCII:","TO ASCII:","  OK","CANCEL",
};
short moveas[3]={ 65,128,128 };

void MoveAscii()
{
struct Window *wn;
struct RastPort *rp;
ULONG flags=WINDOWDRAG|ACTIVATE;
ULONG class;
USHORT code;
short i,mox,moy,*point,offs;
void moveout(),MAusf();

   wn=Make_Window(120,100,280,71,"MOVE",flags,MOUSEBUTTONS,0);
   if(wn==0)return();
   rp=wn->RPort;
   SetAPen(rp,1);RectFill(rp,0,11,280,71);
   Box(rp,2,12,277,69,0,JAM1);

   for(i=0;i<=4;i++)
   {
      SetAPen(rp,0);
      RectFill(rp,mdat[i][0],mdat[i][1],mdat[i][2],mdat[i][3]);
      Box(rp,mdat[i][0],mdat[i][1],mdat[i][2],mdat[i][3],2,JAM1);
      Box(rp,mdat[i][0]-1,mdat[i][1],mdat[i][2]+1,mdat[i][3],2,JAM1);
      Text_out(rp,mdat[i][0]+3,mdat[i][1]+3,3,0,JAM2,mtxt[i],0);
   }
   moveout(rp);
   FOREVER
   {
      while(ExaIntui(wn,&class,&code))
      {
         if(code!=SELECTDOWN)break;
         i=Prurec(wn->MouseX,wn->MouseY,mdat,0,4);
         if(i<0)break;
         switch(i)
         {
            case 0: case 1: case 2:
               point=&moveas[i];
               offs=mdat[i][0]+strlen(mtxt[i])*8+3;
               *point=(short)input_zahl(wn,offs,mdat[i][1]+3,3,"");
               if(*point<0)*point=0;
               if(*point>255)*point=255;
               break;

            case 3:
               Invert(rp,mdat[i]);
               MAusf();
            case 4:
               Invert(rp,mdat[i]);
               Delay(5);
               CloseWindow(wn);
               return();
         }
      moveout(rp);
      }
   }
}
/*---- Unterfunktion zu h1.15 ----*/
void moveout(rp)
struct RastPort *rp;
{
short offs,i;
char text[5];

   for(i=0;i<=2;i++)
   {
      sprintf(text,"%3.0f",(float)moveas[i]);
      offs=mdat[i][0]+strlen(mtxt[i])*8+3;
      Text_out(rp,offs,mdat[i][1]+3,3,0,JAM2,text,0);
   }
}
/*---- Unterfunktion zu h1.15 ----*/
void MAusf()
{
short mofa=moveas[0],moua=moveas[1],mota=moveas[2],help;
register short j,i,step=1;
long *adr,*adr1;
long merker=Ascii;

   if(mofa==moua)return();
   if(mofa>moua) { help=mofa;mofa=moua;moua=help; }
   if(mota > mofa && mota < moua)
   {
      mota+=(moua-mofa);
      help=mofa;mofa=moua;moua=help-1;

      step=-1;
   }
   else moua++;

   for(i=mofa;i!=moua;i+=step,mota+=step)
   {
      if(mota>255)continue;
      adr=cmatrix+100*i;
      adr1=cmatrix+100*mota;
      for(j=0;j<=99;j++,adr1++)*adr1=adr[j];
      Ascii=i;
      AsciiOut();
   }
   Ascii=merker;
   AsciiOut();
}
/*-----------------------------------------------------------------------*/

