#include <stdio.h>
#include <auxcfg.h>
#include <spec.h>

#include <exec/types.h>             /* Laedt die Include-Files */
#include <exec/ports.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <graphics/display.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>

#include <mdllib.h>

#define BMHDChunk 1
#define CMAPChunk 2
#define BODYChunk 3
#define CAMGChunk 4
#define Unknown   5


#define TEKPIPENAME0 "ram:liserp0"
#define TEKPIPENAME1 "ram:liserp1"
#define TEKPIPENAME2 "ram:liserp2"
#define TEKPIPENAME3 "ram:liserp3"

#define TMPGCURSOR   "t:gcursor"
#define ASHBDRY      "t:ashbdry"

#define _TEKXMAX 1024
#define _TEKYMAX 780

extern struct WBStartup *WBenchMsg;
extern struct IconBase *IconBase;

int   cx,cy,cb1,cb2,
      esc,fdstdin,fdstdout,
      ink=2,
       opt=1,
       prt_passes=2,
       prt_lsbmsb=1,
       x_prt_siz=1024,
       y_prt_siz=1024,
       aposx=0,
       aposy=0,
       fdprinter=0,
       pribufptr=0,
       pribufsiz=8190,
      paper=0,
      ptr=0,
      bufsiz=200000,
      nohco=FALSE,
      msizex=3,
      msizey=3,
      sizex=3,
      sizey=3,
      thickx=1,
      thicky=1,
      txtangle=0,
      sinphi=0,
      cosphi=262144,
      gramode=0,
      flg_half=FALSE;

unsigned char tekname[80],
                prt_init[80]="\x1B@",
                prt_gra[80]="\x1BZ",
                prt_halflf[80]="\x1B\x33\x02\n",
                prt_lf[80]="\x1B\x33\x14\n",
                prt_fin[80]="\x1B@\x0C",
              *buf,
              *printerbuf,
              *tekbuf,
              vectorfont[256][40];

struct CMAPC          /* Definition des CMAP-Chunks               */
{
 int anz;             /* Anzahl der Farben                        */
 struct ColorRegister /* Definition einer Farbe                   */
 {
  UBYTE red;
  UBYTE green;
  UBYTE blue;
 } Color[64];         /* lieber zuviel als zuwenig                */
};

struct FORMC          /* Definition des Anfang-Chunks             */
{
 char  FORMName[4];   /* handelt es sich um ein IFF-Format?       */
 long  len;           /* Gesamte Laenge des Files                 */
 char  ILBM[4];       /* handelt es sich um ILBM-Format?          */
};

struct BMHDC          /* Definition des BMHD                      */
{
 char  BMHDName[4];
 long  lenBMHD;       /* Laenge des BMHD-Chunks                   */
 short Width;         /* Breite des Bildes                        */
 short Height;        /* Hoehe des Bildes                         */
 short xpos;          /* x-Position des Bildes                    */
 short ypos;          /* y-Position des Bildes                    */
 char  Depth;         /* Anzahl der BitPlanes                     */
 char  mask;          /* Mask-Bit                                 */
 char  compression;   /* Bild 'compressed'?                       */
 char  null;
 short color;
 char  xaspect;
 char  yaspect;
 short PWidth;
 short PHeight;
};

struct CHUNKID        /* hier werden die zu analysierenden Bytes  */
{                     /* abgelegt                                 */
 char  Name[4];       /* Name des Chunks                          */
 int   len;           /* Laenge des Chunks                        */
};

struct HEADER         /* diese Struktur enthaelt die Zeichenfolge */
{                     /* um den Chunk zu erkennen.                */
 char bmhd[4];
 char cmap[4];
 char body[4];
 char camg[4];
};

struct CAMGC          /* Definition des CAMG                      */
{
 char CAMGName[4];
 long lenCAMG;
 long ViewModes;
};

struct CMAPC CMAPl;
struct FORMC FORMl;
struct BMHDC BMHDl;
struct CHUNKID CHUNKid;
struct FORMC FORMs = {'F','O','R','M',0,'I','L','B','M'};
struct BMHDC BMHDs = {'B','M','H','D',20,0,0,0,0,0,2,0,0,0,10,11,0,0};
struct CAMGC CAMGs = {'C','A','M','G',4,0};
struct HEADER Header=
{
 'B','M','H','D',    /* BMHD-Chunk                                */
 'C','M','A','P',    /* CMAP-Chunk                                */
 'B','O','D','Y',    /* BODY-Chunk                                */
 'C','A','M','G',    /* CAMG-Chunk                                */
};

