/* subroutines to make pattern play program work */

#include "stdio.h"
#include "fcntl.h"

extern struct Screen *sC;
extern struct Window *wG;
extern struct RastPort *rpG;
extern int mousex, mousey;

static char    def_name[50] = "";
static char    def_dir[50] = "";

struct patdata
{
unsigned int ourpattern[32], power_of_2, pen1color, pen2color;
} it;

extern struct Gadget Pen1;
DoPen1()
{
   it.pen1color= (mousex-Pen1.LeftEdge)/(Pen1.Width/4)+4*((mousey-
       Pen1.TopEdge)>Pen1.Height/2);
   fillsamples();
}

extern struct Gadget Pen2;
DoPen2()
{
   it.pen2color= (mousex-Pen2.LeftEdge)/(Pen2.Width/4)+4*((mousey-
       Pen2.TopEdge)>Pen2.Height/2);
   fillsamples();
}

extern struct Gadget Pen1Sample, Pen2Sample, Bigsample;

fillsamples()
{
   SetAPen(rpG, (long)it.pen1color);
   
   SetAfPt(rpG, 0l, 0l);
   SetDrMd(rpG, JAM1);
   RectFill(rpG, (long)Pen1Sample.LeftEdge, (long)Pen1Sample.TopEdge,
       (long)(Pen1Sample.LeftEdge+Pen1Sample.Width),
       (long)(Pen1Sample.TopEdge+Pen1Sample.Height));

   SetAPen(rpG, (long)it.pen2color);
   RectFill(rpG, (long)Pen2Sample.LeftEdge, (long)Pen2Sample.TopEdge,
       (long)(Pen2Sample.LeftEdge+Pen2Sample.Width),
       (long)(Pen2Sample.TopEdge+Pen2Sample.Height));

   SetAPen(rpG, (long)it.pen1color);
   SetBPen(rpG, (long)it.pen2color);
   SetDrMd(rpG, JAM1|JAM2);
   SetAfPt(rpG, it.ourpattern, (long)it.power_of_2);
   RectFill(rpG, (long)Bigsample.LeftEdge, (long)Bigsample.TopEdge,
       (long)(Bigsample.LeftEdge+Bigsample.Width),
       (long)(Bigsample.TopEdge+Bigsample.Height-1));

   RefreshGadgets(&Pen1Sample, wG, 0l);
}

extern struct Gadget Grid;
DoGrid()
{
int bit, word, mask;

   bit = (mousex-Grid.LeftEdge)/(Grid.Width/16);
   mask=0x8000>>bit;
   word= (mousey-Grid.TopEdge)/(Grid.Height/32);
   
   if (word>=(1<<it.power_of_2))
   {   DisplayBeep(0l);
       return;
   }
   
   it.ourpattern[word]^=mask;
   
   drawbit(bit, word, it.ourpattern[word]&mask);
   
   fillsamples();
}

drawbit(bit, word, flag)
int bit, word, flag;
{

   SetAPen(rpG, flag? 0l: 1l);
   SetAfPt(rpG, 0l, 0l);
   SetDrMd(rpG, JAM1);
   RectFill(rpG, (long)(Grid.LeftEdge+4*bit), (long)(Grid.TopEdge+4*word),
               (long)(Grid.LeftEdge+4*bit+2), (long)(Grid.TopEdge+4*word+2));
}

extern struct PropInfo SizerSInfo;
SetSize()
{
unsigned int x, y, size, mask;

   x=SizerSInfo.VertPot>>11;
   for(size=1, it.power_of_2=0; x; x=x>>1, size*=2, ++it.power_of_2);
   
   SetAPen(rpG, 3l);
   SetAfPt(rpG, 0l, 0l);
   SetDrMd(rpG, JAM1);
   RectFill(rpG, (long)(Grid.LeftEdge), (long)(Grid.TopEdge),
               (long)(Grid.LeftEdge+Grid.Width-1),
               (long)(Grid.TopEdge+Grid.Height-1));

   for (x=0, mask=0x8000; x<16; ++x, mask=mask>>1)
   {   for (y=0; y<size; ++y)
           drawbit(x, y, mask&it.ourpattern[y]);
   }
   
   fillsamples();
}

