/*->c.vtfile */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"


#include "h.def"
#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.xext"

#include "h.file"

#include "h.vtdef"
#include "h.vtcol"
#include "h.vtlo"

#include "h.vtfile"



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

 Code to handle filing system interface for VT terminals

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



/*****************************************************************************/
                     /******* Spool Code ********/

int spoolflag=0;                        /* 1= we are spooling stuff */
int spconcode=1;                        /* 1= we are spooling concodes */
FILE * spfp=NULL;                       /* pointer to spool file */



void spoolclose(void)                 /* close spool file */
{
 fclose(spfp);
 spfp=NULL;
 spoolflag=0;
 vtwritespool();
}




int openspoolfile(char * filename,int type)  /* open spool file */
{
 FILE * fp;

 if(pendingramwrite()) return(0);

 createfile(filename,0,type);
 if((fp=fopen(filename,"wb"))==NULL) return(0);

 if(spfp!=NULL) spoolclose();

 spfp=fp;

 if(type==CEPT3 || type==CEPT2)
 {
  fputs("ACDemo\n",fp);
 }

 spoolflag=1;
 vtwritespool();
 return(1);
}



void myspool(int byte)  /* spool a byte */
{
 putc(byte,spfp);
 if(ferror(spfp))
 {
  spoolclose();
  errorbox("{VT05}");  /* Error on Spool file */
 }
}


void spooltoggle(void)                /* toggle spool state */
{
 if(spfp!=NULL) 
 {
  spoolflag^=1;
  vtwritespool();
 }
}


void spoolcont(void)                  /* toggle spool con codes */
{
 spconcode^=1;
}


void spoolon(void)
{
 if(spfp!=NULL)
 {
  spoolflag=1;
  vtwritespool();
 }
}


void spooloff(void)
{
 spoolflag=0;
 vtwritespool();
}





/* script interface */


int spoolopen(int fp)
{
 char * name=stringptr(stack[fp]);
 int    type=stack[fp+1];
 return(openspoolfile(name,type));
}


void ourspoolclose(int fp)
{
 fp=0;
 spoolclose();
}


void spool(int fp)
{
 if(stack[fp]) spoolon();
 else          spooloff();
}


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

static int seqp;
static char seqs[30];

void startseq(void)
{
 seqp=0;
 seqs[0]=0;
}

void flushseq(fp) FILE * fp;
{
 int i;
 if(seqp)
 {
  rputc(27,fp);
  rputc('[',fp);
  i=0;
  while(seqs[i]) rputc(seqs[i++],fp);
  rputc('m',fp);
 }
}


void addseq(i) int i;
{
 if(seqp) seqs[seqp++]=';';
 sprintf(seqs+seqp,"%d",i);
 seqp=strlen(seqs);
}


/* save chunk of capture buffer, return 1 on OK, 0 on error */

int savechunk2(int xlo,int ylo,int xhi,int yhi,FILE * fp)
{
 int     rstyle;
 int     rback;
 int     rfore;
 int     rrend;
 int     cstyle;
 int     cfore;
 int     cback;
 int     crend;
 int     byte;
 int     i;
 int     zero;
 int     x;
 int     y;
 int     lo;
 int     hi;

 tline * lp;
 int     loc;
 int   * data;
 int     atrf;


 if(spconcode)
 {
  startseq();
  addseq(0);
  flushseq(fp);
 }

 rrend=0;
 rfore=7;
 rback=0;

 for(y=ylo;y<=yhi;y++)
 {
  lp=vtindex(y);
  loc=lp->loc;
  data=(int *)(linedata+loc);
  atrf=lp->attr>0;

  if(y==ylo) lo=xlo; 
  else       lo=0;

  if(y==yhi) hi=xhi;
  else       hi=width-1;

  lo=(lo>>atrf);
  hi=(hi>>atrf);

  if(!spconcode)
  { 
   while(hi>=lo)
   {
    if((data[hi] & 0xFF)!=32) break;
    hi--;
   }
   if(lo<=hi)
    for(x=lo;x<=hi;x++) rputc(data[x] & 0xFF,fp);
  }
  else
  {
   /* save ansi stuff */
   /* 1 start of line, set double height etc. */
             
   if(atrf)
   { 
    rputc(27,fp);
    rputc('#',fp);
    rputc("X346"[lp->attr],fp);
   }

   for(x=lo;x<=hi;x++)
   {
    byte=data[x];
    cstyle=byte & 0xFF00;
    cback=(byte & 0xFF0000)>>16;
    cfore=(byte & 0xFF000000)>>24;
    cfore=cfore^cback;

    if(screenmode)
    {
     cback=logicalcolour(cfore);
     cfore=logicalcolour(cback);
    }
    else
    {
     cfore=logicalcolour(cfore);
     cback=logicalcolour(cback);
    }

    if(!ansisys)
    {
     if(cback==WHITE)
     {
      rstyle=cfore;
      cfore=cback;
      cback=rstyle;
      crend|=64;
     }
    }

    crend=0;
    if(cstyle & VTFLASH) crend|=0x10;
    if(cstyle & VTITAL)  crend|=0x4;
    if(cstyle & VTUNDER) crend|=0x8;
    if(cstyle & VTBOLD)  crend|=0x1;
    if(cstyle & VTFEINT) crend|=0x2;

    startseq();
    zero=0;
    rstyle=crend^rrend; /* diff bits set */
    if(rstyle)
    {
     if((rstyle & crend)!=rstyle)
     {
      zero=1;
      rstyle=crend;
      addseq(0);
     }
     for(i=0;i<8;i++) if(rstyle & (1<<i)) addseq(i+1);
    }

    if(ansisys)
    {
     if(cfore!=rfore || zero) addseq(30+cfore);
     if(cback!=rback || zero) addseq(40+cback);
    }

    flushseq(fp);

    rfore=cfore;
    rback=cback;
    rrend=crend;

    rputc(byte,fp);
   }
  }

  if(spconcode) rputc(CR,fp);
  rputc(LF,fp);
  if(rerror(fp)) break;
 }

 return(1);
}





int savechunk(int xlo,int ylo,int xhi,int yhi,char * filename)
{
 FILE *  fp;
 int     code;

 if((fp=ropen(filename,"wb"))==NULL) return(0);

 code=savechunk2(xlo,ylo,xhi,yhi,fp);

 savetypeclose(fp,filename);
 return(code);
}



/* save all the capture buffer */

int saveallbuffer(char * filename) 
{ 
 return(savechunk(0,0,width-1,buffsize-1,filename));
}



int vtsavescreen(char * name,int type)
{
 int code=0;
 int ccodes=spconcode;

 if(type==TEXT || type==RAWDATA)
 {
  ccodes=type==RAWDATA;
  code=savechunk(0,tops,width-1,tops+vtheight,name);
  spconcode=ccodes;
 }

 return(code);
}