char cmap[]="CMAP";
char body[]="BODY";
char form[]="FORM";
char ilbm[]="ILBM";


/* ---------------------------------------------
         User Callback functions
   --------------------------------------------- */
float frline(stream)
FILE *stream;
{
int i,n;
char c,s[80];

   fgets(s,80,stream);
   return(atosf(s));
}

void Cursor()
{
int n,x,y,xx,yy,
      flg_tek=FALSE,
      flg_xy=TRUE,
      flg_xc=TRUE,
      flg_x=FALSE,
      flg_y=FALSE,
      leftmargin,
      bottommargin,
      rightmargin,
      topmargin,
      _win_flg;
float tmin,
      tmax,
      ymin,
      ymax,
      real_t,
      real_y,
      yfak,
      tfak,
      xoffset,
      yoffset;
char z[80],s[80];
FILE *fp;

getxy(&x,&y);

fp=fopen(ASHBDRY,"r");
leftmargin = frline(fp);
bottommargin = frline(fp);
rightmargin = frline(fp);
topmargin = frline(fp);
_win_flg = frline(fp);
tmin = frline(fp);
tmax = frline(fp);
ymin = frline(fp);
ymax = frline(fp);
_tica = frline(fp);
fclose(fp);

yfak=(topmargin-bottommargin)/(ymax-ymin);
tfak=(rightmargin-leftmargin)/(tmax-tmin);
xoffset= ((- tmin) * tfak) + leftmargin;
yoffset= ((- ymin) * yfak) + bottommargin;

real_t= (x - xoffset)/tfak;
real_y= (y - yoffset)/yfak;
xx= real_t / _tica;

sprintf(s,"tek x = %d  tek y = %d\ndata:      x=%f    y=%f\nx-channel = %d\n"
           ,x,y,real_t,real_y,xx);
Help(s);
}

