/*--(FontDesigner)--------- File h2.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 long XMatrix,YMatrix,BaseLine,HelpLine,Ascii,DMode;
extern long Quadrant;
extern struct TextFont *tftopaz,*tfuser;
extern struct Window *wind;
extern struct RastPort *rast;
extern ULONG *cmatrix,maske[],cmemo[],scmemo[];
extern UBYTE bmaske[],*drawmem;
extern struct Image *oima,*drima,*mima;

/*----------------------- Daten für Hauptdisplay ---------------------*/

short recdat[][4]=
{
   { 0,11,512,211 },
   { 456,216,505,228}, /* Change Ascii */
   { 456,228,505,239},
   { 456,239,505,250 },
   { 520,187,566,199 }, /*  4 */
   { 566,187,597,199 },
   { 597,187,628,199 },

   { 520,204,566,216 }, /*  7 */
   { 566,204,597,216 },
   { 597,204,628,216 },

   { 520,221,566,233 }, /* 10 */
   { 566,221,597,233 },
   { 597,221,628,233 },

   { 520,238,566,250 }, /* 13 */
   { 566,238,597,250 },
   { 597,238,628,250 },

   { 594,13,628,27 }, /* 16 */
   { 594,35,628,49 }, /* 17 */
   { 594,57,628,71 }, /* 18 */
   { 594,79,628,93 }, /* 19 */
   { 594,101,628,115 }, /* 20 */
   { 520,145,556,163 },  /* 21 */
   { 592,145,628,163 },
   { 556,127,592,145 },
   { 556,163,592,181 }, /* 24 */
   { 556,145,574,154 },
   { 574,145,592,154 },
   { 556,154,574,163 },
   { 574,154,592,163 }, /* 28 */
   { 10,216,64,228 },  /* MIRR_B */
   { 10,238,64,250 },  /* MIRR_H */
   { 79,216,133,228 }, /* ROTATE */
   { 302,216,356,228}, /* UNDO */
   { 79,238,133,250 }, /* INVERS */
   { 233,216,287,228 },      /* LOAD */
   { 148,216,218,228 },/* EXPAND_X */
   { 148,238,218,250 },/* EXPAND_Y */
   { 233,238,287,250},  /* SAVE */
   { 371,216,441,228 }, /* PRG */
   { 371,238,441,250 }, /* SHOW */
   { 302,238,356,250 }, /* MOVE */

};
char *rectxt[]=
{
   "","","","",
   "XM=","","","YM=","","","BL=","","","HL=","","",
   "ALL","MAT","DEL","SNP","CPY",
   "","","","",
   "","","","",
   "MIRR_H","MIRR_B","ROTATE","UNDO","INVERS","LOAD","EXPAND_X","EXPAND_Y",
   "SAVE","PROGRAMM","SHOW","MOVE",
};
char txtoff[][2]=
{
   {0,0},{11,3},{0,0},{0,0},
   {3,3},{0,0},{0,0},
   {3,3},{0,0},{0,0},
   {3,3},{0,0},{0,0},
   {3,3},{0,0},{0,0},
   {5,4},{5,4},{5,4},{5,4},{5,4},  /* 16-20 */
   {0,0},{0,0},{0,0},{0,0},        /* 21-24 */
   {0,0},{0,0},{0,0},{0,0},        /* 25-28 */
   {3,3},{3,3},{3,3},{11,3},
   {3,3},{11,3},{3,3},{3,3},
   {11,3},{3,3},{19,3},{11,3},
};

short pfeil[][7]=
{
   { 528,154,545,146,545,162,-2 },
   { 620,154,603,146,603,162,-2 },
   { 574,129,560,143,588,143,-2 },
   { 574,179,560,165,588,165,-2 },
   { 576,193,586,188,586,198,-2 },
   { 617,193,607,188,607,198,-2 },
   { 581,206,573,214,589,214,-2 },
   { 612,214,604,206,620,206,-2 },
   { 581,223,573,231,589,231,-2 },
   { 612,231,604,223,620,223,-2 },
   { 576,244,586,239,586,249,-2 },
   { 617,244,607,239,607,249,-2 },
   { 480,229,472,237,488,237,-2 },
   { 480,249,472,241,488,241,-2 },
};
char wtitle[]="F O N T  DESIGNER    Progammed by Richard Aretz";

/*h2.1------------------ Erzeugt das Hauptdisplay ---------------------*/

