/*---(FontDesigner)------------ File h3.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 --------------------------*/

extern struct Image *oima,*drima,*mima;
extern struct FileInfoBlock *f_info;
extern struct RastPort *rast;
extern struct Window *wind;
extern long XMatrix,YMatrix,BaseLine,HelpLine,Ascii,DMode;
extern long Quadrant,undoascii;
extern ULONG *cmatrix;
extern BYTE *drawmem;
extern ULONG cmemo[],scmemo[],undomem[];

/*------------------- Daten für Programmodus -----------------------*/
short pdat[][4]=
{
   { 10,16,88,28 }, { 105,16,167,28 },{ 184,16,254,28 },
   { 10,33,56,45 },{ 76,33,122,45 },{ 142,33,188,45 },{ 208,33,254,45 },
   { 10,50,56,62 },{ 76,50,122,62 },{ 142,50,164,62 },{ 172,50,194,62 },
   { 202,50,224,62 },{ 232,50,254,61 },
   { 30,67,50,77 },{ 30,87,50,97 },{ 10,77,30,87 },{ 50,77,70,87 },
   { 80,76,118,88 },{ 128,76,166,88 },
   { 176,76,254,88 },

};
char *ptxt[]=
{
   "START:","END:","STEP:"," INV"," ROT","MIR_H","MIR_B","EXP_X","EXP_Y",
   "Q1","Q2","Q3","Q4","UP","DOWN","LEFT","RIGHT","DELE"," GO","PZ:",
};
short parr[][7]=
{
   { 40,68,47,75,33,75,-2 },
   { 40,96,47,89,33,89,-2 },
   { 13,82,25,79,25,86,-2 },
   { 67,82,55,79,55,86,-2 },
};
char programm[100];