Clearit()
{
int i;
   for (i=0; i<32; ++i) it.ourpattern[i]=0;
   SetSize();
}

char *index();

call_get_fname(filename, greet)
char filename[], *greet;
{
char *p;
int t;

   if (get_fname(wG,sC,greet,def_name,def_dir))
   {
       if ((p=index(def_name, '.'))) *p=0;

       if (def_dir[0])
       {   strcpy(filename, def_dir);
           if ((t=filename[strlen(filename)-1]!=':') && t!='/')
                           strcat(filename, "/");
       }
       else filename[0]=0;
       strcat(filename,def_name);
       strcat(filename,".pat");
       
       return 1;
   }
   return 0;
}

Loadit()
{
char filename[70];
int fileno;

   if (call_get_fname(filename, "Load"))
   {
       
       if ((fileno=open(filename, O_RDONLY))==-1)
       {
badexit:   if (fileno!=-1) close(fileno);
           DisplayBeep(sC);
           return -1;
       }
       if (read(fileno, &it, sizeof(struct patdata))==0) goto badexit;
       close(fileno);
   
       SizerSInfo.VertPot=((1<<it.power_of_2)-1)<<11;
   }
   SetSize();
}


Saveit()
{
char filename[70], *p;
int fileno, t;
FILE *file;

   if (call_get_fname(filename, "Save"))
   {

       if ((fileno=open(filename, O_RDWR|O_CREAT))==-1)
       {
badexit:   if (fileno!=-1) close(fileno);
           DisplayBeep(sC);
           return -1;
       }
       if (write(fileno, &it, sizeof(struct patdata))==-1) goto badexit;
       close(fileno);

       p=index(filename,'.'); *p=0;
       strcat(filename,".h");
       if (!(file=fopen(filename, "w"))) goto badexit;
   
       fprintf(file, "char %s[]=\n{   ", def_name);
       for (t=0; t<((1<<it.power_of_2)-1); ++t)
           fprintf(file, "0x%04.4x,\n    ", it.ourpattern[t]);
       fprintf(file, "0x%04.4x\n};\n", it.ourpattern[t]);
   
       fprintf(file, "#define %s_size %dl\n", def_name, it.power_of_2);
   
       fclose(file);
   }
   SetSize();
}

init()
{
int swatchwidth, swatchheight, x;

   swatchwidth=Pen1.Width/4; swatchheight=Pen1.Height/2;
   SetAfPt(rpG, 0l,0l);
   SetDrMd(rpG, JAM1);
   for (x=0; x<4; ++x)
   {   SetAPen(rpG, (long)x);
       RectFill(rpG, (long)(Pen1.LeftEdge+x*swatchwidth), (long)Pen1.TopEdge,
        (long)(Pen1.LeftEdge+(x+1)*swatchwidth-1),
        (long)(Pen1.TopEdge+swatchheight-1));
       RectFill(rpG, (long)(Pen2.LeftEdge+x*swatchwidth), (long)Pen2.TopEdge,
        (long)(Pen2.LeftEdge+(x+1)*swatchwidth-1),
        (long)(Pen2.TopEdge+swatchheight-1));
       SetAPen(rpG, (long)(x+4));
       RectFill(rpG, (long)(Pen1.LeftEdge+x*swatchwidth),
        (long)(Pen1.TopEdge+swatchheight),
        (long)(Pen1.LeftEdge+(x+1)*swatchwidth-1),
        (long)(Pen1.TopEdge+Pen1.Height-1));
       RectFill(rpG, (long)(Pen2.LeftEdge+x*swatchwidth),
        (long)(Pen2.TopEdge+swatchheight),
        (long)(Pen2.LeftEdge+(x+1)*swatchwidth-1),
        (long)(Pen2.TopEdge+Pen2.Height-1));
   }

   SizerSInfo.VertPot=0x7fff;
   SetSize();
}

extern struct Requester RequesterStructure2;

tellit()
{
   Request(&RequesterStructure2, wG);
}