BYTE Display()
{
ULONG flags=WINDOWCLOSE|ACTIVATE|REPORTMOUSE|SMART_REFRESH|
            RMBTRAP|WINDOWDEPTH;
ULONG iflags=CLOSEWINDOW|MOUSEBUTTONS|VANILLAKEY;
short i;

   wind=Make_Window(0,0,636,256,wtitle,flags,iflags,0);
   if(wind==0) return(-1);
   rast=wind->RPort;
   SetAPen(rast,3);RectFill(rast,0,11,640,256);
   SetAPen(rast,0);
   RectFill(rast,0,11,512,211);
   RectFill(rast,521,14,587,65);
   RectFill(rast,521,70,587,121);
   for(i=21;i<=24;i++)
   {
      RectFill(rast,recdat[i][0]+4,recdat[i][1]+2,
                       recdat[i][2]+4,recdat[i][3]+2);
   }

   Box(rast,0,11,512,211,2,JAM1);

   for(i=1;i<=40;i++)
   {
      if ( !(i>20 && i<29) )
      {
         SetAPen(rast,0);
         RectFill(rast,recdat[i][0]+4,recdat[i][1]+2,
                       recdat[i][2]+4,recdat[i][3]+2);
      }
      SetAPen(rast,1);
      RectFill(rast,recdat[i][0],recdat[i][1],recdat[i][2],recdat[i][3]);
      Box(rast,recdat[i][0],recdat[i][1],recdat[i][2],recdat[i][3],2,JAM1);
      Text_out(rast,recdat[i][0]+txtoff[i][0],recdat[i][1]+txtoff[i][1],0,1,
               JAM2,rectxt[i],0);
   }
   for (i=0;i<=13;i++)
      FDrawPolygon(rast,pfeil[i],2,JAM1);

   AsciiOut();Matout();Mem_to_Matrix();
   Invert(rast,recdat[17-DMode]);
   Invert(rast,recdat[25+Quadrant]);
   return(0);
}
/*h2.2---------------- Aktuellen ascii-code ausgeben -----------------*/
void AsciiOut()
{
char text[5];

   sprintf(text,"%3.0f",(float)Ascii);
   Text_out(rast,recdat[1][0]+txtoff[1][0],recdat[1][1]+txtoff[1][1],
            0,1,JAM2,text,0);
}
/*h2.3------------------ Werte für Matrix ausgeben ------------------*/
void Matout()
{
char text[10],i;
long help;

   for(i=4;i<=13;i+=3)
   {
      switch(i)
      {
         case 4: help=XMatrix;break;
         case 7: help=YMatrix;break;
         case 10: help=BaseLine;break;
         case 13: help=HelpLine;break;
      }
      sprintf(text,"%s%2.0f",rectxt[i],(float)help);
      Text_out(rast,recdat[i][0]+txtoff[i][0],recdat[i][1]+txtoff[i][1],
               0,1,JAM2,text,0);
   }
}
/*h2.4--------------- Aktuellen Ascii-code verändern -------------------*/
void ChangeAscii(mode)
BYTE mode;
{
ULONG class;
USHORT code;
register short i;


   if(mode==0)
   {
      SetAPen(rast,0);
      Ascii=(long)input_zahl(wind,recdat[1][0]+txtoff[1][0],
                             recdat[1][1]+txtoff[1][1],3,"");
      if(Ascii<0 || Ascii>255)Ascii=65;
      AsciiOut();
      Mem_to_Matrix();
      return();
   }
   Invert(rast,recdat[mode+1]);
   Delay(10);
   FOREVER
   {
      switch (mode)
      {
         case 1:
            if(Ascii<255)Ascii++;
            else Ascii=0;
            break;

         case 2:
            if(Ascii>0)Ascii--;
            else Ascii=255;
            break;

      }
      AsciiOut();
      DrawLittle(0,0,0,cmatrix+100*Ascii);
      Delay(3);
      while(ExaIntui(wind,&class,&code))
      {
         switch(class)
         {
            case MOUSEBUTTONS:
               Mem_to_Matrix();
               Invert(rast,recdat[mode+1]);
               return();
         }
      }
   }
}
/*h2.5-------------------- Matrixdaten verändern -----------------------*/
void ChangeMatrix(var)
BYTE var;
{
ULONG class;
USHORT code;
long *point,pmax,mode=(var-1)%3;

   Mabox(0);
   switch (var)
   {
      case 4: case 5: case 6:
         point=&XMatrix;pmax=64;break;

      case 7: case 8: case 9:
         point=&YMatrix;pmax=50;break;

      case 10: case 11: case 12:
         point=&BaseLine;pmax=50;break;

      case 13: case 14: case 15:
         point=&HelpLine;pmax=64;break;
   }
   if(mode==0)
   {
      SetAPen(rast,0);
      *point=(long)input_zahl(wind,recdat[var][0]+26,recdat[var][1]+3,2,"");
      if(*point<1)*point=1;
      if(*point>pmax)*point=pmax;
      Matout();
      Mem_to_Matrix();
      return();
   }

   Invert(rast,recdat[var]);
   Delay(10);
   FOREVER
   {
      Mabox(0);
      switch (mode)
      {
         case 1:
            if(*point>0)*point-=1;
            else *point=pmax;
            break;
         case 2:
            if(*point<pmax)*point+=1;
            else *point=1;
      }
      Mabox(1);
      Matout();
      Delay(2);
      while (ExaIntui(wind,&class,&code))
      {
         switch (class)
         {
            case MOUSEBUTTONS:
               Invert(rast,recdat[var]);
               Mem_to_Matrix();
               return();
         }
      }
   }
}
/*h2.6------------------ Zeichnet die Matrixbox -----------------------*/
void Mabox(mode)
BYTE mode;
{
short xe=XMatrix*8,ye=11+YMatrix*4,yb=11+BaseLine*4,xh=HelpLine*8;

   Box(rast,0,11,xe,ye,mode+2,JAM1);
   Line(rast,0,yb,xe,yb,mode+2,JAM1);
   Line(rast,xh,11,xh,ye,mode+2,JAM1);
}
/*h2.7-------------Setzt einen Punkt in die Matrix -------------------*/
void SetMPoint(sp,ze,mode)
BYTE sp,ze,mode;
{
short xa=sp*8+1,ya=11+ze*4+1,spmax=63,zemax=49;
ULONG *adr=cmatrix+100*Ascii+2*ze;

   if(DMode==0) { spmax=XMatrix-1;zemax=YMatrix-1; }
   if(sp>spmax || sp<0)return();
   if(ze<0 || ze>zemax)return();

   SetAPen(rast,mode);SetDrMd(rast,JAM1);
   RectFill(rast,xa,ya,xa+6,ya+2);
   WritePixel(rast,522+sp,15+ze);

   if(sp>=32){ adr++;sp-=32; }
   if(mode==1)
      *adr|=maske[sp];
   else
      *adr&=~maske[sp];
}
/*h2.8------------- Haupfunktion in Matrix zeichnen --------------------*/
void DrawInto(mode)
BYTE mode;
{
ULONG class;
USHORT code;
short mox,moy;
ULONG iflags=wind->IDCMPFlags;
void SetMPoint();

   ModifyIDCMP(wind,wind->IDCMPFlags|=MOUSEMOVE);
   SetMPoint(wind->MouseX/8,(wind->MouseY-11)/4,mode);
   FOREVER
   {
      while (ExaIntui(wind,&class,&code))
      {
         switch (class)
         {
            case MOUSEBUTTONS:
              ModifyIDCMP(wind,iflags);
              return();

            case MOUSEMOVE:
               mox=wind->MouseX;moy=wind->MouseY;
               SetMPoint(mox/8,(moy-11)/4,mode);
         }
      }
   }
}
/*h2.9---------- Zeichen aus Zeichensatz in Zwischenspeicher -----------*/
void Font_to_Mem(ascii)
long ascii;
{
ULONG *adr=cmatrix+100*ascii;
UBYTE *fadr=tfuser->tf_CharData;
USHORT *loc=tfuser->tf_CharLoc;
register long hohe,breite,offset,bitoff;
register long i,j;
BYTE TestBit();
void SetBit(),AsciiOut();

   if(ascii<=tfuser->tf_HiChar && ascii>=tfuser->tf_LoChar)
   {
      for(i=0;i<=99;i++)adr[i]=0;
      offset=ascii-tfuser->tf_LoChar;
      if(offset<0)offset=0;

      hohe=tfuser->tf_YSize-1;
      bitoff=loc[offset*2];
      breite=loc[offset*2+1]-1;
      if(hohe<0 || hohe>51) hohe=8;
      if(breite<0 || breite>64)return();

      for(i=0;i<=hohe;i++)
      {
         for(j=0;j<=breite;j++)
         {
            if(TestBit(fadr,j+bitoff))
               SetBit(adr,j);
         }
         fadr+=tfuser->tf_Modulo;adr+=2;
      }
   }
   Ascii=ascii;
   AsciiOut();
}