void InkPlus()
{
char s[80];

ink = ((ink + 1) & 7);
SetAPen(rp,ink);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void InkMinus()
{
char s[80];

ink = ((ink - 1) & 7);
SetAPen(rp,ink);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void PaperPlus()
{
char s[80];

paper = ((paper + 1) & 7);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void PaperMinus()
{
char s[80];

paper = ((paper - 1) & 7);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

help()
{
printf("this program opens a graphic window and makes the rastport public\n");
printf("    -p n         specifies a number for the pipe.\n");
printf("    -buf n       change size of ßvector buffer(used for hardcopy)\n");
printf("    -nohco       display only, no buffer for hardcopy\n");
printf("    -paper n     specifies background colour\n");
printf("    -ink n       specifies drawing colour\n");
printf("    -left n      left edge\n");
printf("    -top n       top edge\n");
printf("    -xsize n     horizontal size\n");
printf("    -ysize n     vertical size\n");
}

posita(x,y)
int x,y;
{
int xx,yy;

   cx = x;
   cy = y;

   if(!nohco) {
     gfxbufin(0x1d);
     cvtxy(x,y);
   }

   xx=my_window->Width; xx=xx-1;
   yy=my_window->Height; yy=yy-32;
   xx=(xx*x)/1024;
   yy=16+((yy*(780-y))/780);
   Move(rp,xx,yy);
}

vectoa(x,y)
int x,y;
{
int xx,yy;

   cx = x;
   cy = y;

   if(!nohco) cvtxy(x,y);

   xx=my_window->Width; xx=xx-1;
   yy=my_window->Height; yy=yy-32;
   xx=(xx*x)/1024;
   yy=16+((yy*(780-y))/780);
   Draw(rp,xx,yy);
}

dperas()
{
int xx,yy,x,y,n;

   xx=my_window->Width;
   yy=my_window->Height;
   SetAPen(rp,paper);
   for(y=10;y<yy-2;y++) {
      Move(rp,2,y);
      Draw(rp,xx-3,y);
   }        
   SetAPen(rp,ink);
   ptr=0;
}

getxy(x,y)
int *x,*y;
{
   int xx,yy,n,i,fp;
   char s[8];

   set_new_pointer();

/* wait for mouse button */
   while((*((UBYTE*)0xbfe001))&64) Delay(10L);
   n=0;
   xx=my_window->Width;
   yy=my_window->Height;
   *x=my_window->MouseX;
   *y=my_window->MouseY;

   *x = (( *x * _TEKXMAX) / xx);
   *y = _TEKYMAX - (( *y * _TEKYMAX) / yy);

   set_old_pointer();
}

gfxtext(s)
char s[];
{
int n,i;
char c,z[256];

   c=s[0];
   if(c==0x1b) {   /* chage text size */
      c=s[1];
      switch(c) {
      case ';':                    /* smallest text size */
         sizex = (msizex *2) / 3;
         sizey = (msizey *2) / 3;
         break;
      case ':':                    /* small text size */
         sizex = (msizex * 3) / 4;
         sizey = (msizey * 3) / 4;
         break;
      case '9':
         sizex = msizex;            /* normal text size */
         sizey = msizey;
         break;
      case '8':
         sizex = 2*msizex;          /* big text size */
         sizey = 2*msizey;
         break;
      }
      n=0;
      while(c>0) {
         c=s[n+2];
         z[n++]=c;
      }
      plotstr(z);
   } else {
      plotstr(s);
   }
}

setcolour(n)
int n;
{
ink = n & 15;
paper = n / 16;
SetAPen(rp,ink);
}

rmtek()
{
   remove_tek();
   close_gfx(my_window);
   free(buf);
   exit(0);
}

textparam(sx,sy,tx,ty,w,name)
int sx,sy,tx,ty,w;
char name[];
{
if(sx>0) {sizex=sx; msizex=sx;}
if(sy>0) {sizey=sy; msizey=sy;}
if(tx>0) thickx=tx;
if(ty>0) thicky=ty;
if(name[0]!=0) readfont(name);
txtangle=w;
rotmat(w);
}

remove_tek()
{
int n;
   n=1;
   while(n>0) {
      unlink(tekname);
      n=open(tekname,0);
      if(n>0) close(tekname);
   }
}


cvtxy(x,y)
int x,y;
{
int n,m,i,h,l;
char ch,cl;

   h=y >> 5; l=y & 31;
   gfxbufin(h | 32); gfxbufin(l | 96);
   h=x >> 5; l=x & 31;
   gfxbufin(h | 32); gfxbufin(l | 64);
}


gettekxy(s,p,x,y)
char s[];
int *p,*x,*y;
{
int xx,yy,i,l,h,ptr;
char c;

   xx = -1 ; yy = -1;
   ptr = *p;
   while(1==1) {
      c=s[ptr++];
      i=(c & 0xe0);
      switch(i) {
      case 32:
         h = (c & 31);
         break;
      case 64:
         l = (c & 31);
         xx = h*32 + l;
         break;
      case 96:
         l = (c & 31);
         yy = h*32 + l;
      }
      if((xx>=0) & (yy>=0)) break;
   }
   *x = xx; *y = yy; *p = ptr;
}


gfxbufin(c)
char c;
{
if(ptr<bufsiz) buf[ptr++]=c;
}

/* *********************************************************************

                  Vector font utilities

   ********************************************************************* */

/* ------------------------------------------------------------------
      Read Vector font from file (as defined in Aux_Config)
   ------------------------------------------------------------------ */
readfont(name)
char *name;
{
int i,n,m;
char c,s[80];
FILE *fp;

   i=auxopen(name);
   close(i);
   strcpy(s,auxparams[0]);
   fp=fopen(s,"r");
   if(fp==NULL) {
      return(0);
   }

   while(!feof(fp)) {
      i=0;
      fscanf(fp,"%s",s);          /* read next entry , number of character */
      n = xtoi(s);
      if(n==0) continue;
      m=1;
      while(m>0) {
         fscanf(fp,"%s",s);       /* read next entry */
         m=xtoi(s);
         if(m>255) m = 255;        /* signal for new position */
         if(m<0) m = 255;          /* may be negative on some compilers */
         vectorfont[n][i++] = m;   /* store result */
      }
   }
   fclose(fp);
}

/* ------------------------------------------------------------------
      Rotation
   ------------------------------------------------------------------ */
rotate(xx,yy)
int *xx,*yy;
{
int rx,ry,x,y;

   x = *xx ; y = *yy;
   rx = ((x * cosphi) >> 19) - (( y * sinphi) >> 19);
   ry = (( y * cosphi) >> 19) + ((x * sinphi) >> 19);
   *xx = rx ; *yy = ry;
}
/* ------------------------------------------------------------------
      plot one single character
   ------------------------------------------------------------------ */
plotchar(c)
unsigned char c;
{
int n,m,i,x,y,mx,my,rx,ry,flag;
unsigned char uc;

   flag=TRUE;
   i=0; n=c;
   mx=cx; my=cy;

   x = 0; y = 4*sizey;
   rotate(&x,&y); posita(x+mx,y+my);

   for(;;) {
      uc = vectorfont[n][i++];
      if(uc == 255) {
         flag=FALSE;
         continue;
      }
      if(uc == 0) break;
      x = uc / 16;
      y = uc & 15;
      x = x * sizex; y = y * sizey;
      rotate(&x,&y);
      if(flag) {
         vectoa(x+mx,y+my);
      } else {
         posita(x+mx,y+my);
         flag = TRUE;
      }
   }
   x = 8 * sizex; y = 0; rotate(&x,&y);
   cx = mx + x;
   cy = my + y;
}

/* ------------------------------------------------------------------
      plot string
   ------------------------------------------------------------------ */
plotstr(s)
char s[];
{
int i,n,m,x,y,mx,my,tx,ty;
unsigned char c;

   cy = cy - 4;

   mx = cx ; my = cy;
   for(tx=0;tx<thickx;tx++) {
      for(ty=0;ty<thicky;ty++) {
         cx = mx + tx;
         cy = my + ty;
         i=0;
         while(1==1) {
            c = s[i++];
            if(c==0) break;
            plotchar(c);
         }
      }
   }
}

/* ----------------------------------------------------
       Calculate rotation matrix
   ---------------------------------------------------- */

rotmat(n)
int n;      /* Angle in degree */
{
int i,m;
float phi,cphi,sphi;

   phi = ((float) n) * 3.1415926 / 180.0;
   cphi = 262144 * cos( phi );
   sphi = 262144 * sin( phi );
   sinphi = (int) sphi;
   cosphi = (int) cphi;
}

xtoi(s)
char  s[];
{  int i,m,l,e;
   char c;

   l=strlen(s); e=0;
   for( i = 0 ; i < l ; i++ ) {
      c = s[i] ; c = toupper(c) ;
      m = c - '0' ;
      if( m > 9 ) m = m - 7 ;
      e = 16 * e + m ;
   } ;
   return(e) ;
}

/* ****************************************************************

                  HARDCOPY and related functions

   **************************************************************** */
void hco_()
{
hco("defaultprinter");
}

hco(str)
char str[];
{
unsigned char *bitplane;
char z[80];
int n,m,i,j;

   pribufsiz=8190;
   pribufptr=0;
   printerbuf=(unsigned char *)calloc(pribufsiz+2,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate printer buffer %d bytes\n",pribufsiz);
      return(0);
   }


   strcpy(z,"defaultprinter");
   if(str[0]!=0) strcpy(z,str);
   fdprinter=auxopen(z);
   n=4;
   prt_passes=atoi(auxparams[n]); n=n+1;
   prt_lsbmsb=atoi(auxparams[n]); n=n+1;
   x_prt_siz=atoi(auxparams[n]); n=n+1;
   y_prt_siz=atoi(auxparams[n]); n=n+1;
   cvtbs(prt_init,auxparams[n]); n=n+1;
   cvtbs(prt_gra,auxparams[n]); n=n+1;
   cvtbs(prt_halflf,auxparams[n]); n=n+1;
   cvtbs(prt_lf,auxparams[n]); n=n+1;
   cvtbs(prt_fin,auxparams[n]);


   n = (x_prt_siz * y_prt_siz) / 8;     /* length of buffer needed */
   n = n + 1024;                        /* to go shure */
   bitplane=(unsigned char *)calloc(n,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate shadow memory %d bytes\n",n);
      free(printerbuf);
      close(fdprinter);
      return(0);
   }
   redrawhco(bitplane);
   printout(bitplane);
   close(fdprinter);
   free(bitplane); free(printerbuf); 
}

strtoprt(s)
unsigned char s[];
{
int n;
unsigned char c;

   n=0;
   while(1==1) {
      c=s[n++];
      if(c==0) break;
      pribufin(c);
   }
}

pribufin(c)
unsigned char c;
{
if(pribufptr>=pribufsiz) pribufflush();
printerbuf[pribufptr++]=c;
}

pribufflush()
{
write(fdprinter,printerbuf,pribufptr); 
pribufptr=0;
}

redrawhco(bitplane)
unsigned char *bitplane;
{
int x,y,i,n,m,p;
char c,s[80];

   p=0;
   while(buf[p]!=0x1d) p=p+1;          /* find posita first */

   while(p<ptr) {                      /* scan vector buffer */

      c=buf[p];
      if(c==0x1d) {
         p=p+1;
         gettekxy(buf,&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(buf[p]!=0x1d) p=p+1;
            continue;
         }
         draw_to(bitplane,FALSE,x,y);
         continue;
      }
      if(c>31) {
         gettekxy(buf,&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(buf[p]!=0x1d) p=p+1;
            continue;
         }
         draw_to(bitplane,TRUE,x,y);
         continue;
      }
      while(buf[p]!=0x1d) p=p+1;          /* find next posita */
   }
}
      
/* --------------------------------------------------------------- */
/*       Draw a line                                               */
/* --------------------------------------------------------------- */
draw_to(bitplane,pen_down,x,y)
unsigned char *bitplane;
int pen_down,x,y;
{
   int   xinc,yinc,
         xcount,ycount,
         fx,fy;


   x = (x_prt_siz * x) / _TEKXMAX ;
   y = (y_prt_siz * y) / _TEKYMAX ; y=y_prt_siz-y;

   if(pen_down == TRUE) {
      xinc=liabs(x-aposx);
      yinc=liabs(y-aposy);
      fx=lisgn(x-aposx);
      fy=lisgn(y-aposy);
      xcount=xinc;
      ycount=yinc;
      do {
         set_pixel(bitplane,aposx,aposy);
         if(xcount>ycount) {
            ycount=ycount+yinc ; aposx=aposx+fx;
         } else {
            xcount=xcount+xinc ; aposy=aposy+fy;
         }
      } while((liabs(x-aposx)>=1) || (liabs(y-aposy)>=1));
   }
   aposx=x; aposy=y;
}

liabs(x)
int x;
{
   if(x>=0) return(x);
   return(-x);
}

lisgn(x)
int  x;
{
   if(x>0) return(1L);
   if(x<0) return(-1L);
   return(0L);
}

/* --------------------------------------------------------------- */
/*       plot one pixel                                            */
/* --------------------------------------------------------------- */
set_pixel(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   register int  byte,bit,n;



   byte=y*(x_prt_siz>>3)+(x>>3);
   bit= x & 7; n=128>>bit;
   bitplane[byte] |= n;
}

/* --------------------------------------------------------------- */
/*       get one pixel from shadow memory                          */
/* --------------------------------------------------------------- */
get_pixel(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   register int   byte,bit;
   register unsigned char c;

   byte=y*(x_prt_siz>>3)+(x>>3);
   bit=7-(x & 7);
   c=((bitplane[byte])>>bit) & 1;
   return(c);
}

/* ----------------------------------------------------------- */
/*       get one byte ready to print from shadow memory        */
/* ----------------------------------------------------------- */
get_prtbyte(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   int    i,m;
   long   n;

   m=0; n=0; x=x_prt_siz-x;
   for(i=1; i<=8; ++i) {
      n=n+prt_passes;
      m=2*m+get_pixel(bitplane,x-n,y);
   }
   return(m);
}

/* ----------------------------------------------------------- */
/*       make hardcopy of shadow memory                        */
/* ----------------------------------------------------------- */
printout(bitplane)
unsigned char *bitplane;
{
   int   m;
   long  x,y,n,i;
   unsigned char c;


   strtoprt(prt_init); pribufflush();

   if(prt_lsbmsb == 2) {              /* trap HP raster row graphics */
      hp_rasterrow(bitplane);
      return(0);

   }

   /* it follows the epson style printout routine */

   x=0;
   while(x<x_prt_siz) {
      y=0;
      for(i=1; i<=prt_passes; ++i) {
         prt_gra_out(y_prt_siz);
         while(y<y_prt_siz) {
            c=get_prtbyte(bitplane,x,y++);
            pribufin(c);
         }
         strtoprt(prt_halflf); 
         y=0; ++x;
      }
      strtoprt(prt_lf); pribufflush();
      x=x+7*prt_passes;
   }

   strtoprt(prt_fin); pribufflush();
}

/* -----------------------------
   HP mode raster row graphics 
   ----------------------------- */

hp_rasterrow(bitplane)
unsigned char *bitplane;
{
   int  x,y,m,n,i;
   unsigned char c;


   m = x_prt_siz / 8;
   n = (y_prt_siz -1) * m;
   x=0;
   while(x<n) {
      strtoprt(prt_gra);
      for(i=0; i<m; i++) {
	 c=bitplane[x++];
	 pribufin(c);
      }
      pribufflush();
   }
   strtoprt(prt_fin); pribufflush();
}

/* ------------------------------------------------------------ */
/* some printer dependend routines:                             */
/* ------------------------------------------------------------ */

prt_gra_out(x)
int  x;
{
unsigned char c1,c2;

   c1=x/256; c2=x-256*c1;
   strtoprt(prt_gra);
   if(prt_lsbmsb==1) {
      pribufin(c2);
      pribufin(c1);
   } else {
      pribufin(c1);
      pribufin(c2);
   }
}


/* convert string which includes the backslash */

cvtbs(s2,s1)
char s2[] , s1[];
{  int   i , l , i2 , i1 ;
   char  c , cc , s[8];

   l=strlen(s1); i2=0 ;
   for (i1 = 0; i1 <= l; i1++) {
      c=s1[i1];
      if(c == ' ') continue;
      if(c == '\\') {
         cc=s1[++i1];
         switch(cc) {
         case 'n':
            c='\n' ;  break ;
         case 'f':
            c='\f' ;  break ;
         case 't':
            c='\t' ;  break ;
         case 'b':
            c='\b' ;  break ;
         case 'x': /* hexadecimal conversion */
            s[0]=s1[++i1] ; s[1]=s1[++i1] ; s[2]=0 ;
            c=xtoi(s) ; break ;
         default:
            ; } ;
         } ;
      s2[i2++]=c ; }
   s2[i2]=0 ;
   return(i2-1);
}

teknewopen()
{
int   n,i,m,_tek4014;
char  c,s[80],z[80];

   strcpy(s,"gfx");
   c=_tekpipe+48;
   z[0]=c; z[1]=0;
   strcat(s,z);
   _tek4014=auxopen(s); /* _tekpipe is defined in spec.h */
   if(_tek4014 > 0) close(_tek4014);
   strcpy(tekname,auxparams[0]);
   _tek4014=creat(tekname,0777);
   if(_tek4014 <= 0) {
      fprintf(stderr,"failed to open graphic file\n");
/*      close_gfx(my_window); */
      exit(-1);
   }
      n = (int) *posita; write(_tek4014,&n,4);
      n = (int) *vectoa; write(_tek4014,&n,4);
      n = (int) *dperas; write(_tek4014,&n,4);
      n = (int) *gfxtext; write(_tek4014,&n,4);
      n = (int) *getxy; write(_tek4014,&n,4);
      n = (int) *setcolour; write(_tek4014,&n,4);
      n = (int) *rmtek; write(_tek4014,&n,4);
      n = (int) *textparam; write(_tek4014,&n,4);
      n = (int) *hco; write(_tek4014,&n,4);
   close(_tek4014);
}


/* ---------------------------------------------------------------

      Diverse Vektororientierte Ausgabe formate:

      HP-GL , DXF, TEX

   --------------------------------------------------------------- */

vector_out(output,x_faktor,y_faktor,move_to,draw_to)
 FILE *output;
 char move_to[], draw_to[];
 float x_faktor, y_faktor;
{
int x,y,i,n,m,p;
float fx,fy;
char c,s[80];

   p=0;
   while(buf[p]!=0x1d) p=p+1;          /* find posita first */

   while(p<ptr) {                      /* scan vector buffer */

      c=buf[p];
      if(c==0x1d) {
         p=p+1;
         gettekxy(buf,&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(buf[p]!=0x1d) p=p+1;
            continue;
         }
         fx = x_faktor * x;
         fy = y_faktor * y;
         fprintf(output,move_to,fx,fy);
         continue;
      }
      if(c>31) {
         gettekxy(buf,&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(buf[p]!=0x1d) p=p+1;
            continue;
         }
         fx = x_faktor * x;
         fy = y_faktor * y;
         fprintf(output,draw_to,fx,fy);
         continue;
      }
      while(buf[p]!=0x1d) p=p+1;          /* find next posita */
   }
   fclose(output);
}

save_hpgl()
{
char s[80];
FILE *output;

   FileSelect("Select HP-GL file",s);
   output = fopen(s,"w");
   fprintf(output,"IN;\nLT;\n1;\n");
   vector_out(output,(float)15,(float)15,
      "PU;PA %5.0f,%5.0f;\n",
      "PD;PA %5.0f,%5.0f;\n");
   fprintf(output,"PU;SP;IP;SC;PA 0,7650\n");
   fclose(output);
}

save_dxf()
{
char s[80];
FILE *output;

   FileSelect("Select HP-GL file",s);
   output = fopen(s,"w");
   vector_out(output,(float)15,(float)15,
      "PU;\nPA %5.0f %5.0f;\n",
      "PD;\nPA %5.0f %5.0f;\n");
   fclose(output);
}

save_tex()
{
char s[80];
FILE *output;

   FileSelect("Select HP-GL file",s);
   output = fopen(s,"w");
   vector_out(output,(float)15,(float)15,
      "PU;\nPA %5.0f %5.0f;\n",
      "PD;\nPA %5.0f %5.0f;\n");
   fclose(output);
}

/* --------------------------------------------------------------------
      IFF save routinen
   -------------------------------------------------------------------- */
save_iff()
{
unsigned char *bitplane;
char z[80];
int n,m;

   x_prt_siz = 1024;
   y_prt_siz = 1024;

   n = (x_prt_siz * y_prt_siz) / 8;     /* length of buffer needed */
   n = n + 1024;                        /* to go shure */
   bitplane=(unsigned char *)calloc(n,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate shadow memory %d bytes\n",n);
      return(0);
   }
   FileSelect("save as IFF to",z);
   redrawhco(bitplane);
   mem_iff(z,bitplane,x_prt_siz,y_prt_siz);
   free(bitplane);
}


mem_iff(name,ptr,width,height)
char name[];
unsigned char *ptr;
int width,height;
{
int output;
char s[80];
 static long i,j,k,anzcol,lenheader,lenfile,lencmap,lenbody;
 static WORD color;
 static BYTE ccount,*b1,*b2,*help;
 static BYTE r,g,b,*plane[6],null=0;
 static struct RastPort *MyRastPorth;
 static struct BitMap *MyBitMaph;
 static struct ViewPort *MyViewPorth;

   output = creat(name,0);

 /* Initialisierung des BMHD-Chunks */
 BMHDs.Height=height;
 BMHDs.Width=width;
 BMHDs.Depth=1;
 BMHDs.compression=0;
 BMHDs.PWidth=BMHDs.Width;
 BMHDs.PHeight=BMHDs.Height;
 if(BMHDs.Height>=400) BMHDs.yaspect *= 2;
 if(BMHDs.Width>=640) BMHDs.xaspect *= 2;
 CAMGs.ViewModes= HIRES | LACE;
 /* Anzahl der Farben? */
 j=BMHDs.Depth;
 if(j>5) j=5;  /* maximal 32 Farbregister abspeichern! */
 for(i=0,anzcol=1;i<j;anzcol *= 2,++i);
 lencmap = anzcol*3;
 lenbody=BMHDs.Width/8*BMHDs.Height*BMHDs.Depth;
 lenheader=sizeof(FORMs)-8+sizeof(BMHDs)+sizeof(CAMGs)+lencmap+8+8;
 lenfile=lenheader+lenbody;
 FORMs.len=lenfile;
 /* Speichern des FORM-Chunks */
   write(output,&FORMs,sizeof(FORMs));
 /* Speichern des BMHD-Chunks */
   write(output,&BMHDs,sizeof(BMHDs));
 /* Speichern des CAMG-Chunks */
   write(output,&CAMGs,sizeof(CAMGs));
 /* Speichern des CMAP-Chunks */
   write(output,&cmap,4);
   write(output,&lencmap,4);
   lencmap+=8;
   r = 0 ; g = 0; b = 0;
   write(output,&r,1); write(output,&g,1); write(output,&b,1);
   r = 255 ; g = 255; b = 255;
   write(output,&r,1); write(output,&g,1); write(output,&b,1);
 
 /* Speichern des BODY-Chunks */
   write(output,&body,4);
   write(output,&lenbody,4);
   write(output,ptr,(width * height) >> 3);
   
   close(output);                    /* File schliessen */
}


main(argc,argv)
int argc;
char *argv[];
{
int i,n,m;
char z[80];
FILE *stream, *tmp1;
char c,tempfile[80];
char mdlfile[80];
char s[80];
char **ToolArray, *Value;
struct DiskObject *Lock;
struct WBArg *Arg;
int wx = 500,
    wy = 400,
    wl = -1,
    wt = -1;

  if(checkopt(argc,argv,"-buf",z)) bufsiz=atoi(z);
  if(checkopt(argc,argv,"-nohco",z)) nohco=TRUE;
  if(checkopt(argc,argv,"-paper",z)) paper=atoi(z);
  if(checkopt(argc,argv,"-ink",z)) ink=atoi(z);
  if(checkopt(argc,argv,"-left",z)) wl=atoi(z);
  if(checkopt(argc,argv,"-top",z)) wt=atoi(z);
  if(checkopt(argc,argv,"-xsize",z)) wx = atoi(z);
  if(checkopt(argc,argv,"-ysize",z)) wy = atoi(z);

/* --- window geometry and name */
  my_new_window = init_window(wx,wy,"tek-Amiga",0,1);
  if(wl > 0)my_new_window->LeftEdge = wl;
  if(wt > 0)my_new_window->TopEdge = wt;

/* ----- initializing menus and requesters */

   add_item(-1,-1,NEW_MENU,"project",0,0); 
      fn_number++;
   add_item(-1,-1,MENU,"Hard Copy",0,0); 
      fn_command[fn_number] = (void *)hco_;
      fn_number++;
   add_item(-1,-1,MENU,"Save IFF",0,0); 
      fn_command[fn_number] = (void *)save_iff;
      fn_number++;
   add_item(-1,-1,MENU,"Save HP-GL",0,0); 
      fn_command[fn_number] = (void *)save_hpgl;
      fn_number++;
   add_item(-1,-1,MENU,"Save DXF",0,0); 
      fn_command[fn_number] = (void *)save_dxf;
      fn_number++;
   add_item(-1,-1,MENU,"Save TEX",0,0); 
      fn_command[fn_number] = (void *)save_tex;
      fn_number++;
   add_item(-1,-1,MENU,"Clear",0,0); 
      fn_command[fn_number] = (void *)dperas;
      fn_number++;
   add_item(-1,-1,MENU,"Cursor",0,0); 
      fn_command[fn_number] = (void *)Cursor;
      fn_number++;
   add_item(-1,-1,NEW_MENU,"colour",0,0); 
      fn_number++;
   add_item(-1,-1,MENU,"Ink +",0,0); 
      fn_command[fn_number] = (void *)InkPlus;
      fn_number++;
   add_item(-1,-1,MENU,"Ink -",0,0); 
      fn_command[fn_number] = (void *)InkMinus;
      fn_number++;
   add_item(-1,-1,MENU,"Paper +",0,0); 
      fn_command[fn_number] = (void *)PaperPlus;
      fn_number++;
   add_item(-1,-1,MENU,"Paper -",0,0); 
      fn_command[fn_number] = (void *)PaperMinus;
      fn_number++;

   teknewopen();
   readfont("font1");

  if(!nohco) buf = (unsigned char *)calloc(bufsiz+10,sizeof(char));

  my_window = (struct Window *) OpenWindow( my_new_window );
  SetMenuStrip( my_window, menu_bar );
  if(my_window == NULL)
  {
    CloseLibrary( IntuitionBase );
    exit();  
  }
  rp = my_window->RPort;
  SetDrMd(rp,JAM1);          /* Drawmode setzen */
  SetAPen(rp,2);             /* Farbregister zum Zeichnen setzen */

  fin_flg = FALSE;
  MainLoop(my_window);

  remove_tek();
  CloseLibrary(IntuitionBase);
  CloseLibrary(GfxBase);
  free(buf);
  exit(0);
}