/*h3.1------------------------ Zeichen spiegeln -----------------------*/
void Mirror(mode)
BYTE mode;
{
register long i,j,*adr=cmatrix+100*Ascii,*point;
register long bitoff;

   switch(mode)
   {
      case 0:
         for(i=0;i<=YMatrix;i++,adr+=2)
         {
            for(j=0;j<=HelpLine;j++)
            {
               if(TestBit(adr,j))
                  SetBit(adr,2*HelpLine-j-1);
            }
         }
         break;
      case 1:
         bitoff=2*64*(BaseLine-1)+64;point=adr;
         for(i=0;i<=BaseLine;i++,adr+=2,bitoff-=64)
         {
            for(j=0;j<=XMatrix;j++)
            {
               if(TestBit(adr,j))
                  SetBit(point,bitoff+j);
            }
         }
         break;
   }
   Mem_to_Matrix();

}
/*h3.2-------------- Undospeicher in Hauptspeicher -----------------*/
void Undo()
{
register long i,*adr=cmatrix+100*Ascii;

   for(i=0;i<=99;i++,adr++)*adr=undomem[i];
   Ascii=undoascii;
   AsciiOut();
   Mem_to_Matrix();
}
/*h3.3---------------------- Zeichen drehen -------------------------*/
void Rotate()
{
register long *adr=cmatrix+100*Ascii,*point=scmemo;
register long i,j,bitoff;

   for(i=0;i<=99;i++,point++)*point=adr[i];
   point=scmemo;
   for(i=0;i<=XMatrix;i++,point+=2)
   {
      bitoff=(YMatrix-1)*64+i;
      for(j=0;j<=YMatrix;j++,bitoff-=64)
      {
         if(TestBit(point,j))
            SetBit(adr,bitoff);
         else ClrBit(adr,bitoff);
      }
   }
   Mem_to_Matrix();
}
/*h3.4---------------------- Zeichen invertieren -----------------------*/
void Revers()
{
register long i,j,*adr=cmatrix+100*Ascii,xend=XMatrix,yend=YMatrix;

   for(i=0;i<=(yend-1);i++,adr+=2)
   {
      for (j=0;j<=(xend-1);j++)
      {
         if(TestBit(adr,j))
            ClrBit(adr,j);
         else
            SetBit(adr,j);
      }
   }
   Mem_to_Matrix();
}
/*h3.5---------- Zeichen in x-Richtung vergrößern -------------------*/
void Expand_x()
{
register ULONG *adr=cmatrix+100*Ascii,*point=scmemo;
register long i,j;

   for(i=0;i<=99;i++,point++)*point=adr[i];
   point=scmemo;
   for(i=0;i<=YMatrix-2;i++,adr+=2,point+=2)
   {
      for(j=0;j<=XMatrix-1;j++)
      {
         if(TestBit(point,j))
         {
            SetBit(adr,j*2);SetBit(adr,j*2+1);
         }
         else
         {
            ClrBit(adr,j*2);ClrBit(adr,j*2+1);
         }
      }
   }
   Mem_to_Matrix();
}
/*h3.6------------- Zeichen in y-Richtung vergrößern --------------*/
void Expand_y()
{
ULONG *adr=cmatrix+100*Ascii,*point=scmemo;
register long i;

   for(i=0;i<=99;i++,point++)*point=adr[i];
   point=scmemo;
   for(i=0;i<=99;i+=4)
   {
      adr[i]=*point;adr[i+2]=*point;point++;
      adr[i+1]=*point;adr[i+3]=*point;point++;
   }
   Mem_to_Matrix();
}
/*h3.7--------------- Programmodus aktivieren ----------------------*/
void Programm()
{
static short start=32,end=255,step=1,count=0;
ULONG flags=WINDOWCLOSE|ACTIVATE|WINDOWDRAG;
ULONG iflags=CLOSEWINDOW|MOUSEBUTTONS;
struct Window *wn;
struct RastPort *rp;
ULONG class;
USHORT code;
short i,mox,moy,flag=0;
char htext[10];
void pz_out(),Go_Amiga();

   wn=Make_Window(170,140,278,105,"Programm",flags,iflags,0);
   if(wn==0)return();
   rp=wn->RPort;
   SetAPen(rp,1);RectFill(rp,0,11,278,105);
   Box(rp,2,12,275,103,0,JAM1);

   for (i=0;i<=19;i++)
   {
      SetAPen(rp,0);
      RectFill(rp,pdat[i][0],pdat[i][1],pdat[i][2],pdat[i][3]);
      Box(rp,pdat[i][0],pdat[i][1],pdat[i][2],pdat[i][3],2,JAM2);
      Box(rp,pdat[i][0]-1,pdat[i][1],pdat[i][2]+1,pdat[i][3],2,JAM2);
      if(i<13 || i>16)
        Text_out(rp,pdat[i][0]+3,pdat[i][1]+3,3,0,JAM2,ptxt[i],0);
      else
         FDrawPolygon(rp,parr[i-13],3,JAM1);
   }
   pz_out(rp,start,end,step);
   if(count==0)
      Text_out(rp,203,79,3,0,JAM2,"NULL",0);
   else
      Text_out(rp,203,79,3,0,JAM2,ptxt[programm[count-1]],0);

   FOREVER
   {
      while(ExaIntui(wn,&class,&code))
      {
         mox=wn->MouseX;moy=wn->MouseY;

         switch (class)
         {

            case CLOSEWINDOW:
               CloseWindow(wn);
               return();

            case MOUSEBUTTONS:
               if(code != SELECTDOWN) break;
               i=Prurec(mox,moy,pdat,0,19);
               if(i<0)break;
               if(i>2 && i<18)
               {
                  if(flag==0)count=0;
                  Invert(rp,pdat[i]);
                  Delay(5);
                  programm[count]=i;
                  programm[count+1]=0;
                  sprintf(htext,"%s    ",ptxt[i]);
                  Text_out(rp,203,79,3,0,JAM2,htext,5);
                  count++;
                  if(count>98)count--;
                  flag=1;
               }
               SetAPen(rp,1);
               switch (i)
               {
                  case 0:
                     start=(short)input_zahl(wn,61,19,3,"");
                     if(start<0 || start>255)start=32;
                     break;
                  case 1:
                     end=(short)input_zahl(wn,140,19,3,"");
                     if(end<start || end>255)end=255;
                     break;
                  case 2:
                     step=(short)input_zahl(wn,227,19,3,"");
                     if(step<1 || step>255)step=1;
                     break;
                  case 18:
                     Text_out(rp,pdat[i][0]+3,pdat[i][1]+3,1,0,JAM2,
                              "STOP",0);
                     Invert(rp,pdat[i]);
                     Go_Amiga(wn,start,end,step);
                     break;
                  case 19:
                     Text_out(rp,203,79,3,0,JAM2," NULL",0);
                     Invert(rp,pdat[i]);
                     count=0;programm[0]=0;
                     break;

               }
               if(i>2)Invert(rp,pdat[i]);
               Text_out(rp,pdat[18][0]+3,pdat[18][1]+3,3,0,JAM2,
                        " GO ",0);
               pz_out(rp,start,end,step);

         }
      }
   }
}
/*---- Unterfunktion zu h3.7 ----*/
void pz_out(rp,st,end,stp)
struct RastPort *rp;
short st,end,stp;
{
char htext[10];

   sprintf(htext,"%3.0f",(float)st);
   Text_out(rp,61,19,3,0,JAM2,htext,0);
   sprintf(htext,"%3.0f",(float)end);
   Text_out(rp,140,19,3,0,JAM2,htext,0);
   sprintf(htext,"%3.0f",(float)stp);
   Text_out(rp,227,19,3,0,JAM2,htext,0);
}
/*---- Unterfunktion zu h3.7 ----*/
void Go_Amiga(wn,st,end,stp)
struct Window *wn;
short st,end,stp;
{
short i,count;
long mer1=Ascii,mer2=Quadrant;
ULONG class;
USHORT code;

   for(i=st;i<=end;i+=stp)
   {
      Ascii=i;count=0;AsciiOut();
      ExaIntui(wn,&class,&code);
      if(class==MOUSEBUTTONS && code==SELECTDOWN)break;
      while (programm[count] != 0)
      {
         Invert(wn->RPort,pdat[programm[count]]);
         switch (programm[count])
         {
            case 3: Revers();break;
            case 4: Rotate();break;
            case 5: Mirror(0);break;
            case 6: Mirror(1);break;
            case 7: Expand_x();break;
            case 8: Expand_y();break;
            case 9: case 10: case 11: case 12:
               Quadrant=programm[count]-9;
               break;
            case 13: Scroll(2);break;
            case 14: Scroll(3);break;
            case 15: Scroll(0);break;
            case 16: Scroll(1);break;
            case 17: Delete(0);break;
         }
         Invert(wn->RPort,pdat[programm[count]]);
         count++;
      }
   }
   Ascii=mer1;Quadrant=mer2;
   Mem_to_Matrix();AsciiOut();
}
/*h3.8--------------- Gesamten Zeichensatz anzeigen --------------*/
void Show()
{
ULONG class;
USHORT code;
short Font_out(),ascii=0;

   Mabox(0);
   ascii=Font_out(ascii);
   FOREVER
   {
      while(ExaIntui(wind,&class,&code))
      {
         switch (code)
         {
            case MENUDOWN:
               if(ascii>=254)ascii=0;
               ascii=Font_out(ascii);
               break;

            case SELECTDOWN:
               Mem_to_Matrix();
               Mabox(1);
               return();
         }
      }
   }
}
/*----- Unterfunktion zu h3.8 -----*/
short Font_out(ascii)
short ascii;
{
register long xa=4,ya=13;

   SetAPen(rast,0);SetDrMd(rast,JAM1);
   RectFill(rast,1,11,511,210);

   while( ya<160 && ascii<254)
   {
      xa=4;
      while(xa<447 && ascii<254)
      {
         DrawLittle(0,xa-522,ya-15,cmatrix+100*ascii);
         Box(rast,xa-1,ya-1,xa+XMatrix+1,ya+YMatrix+1,2,JAM1);
         ascii++;
         xa+=XMatrix+2;
      }
      ya+=YMatrix+2;
   }
   return(ascii);
}
/*h3.9----------------- Speicher besorgen ---------------------*/
BYTE GetMemory(mode)
BYTE mode;
{
register BYTE *bpoi;
register short i,j;

   if(mode==0) goto cleanup1;

   oima=AllocMem(sizeof(struct Image),MEMF_CHIP|MEMF_CLEAR);
   if(oima==0)return(-1);
   drima=AllocMem(sizeof(struct Image),MEMF_CHIP|MEMF_CLEAR);
   if(drima==0)goto cleanup6;
   mima=AllocMem(sizeof(struct Image),MEMF_CHIP|MEMF_CLEAR);
   if(mima==0)goto cleanup5;
   f_info=AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
   if(f_info==0)goto cleanup4;

   cmatrix=AllocMem(102400,MEMF_CLEAR);
   if(cmatrix==0) goto cleanup3;

   drawmem=AllocRaster(512,400);
   if(drawmem==0) goto cleanup2;

   oima->LeftEdge=522;oima->TopEdge=15;oima->Width=64;oima->Height=50;
   oima->Depth=1;oima->ImageData=NULL;oima->PlanePick=1;
   oima->PlaneOnOff=0;oima->NextImage=NULL;

   drima->LeftEdge=0;drima->TopEdge=11;drima->Width=512;drima->Height=200;
   drima->Depth=2;drima->ImageData=NULL;drima->PlanePick=3;
   drima->PlaneOnOff=0;drima->NextImage=NULL;

   mima->LeftEdge=522;mima->TopEdge=71;mima->Width=64;mima->Height=50;
   mima->Depth=1;mima->ImageData=NULL;mima->PlanePick=1;
   mima->PlaneOnOff=0;mima->NextImage=NULL;

   bpoi=drawmem+12800;
   for (i=0;i<=199;i++)
   {
      for(j=0;j<=63;j++,bpoi++)
      {
         *bpoi=128;
         if(i%4 == 0)
            *bpoi=0xff;
      }
   }
   return(0);

cleanup1: FreeRaster(drawmem,512,400);
cleanup2: FreeMem(cmatrix,102400);
cleanup3: FreeMem(f_info,sizeof(struct FileInfoBlock));
cleanup4: FreeMem(mima,sizeof(struct Image));
cleanup5: FreeMem(drima,sizeof(struct Image));
cleanup6: FreeMem(oima,sizeof(struct Image));

   return(-1);
}
/*h3.11------ Sicherheitsabfragen un Meldungen ausgeben --------*/