/*h2.10------------------ Zeichen Manipulieren ---------------------------*/
void Delete(mode)
BYTE mode;
{
ULONG *adr=cmatrix+100*Ascii,*point=cmemo;
register long i,j;

   switch(mode)
   {
      case 0: /* CLR */
         switch(DMode)
         {
            case 0:
               for(i=0;i<=(YMatrix-1);i++,adr+=2)
               {
                  for(j=0;j<=(XMatrix-1);j++)
                  {
                     ClrBit(adr,j);
                  }
               }
            break;
            case 1:
               for(i=0;i<=99;i++)adr[i]=0;
         }
      break;

      case 1: /* Snapshot */
         switch(DMode)
         {
            case 0:
               for(i=0;i<=(YMatrix-1);i++,adr+=2,point+=2)
               {
                  for(j=0;j<=(XMatrix-1);j++)
                  {
                     if(TestBit(adr,j))
                        SetBit(point,j);
                     else
                        ClrBit(point,j);
                  }
               }
            break;
            case 1:
               for(i=0;i<=99;i++,point++)*point=adr[i];
            break;
         }
         DrawLittle(1,0,0,cmemo);
      break;

      case 2: /* Copy */
         switch(DMode)
         {
            case 0:
               for(i=0;i<=(YMatrix-1);i++,adr+=2,point+=2)
               {
                  for(j=0;j<=(XMatrix-1);j++)
                  {
                     if(TestBit(point,j))
                        SetBit(adr,j);
                     else
                        ClrBit(adr,j);
                  }
               }
            break;
            case 1:
               for(i=0;i<=99;i++,adr++)*adr=point[i];
            break;
         }
      break;
   }
   Mem_to_Matrix();
}
/*h2.11------------------- Scrolling ausführen -----------------------*/
void Scroll(mode)
BYTE mode;
{
ULONG *adr=cmatrix+100*Ascii,*point;
long i,j,bitoff;
BYTE astep,bstep,cstep;
long xstart,xend,ystart,yend;
ULONG class;
USHORT code;


   switch(Quadrant)
   {
      case 0:
         xstart=0;ystart=0;xend=HelpLine;yend=BaseLine;
         break;
      case 1:
         xstart=HelpLine;ystart=0;xend=XMatrix;yend=BaseLine;
         break;
      case 2:
         xstart=0;ystart=BaseLine;xend=HelpLine;yend=YMatrix;
         break;
      case 3:
         xstart=HelpLine;ystart=BaseLine;xend=XMatrix;yend=YMatrix;
         break;
   }

   switch (mode)
   {
      case 0:
         astep=1;bstep=0;cstep=0;
         break;
      case 1:
         astep=-1;bstep=0;cstep=0;
         break;
      case 2:
         astep=0;bstep=0;cstep=64;yend--;
         break;
      case 3:
         astep=0;bstep=64;cstep=0;yend--;
         break;
   }


   /*--- Scroll left & right up & down ---*/

      adr=cmatrix+100*Ascii;
      for(i=0;i<=99;i++,adr++)scmemo[i]=*adr;
      adr=cmatrix+100*Ascii+2*ystart;
      point=scmemo+2*ystart;
      for(i=ystart;i<=(yend-1);i++)
      {

         for(j=xstart;j<=(xend-1);j++)
         {
            if(TestBit(point,j+astep+cstep))
               SetBit(adr,j+bstep);
            else ClrBit(adr,j+bstep);
         }
         switch (mode)
         {
            case 0: ClrBit(adr,xend);break;
            case 1: ClrBit(adr,xstart);break;
         }
         adr+=2;point+=2;
      }
      switch (mode)
      {
         case 2:
            adr=cmatrix+100*Ascii+2*yend;
            for(i=xstart;i<=(xend-1);i++)
               ClrBit(adr,i);
            break;
         case 3:
            adr=cmatrix+100*Ascii+2*ystart;
            for(i=xstart;i<=(xend-1);i++)
               ClrBit(adr,i);
      }
      Mem_to_Matrix();
}
/*h2.12---------- Zeichen aus Zwischenspeicher in Matrix ------------*/
void Mem_to_Matrix()
{
register long *adr;
register long i,j;
register UBYTE *point=drawmem;

   adr=cmatrix+100*Ascii;
   BltClear(drawmem,12800,1);
   for(i=0;i<=49;i++,point+=256)
   {
      for(j=0;j<=31;j++)
      {
         if(*adr & maske[j])
         {
            *(point+64+j)=127;
            *(point+128+j)=127;
            *(point+192+j)=127;
         }
      }
      adr++;
      for(j=32;j<=63;j++)
      {
         if(*adr & maske[j-32])
         {
            *(point+64+j)=127;
            *(point+128+j)=127;
            *(point+192+j)=127;
         }
      }
      adr++;
   }

   point=drawmem;
   drima->ImageData=point;
   DrawImage(rast,drima,0,0);
   DrawLittle(0,0,0,cmatrix+100*Ascii);
   Mabox(1);
}
/*------------------------------------------------------------------------*/
