/*=========================================================================
 *           Envision: Font editor for Atari                              *
 ==========================================================================
 * File: dialogs.c                                                        *
 * Author: Mark Schmelzenbach                                             *
 * Started: 07/28/97                                                      *
 =========================================================================*/ 
#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
#include <grx20.h>

#ifdef __linux__
#include <vga.h>
#define BS 127
#else
#define BS 8
#endif

#include "envision.h"

/*=========================================================================*/
#ifndef __linux__
static char arrow[] = {
        0,1,0,0,0,0,0,0,0,0,0,0,
        1,2,1,0,0,0,0,0,0,0,0,0,
        1,2,2,1,0,0,0,0,0,0,0,0,
        1,2,2,2,1,0,0,0,0,0,0,0,
        1,2,2,2,2,1,0,0,0,0,0,0,
        1,2,2,2,2,2,1,0,0,0,0,0,
        1,2,2,2,2,2,2,1,0,0,0,0,
        1,2,2,2,2,2,2,2,1,0,0,0,
        1,2,2,2,2,2,2,2,2,1,0,0,
        1,2,2,2,2,2,2,2,2,2,1,0,
        1,2,2,2,2,2,2,2,2,2,2,1,
        1,2,2,2,2,1,1,1,1,1,1,0,
        1,2,2,2,1,0,0,0,0,0,0,0,
        1,2,2,1,0,0,0,0,0,0,0,0,
        1,2,1,0,0,0,0,0,0,0,0,0,
        0,1,0,0,0,0,0,0,0,0,0,0,
};