char *shtxt[]=
{
   "Are you shure to quit ?",
   "I can't find this font !",
   "ERROR !! Font not saved.",
   "Not enough Memory !!!",
   "I can't find Diskfont Library",
   "No ASSIGN ! Please use CLI",
   "Loading Font !  Please Wait",
   "Loading Topaz/8 !  Please Wait",
   "Examine Font !!",
   "One Moment ! Writing Char Data !",
   "Creat New Fastdirectory !",
   "Writing xxxx.font !",
};

BYTE Shure(nr)
BYTE nr;
{
static flag=0;
static struct Window *swind;
ULONG flags=ACTIVATE|WINDOWDRAG;
ULONG class;
USHORT code;
char text[2][4];
short sh_data[2][4];
short wbr;
BYTE i;

   if(nr>=6 && flag==1)
   {
      flag=0;
      CloseWindow(swind);
      return(0);
   }
   wbr=strlen(shtxt[nr])*8+28;
   sh_data[0][0]=10;sh_data[0][1]=32;sh_data[0][2]=40;sh_data[0][3]=44;
   if(nr>0) sh_data[0][2]=32;
   sh_data[1][0]=wbr-44;sh_data[1][1]=32;
   sh_data[1][2]=wbr-22;sh_data[1][3]=44;
   if(nr<1)
   {
      strcpy(text[0],"YES");strcpy(text[1],"NO");
   }
   else
   {
      strcpy(text[0],"OK");strcpy(text[1],text[0]);
   }
   swind=Make_Window(0,0,wbr,51,"REQUEST",flags,MOUSEBUTTONS,0);
   if(swind==0)return(0);
   SetAPen(swind->RPort,1);RectFill(swind->RPort,0,11,wbr,51);
   Box(swind->RPort,2,12,wbr-3,49,0,JAM1);

   Text_out(swind->RPort,10,16,0,1,JAM2,shtxt[nr],0);
   if(nr<6)
   {
      for(i=0;i<=1;i++)
      {
         Box(swind->RPort,sh_data[i][0],sh_data[i][1],sh_data[i][2],
                       sh_data[i][3],2,JAM1);
         Text_out(swind->RPort,sh_data[i][0]+3,sh_data[i][1]+3,0,1,JAM2,
                  text[i],0);
      }
   }
   else
   {
      flag=1;
      return(0);
   }

   FOREVER
   {
      while(ExaIntui(swind,&class,&code))
      {
         if(code!=SELECTDOWN)break;
         i=Prurec(swind->MouseX,swind->MouseY,sh_data,0,1);
         if(i<0)break;
         CloseWindow(swind);
         return(i);
      }
   }
}
/*h3.12---------------------- Direktory sortieren ---------------------*/
void SortDir(names,anz)
BYTE *names;
short anz;
{
register short i,j=1;
BYTE *p1=names,*p2,*p3,h;

   p3=AllocMem(1024,MEMF_CLEAR);
   if(p3==0)return();
   p2=p3;
   for(i=0;i<=1023;i++,p1++)p2[i]=*p1;

   p1=names;
   for(i=1;i<=anz-1;i++)
   {
      h=*p2;p2++;
      if(h==1)
      {
         *p1=1;p1++;
         strcpy(p1,p2);
         p1+=strlen(p2)+1;
      }
      p2+=strlen(p2)+1;
   }
   p2=p3;
   for(i=1;i<=anz-1;i++)
   {
      h=*p2;p2++;
      if(h==0)
      {
         *p1=0;p1++;
         strcpy(p1,p2);
         p1+=strlen(p2)+1;
      }
      p2+=strlen(p2)+1;
   }
   FreeMem(p3,1024);
}
/*h3.13--------------- Zeichensatzdiskette aktualisieren ----------------*/
void Assign(drive)
char *drive;
{
struct FileLock *lockp,*Lock();
char text[100],*point,i;

   strcpy(text,drive);text[4]=0;
   if((lockp=Lock(text,ACCESS_READ))==0)
      return();
   if(Examine(lockp,f_info)==0)
      return();
   UnLock(lockp);

   /*-- Stern und Anführungszeichen im Filenamen bearbeiten --*/
   point=f_info->fib_FileName;
   strcpy(text,f_info->fib_FileName);
   for(i=0;i <= strlen(text);i++,point++)
   {
      *point=text[i];
      if(text[i]=='*' || text[i]=='"')
      {
         *point='*';point++;
         *point=text[i];
      }
   }
   /*-----------------------------------*/

   sprintf(text,"assign > nil: fonts: \"%s:%s\"",
           f_info->fib_FileName,drive+4);
   Execute(text,0,0);
}
/*-----------------------------------------------------------------------*/