void FixMouse()
{
 GrCursor *newc;
 long cols[3];
 int i,xx,yy;
 int wrkw2=(12+7)&~7;
 int workw=wrkw2<<1;
 int workh=((12+7)&~7)<<1;
    
 cols[0]=0;
 cols[1]=1;
 cols[2]=14;
 newc=GrBuildCursor(arrow,32,32,32,1,1,cols);
 if(!newc) return;

 newc->xsize=12;
 newc->ysize=16;
 newc->xoffs=1;
 newc->yoffs=1; 
 newc->xwork = workw;
 newc->ywork = workh;

 GrSetContext(&newc->work);    
 GrFilledBoxNC(0,0,(12 + 12 - 1),(16 - 1),0L); 
 i=0;
 for(yy=0; yy<16; yy++) {
   for(xx=0; xx<12; xx++) {
      if (arrow[i]) {
        GrPlotNC(xx,yy,cols[arrow[i]]); 
      } else GrPlotNC(xx+wrkw2,yy,GrColorValue(-1L));
      i++;
   }
 }
 GrSetContext(NULL);
 GrMouseEraseCursor();
 GrMouseSetCursor(newc); 
 GrMouseDisplayCursor();
}
#endif
/*=========================================================================*/
int drawbutton(int x, int y, char *txt)
{
 int l,o,c;
 char *f,btxt[16];
 
 btxt[0]=c=0;
 f=strchr(txt,'*');
 if (!f) 
   strcpy(btxt,txt);
 else {
   if (f-txt) {
    strncpy(btxt,txt,f-txt);
    btxt[f-txt]=0;
   }
   strcat(btxt,f+1);
   c=*(f+1);
   o=(f-txt)*8;
 }
 l=32-strlen(btxt)*4;
 GrFilledBox(x+1,y+1,x+63,y+8,148); 
 GrLine(x,y,x+64,y,152);
 GrBox(x+64,y,x+64,y+9,152);  /* Broken GrLine in Linux? */
 GrLine(x,y+9,x+64,y+9,144);
 GrBox(x,y+1,x,y+9,144);      /* Broken GrLine in Linux? */
 string(x+l,y+1,btxt);
 if (c) {
  plotchr(x+l+o,y+1,c-32,1,dfont);
 }
}
/*=========================================================================*/
int string(int x, int y, char *str)
{
 int sx, c, i;

 if (!str) return;
 sx=x;
 for(i=0;i<strlen(str);i++) {
  c=*(str+i);
  if ((c<97)||(c>123)) c=c-32;
  if (c) plotchr(sx,y,c,2,dfont);
  sx+=8;
 }
}
/*=========================================================================*/
int raisedbox(int x, int y, int w, int h)
{
 w=w-x;
 h=h-y;
 GrFilledBox(x+1,y+1,x+w-1,y+h-1,148); 
 GrLine(x,y,x+w,y,152);
 GrBox(x+w,y,x+w,y+h,152);  /* Broken GrLine in Linux? */
 GrLine(x,y+h,x+w,y+h,144);
 GrBox(x,y+1,x,y+h,144);      /* Broken GrLine in Linux? */
}
/*=========================================================================*/
char stoa(char s)
{
 if ((s>=32)&&(s<=96)) s=s-32;
 return s;
}
/*=========================================================================*/
char *ginput(int xp, int yp, int slen, int len, char *init, int tp)
{
 /* tp 0=normal 1=num 2=filename */
 
 int cx, cc, dd, cp;
 char buffer[256];
 char c, *r;
 
 GrMouseEraseCursor();
 
 GrFilledBox(xp,yp,slen,yp+8,146);
 GrHLine(xp-1,slen+1,yp-1,144);
 GrHLine(xp-1,slen+1,yp+9,152);
 GrVLine(xp-1,yp,yp+8,144);
 GrVLine(slen+1,yp,yp+8,152);
 
 if (init) {
  string(xp+1,yp,init);
  cp=strlen(init);
  cx=xp+1+8*cp;
  strcpy(buffer,init);
 } else { 
  cx=xp+1;
  cp=0;
  *buffer=0;
 }
 
 cc=10; 
 dd=500;
 
 do {
  GrVLine(cx,yp,yp+7,cc);
  c=getch();
  
  if (!c) {
   getch();
  } else
  if ((c==BS)&&(cp)) {
    cp--;
    cx-=8;
    GrFilledBox(cx,yp,cx+9,yp+7,146);
    buffer[cp]=0;
    cc=10;
    dd=500;
  } else if ((cp<len)&&(cx+8<slen)&&((isalnum(c))||(c=='.')
              ||(c=='\\')||(c=='/'))) {
    if ((tp==1)&&(isalpha(c))) ;
    else if ((tp==2)&&((c=='/')||(c=='\\')||(cp==12)
              ||((c=='.')&&(strchr(buffer,'.'))))) ;
    else {
      if (tp==2) c=toupper(c);
      buffer[cp]=c;
      cp++;
      buffer[cp]=0;
      GrVLine(cx,yp,yp+7,146);
      plotchr(cx,yp,stoa(c),2,dfont);
      cx+=8;
      cc=10;
      dd=500;
    }
  }
 } while (c!=13);
  
 GrVLine(cx,yp,yp+7,146);
  
 if (*buffer) {
   r=(char *)malloc(strlen(buffer)+1);
   strcpy(r,buffer);
 } else r=NULL;
 return r;
}
/*=========================================================================*/
char *get_filename(char *title, char *image)
{
 char *r;
 
 GrBitBlt(dialog,0,0,NULL,79,64,243,91,GrWRITE);
 raisedbox(79,64,241,90);
 GrLine(79,91,241,91,0);
 GrLine(242,65,242,91,0);
 GrLine(243,66,243,91,0);
 string(83,68,title);
 if (image)
  r=ginput(83,78,237,24,NULL,2);  
 else
  r=ginput(83,78,237,24,NULL,0);  
 GrBitBlt(NULL,79,64,dialog,0,0,164,27,GrWRITE);
 return r;
}
/*=========================================================================*/
int error_dialog(char *error)
{
 GrBitBlt(dialog,0,0,NULL,79,64,243,91,GrWRITE);
 raisedbox(79,64,241,90);
 GrLine(79,91,241,91,0);
 GrLine(242,65,242,91,0);
 GrLine(243,66,243,91,0);
 string(83,68,error);
 drawbutton(129,78,"Okay");
 getch();
 GrBitBlt(NULL,79,64,dialog,0,0,164,27,GrWRITE);
}
/*=========================================================================*/
int do_options()
{
 int c,yp;
 char *names[]={"Basic","MAE","Mac/65","Action!"};
 char *hot="BM6A";
 char *oldname=NULL;
 
 GrMouseEraseCursor(); /* 144 */
 raisedbox(79,16,258,112);
 string(107,18,"Default Options");
 yp=30;
 string(82,yp,"Use disk image? ( / )");
 plotchr(218,yp,57,1,dfont);
 plotchr(234,yp,46,1,dfont);
 do { 
  c=toupper(getch()); 
 } while ((c!='Y')&&(c!='N')&&(c!=27));

 if (c=='Y') {
   GrFilledBox(210,yp,255,yp+8,148);
   string(206,yp,"Yes");
   yp+=10;
   oldname=options.disk_image;
   options.disk_image=ginput(99,yp,253,24,oldname,0);
   if (oldname)
     free(oldname);
   GrFilledBox(98,yp-1,254,yp+9,148);
   if (options.disk_image)
     string(99,yp,options.disk_image);
   else yp-=10;
 } else {
   if (options.disk_image)
     free(options.disk_image);
   options.disk_image=NULL;
 }
 if (!options.disk_image) {
  GrFilledBox(206,yp,255,36,148);
  string(206,yp,"No");
 }
 yp+=16;
 string(82,yp,"Select export format:");
 yp+=8;
 string(90,yp,".BAS .MAE .M65 .ACT");
 plotchr(98,yp,34,1,dfont);
 plotchr(138,yp,45,1,dfont);
 plotchr(186,yp,22,1,dfont);
 plotchr(218,yp,33,1,dfont);
 do {
  c=toupper(getch());
  oldname=strchr(hot,c);
 } while(!oldname);
 c=oldname-hot;
 yp-=8;
 GrFilledBox(82,yp,254,yp+16,148);
 string(82,yp,"Export format:");
 string(198,yp,names[c]);
 options.write_tp=c;
 if ((!c)||(c==2)) {
   yp+=10;
   string(90,yp,"Base:");
   do { oldname=ginput(135,yp,178,5,NULL,1); } while(!oldname);
   GrFilledBox(134,yp-1,179,yp+9,148);
   string(136,yp,oldname);
   options.base=atoi(oldname);
   free(oldname);
   yp+=10;
   string(90,yp,"Step:");
   do { oldname=ginput(135,yp,178,5,NULL,1); } while(!oldname);
   GrFilledBox(134,yp-1,179,yp+9,148);
   string(136,yp,oldname);
   options.step=atoi(oldname);
   free(oldname);
 } else {
   options.base=options.step=0;
 }
 drawbutton(136,94,"Okay");
 getch(); 
 GrFilledBox(79,16,258,112,0);
 string(192,104,"Char");
}
/*=========================================================================*/
int do_colors()
{
 int i,yp;
 char buf[16],*color;
 
 GrMouseEraseCursor(); 
 raisedbox(79,16,258,112);
 string(107,18,"Color Registers");
 yp=30;
 for(i=1;i<5;i++) {
   GrBox(90,yp,100,yp+8,0);
   GrFilledBox(91,yp+1,99,yp+7,clut[i]);
   sprintf(buf,"PF%d:",i);
   string(106,yp,buf);
   sprintf(buf,"%d",clut[i]);
   do { color=ginput(151,yp,178,5,buf,1); } while(!color);
   GrFilledBox(150,yp-1,179,yp+9,148);
   string(152,yp,color);
   clut[i]=(atoi(color)&254);
   GrFilledBox(91,yp+1,99,yp+7,clut[i]);   
   free(color);
   yp+=10;
 }
 drawbutton(136,94,"Okay");
 getch(); 
 GrFilledBox(79,16,258,112,0);
 string(192,104,"Char");
}
/*=========================================================================*/
int select_draw(char *title)
{
 int i,sx,sy,yp;
 GrMouseEvent evt;
 
 GrSetContext(back);
 raisedbox(0,32,272,120);
 string(9,36,title);
 yp=104;
 GrFilledBox(7,48,265,yp+8,146);
 GrHLine(6,266,47,144);
 GrHLine(6,266,yp+9,152);
 GrVLine(6,48,yp+8,144);
 GrVLine(266,48,yp+8,152);
 sx=0; sy=0;
 for(i=0;i<256;i++) {
   map_plotchr(8+sx,48+sy,i,1,dfont);
   sx+=8; 
   if (sx>248) { sx=0; sy+=8; }
 }
 GrSetContext(NULL);
 GrBitBlt(NULL,24,32,back,0,32,272,120,GrWRITE);
 
 yp=0;
 do {
  GrMouseGetEvent(GR_M_EVENT, &evt);
  if (evt.flags&GR_M_BUTTON_DOWN) {
    while (!(evt.flags&GR_M_BUTTON_UP)) 
      GrMouseGetEvent(GR_M_EVENT,&evt);
    if ((evt.x>=31)&&(evt.x<=289)&&(evt.y>=48)&&(evt.y<=112)) {
      sx=(evt.x-32)/8; sy=(evt.y-48)/8;
      i=sy*32+sx;
      yp=1;
    }
  }
  if (evt.flags&GR_M_KEYPRESS) {
    i=stoa(evt.key&255);
    yp=1;
  }
 } while (!yp);
 return i;
}
/*=========================================================================*/
int get_number(char *title, int def, int max)
{
 char *r, buf[8];
 int i;
 
 GrBitBlt(dialog,0,0,NULL,79,64,243,91,GrWRITE);
 raisedbox(79,64,241,90);
 GrLine(79,91,241,91,0);
 GrLine(242,65,242,91,0);
 GrLine(243,66,243,91,0);
 string(83,68,title);
 if (def>=0) 
   sprintf(buf,"%d",def);
 else *buf=0;
 do {
   r=ginput(83,78,237,24,buf,1);
   if (r) {
     i=atoi(r);
     free(r);
   } else i=-1;
 } while ((max>=0)&&(i>max));
 GrBitBlt(NULL,79,64,dialog,0,0,164,27,GrWRITE);
 return i;
}
/*=========================================================================*/
int do_size()
{
 int minx, miny, x, y, loop;
 char buf[16], *size;
 unsigned char *newmap,*look;
 
 GrBitBlt(dialog,0,0,NULL,79,64,243,91,GrWRITE);
 raisedbox(79,64,241,90);
 GrLine(79,91,241,91,0);
 GrLine(242,65,242,91,0);
 GrLine(243,66,243,91,0);
 string(83,68,"New Width:");
 miny=24;
 if (mode<6) minx=40;
   else minx=20;
 if (mode==7) miny=12;
 
 string(83,68,"New Width:");
 sprintf(buf,"%d",sx); 
 loop=1;
 do { 
  size=ginput(167,68,194,5,buf,1); 
  if (size) {
   x=atoi(size);
   if ((x>=minx)&&(x<=512)) 
     loop=0;
  } else loop=1;
 } while(loop);
 GrFilledBox(166,67,195,77,148);
 string(167,68,size); 
 string(83,78,"New Height:");
 sprintf(buf,"%d",sy); 
 loop=1;
 do { 
  size=ginput(175,78,202,5,buf,1); 
  if (size) {
   y=atoi(size);
   if ((y>=miny)&&(y<=512)) 
     loop=0;
  } else loop=1;
 } while(loop);
 GrBitBlt(NULL,79,64,dialog,0,0,164,27,GrWRITE);

 if ((sx==x)&&(sy==y))
  return 0;
 look=newmap=map;
 if (x<sx) {
  for(loop=0;loop<sy;loop++) {
    for(minx=0;minx<x;minx++)
      *look++=*newmap++;
    newmap+=sx-x;
  }
 } 
 newmap=(unsigned char *)realloc(map,x*y);
 if (newmap) {
   if (x>sx) {
     map=newmap;
     look=newmap+x*y-sx*sy;
     memmove(look,newmap,sx*sy);
     for(loop=0;loop<sy;loop++) 
       for(minx=0;minx<x;minx++)
         if (minx<sx) *map++=*look++;
           else *map++=0;
   } 
   if (x*y>sx*sy)
     memset(newmap+sx*sy,0,x*y-sx*sy);
   map=newmap;
   sx=x;
   sy=y;
 } else {
   error_dialog("Cannot allocate new map");
 }
 cx=cy=scx=scy=0;
 return 0;
}
