/*->c.script */


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


#include "h.os"
#include "h.wimp"
#include "h.sprite"
#include "h.werr"
#include "h.wimpt"
#include "h.bbc"
#include "h.akbd"

#include "h.Drawlevel0"

#include "h.wos"
#include "h.ram"


#include "h.def"
#include "h.main"
#include "h.file"
#include "h.timex"
#include "h.strdef"

#include "h.xext"
#include "h.pr"
#include "h.dir"
#include "h.batch"
#include "h.view"
#include "h.mym"
#include "h.serial"  
#include "h.config"
#include "h.state"
#include "h.key"
#include "h.rxfax"
#include "h.txfax"
#include "h.sched"
#include "h.log"

#include "h.script"




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

char * unquotec(char * input,char * output)
{
 char * r;
 char * w;

 r=input;
 w=output;

 while(*r)
 {
  if(*r=='\"' || *r=='\\') *w++='\\';
  *w++=*r++;
 }

 *w=0;

 return(output);
}



int setvar(int index,int * var)
{
 int val=stack[index];
 int change;

 if(val==0 || val>0)
 {
  val=val!=0;
  change=(*var!=val);
  *var=val;
 }
 else change=0;

 return(change);
}


int scriptpoll=1;

void setpoll(int fp)
{
 scriptpoll=stack[fp];
}


void setbatch(int fp)
{
 int xdisplay=stack[fp];
 int xsort=stack[fp+1];
 if(xdisplay>=0 && xdisplay<3) display=xdisplay;
 if(xsort>=0 && xsort<4) sort=xsort;
}


void setbatchconfig(int fp)
{
 setvar(fp,&autoremove);
 setvar(fp+1,&batdiscard);
 setvar(fp+2,&batpopup);
 setvar(fp+3,&txbatpopup);
 setvar(fp+4,&unsentwarn);
 setvar(fp+5,&newfaxpopup);
}


void setbatchconfig2(int fp)
{
 setvar(fp+0,&batforward);
 strcpy(batforwardname,stringptr(stack[fp+1]));
}


void setautoredial(int fp)
{
 attempts=stack[fp+0];
 ardelay=stack[fp+1]*100;
}


void setcomms(int fp)
{
 setvar(fp+0,&prefix);
}


/* void sprints(string & s);   // send string to port */

void sprints(int fp)
{
 convertstringline(stringptr(stack[fp]));
}


/* void sprinti(int i);                // print int to port */

void sprinti(int fp)
{
 char string[32];
 sprintf(string,"%d",stack[fp]);
 convertstringline(string);
}



/* void pause(int timeout);            // wait, but keep on polling */

void pause(int fp)
{
 int time=clock()+stack[fp];

 do
 {
  if(scriptstop()) break;
  if(scriptpoll) poll(FORCEZERO);
 } while(time>clock());
}



/* int  sreads(string & s,int timeout,int max); */
/*
// try to read string (max chars) from port
// return 1 if string was terminated with
// CR/LF
*/


int sreads(int fp)
{
 int  timeout=stack[fp+1]+clock();
 char temp[128];
 int  s=stack[fp];
 int  max=stack[fp+2];
 int  first;
 int  code=0;
 int  totlen=1;
 int  index=0;
 int  byte;

 first=1;


 while(clock()<timeout)
 {
  if((byte=getbyte())==-1)
  {
   if(scriptstop()) break;
   if(scriptpoll) pollzt();
  }
  else
  {     /* we got a byte */
   temp[index++]=byte;
   temp[index]=0;
   totlen++;


   if(index==127 || byte==CR || byte==LF || totlen>=max)
   {
    if(first)
    {
     assignstring(s,temp);
     first=0;
    }
    else
     appendstring(s,temp);

    index=0;

    if(byte==CR || byte==LF || totlen>=max) 
    {
     code=1;
     break;
    }
   }
  }
 }
 return(code);
}



/* int  sreadtext(string & s,int timeout,int max); */
/*
// try to read string (max chars) from port
// return 1 if string was terminated with
// CR/LF
// no ctrl codes are passed on, string terminates with 0
*/


int sreadtext(int fp)
{
 int  timeout=stack[fp+1]+clock();
 char temp[128];
 int  s=stack[fp];
 int  max=stack[fp+2];
 int  first;
 int  code=0;
 int  totlen=1;
 int  index=0;
 int  byte;
 int  dle;

 first=1;
 dle=0;

 while(clock()<timeout)
 {
  if((byte=getbyte())==-1)
  {
   if(scriptstop()) break;
   if(scriptpoll) pollzt();
  }
  else
  {     /* we got a byte */
   if(dle)
   {
    dle=0;
   }
   else
   {
    if(byte==DLE)
    {
     dle=1;
    }
    else
    {
     if(byte>=SPC)
     {
      temp[index++]=byte;
      temp[index]=0;
      totlen++;
     }

     if(index==127 || totlen>=max || (index && (byte==CR || byte==LF)))
     {
      if(first)
      {
       assignstring(s,temp);
       first=0;
      }
      else
       appendstring(s,temp);

      index=0;

      if(byte==CR || byte==LF || totlen>=max) 
      {
       code=1;
       break;
      }
     }
    }
   }
  }
 }

 return(code);
}



/* return 0 OK, 1 fail, take timeout cs parameter and string */
/* int getframe(string & s,int timeout);                     */


int sgetframe(int fp)
{
 int    timeout;
 char   temp[128];
 int    escape;
 int    c;
 int    start;
 int    i;
 int    s;

 timeout=stack[fp+1]+clock();
 s=stack[fp];

 i=0;
 start=0;
 escape=0;

 while(clock()<timeout)
 {
  if((c=getbyte())==-1)
  {
   if(scriptstop()) break;
   if(scriptpoll) pollzt();
  }
  else
  {
   if(c==0xFF) start=1;

   if(escape)
   {
    if(c==0x10) 
    {
     if(start) temp[i++]=c;
    }
    else
    if(c==0x3)
    {
     temp[i]=0;
     assignstringlen(s,temp,i);
     return(i==0);
    }
    escape=0;
   }
   else
   if(c==0x10) escape=1;
   else
   if(start) temp[i++]=c;
  }
 }
 return(1);
}



/* int ssendframe(string & s) */

int ssendframe(int fp)
{
 int    len;
 int    s;
 char * p;
 int    i;
 int    c;

 s=stack[fp];

 p=stringptr(s);
 len=stringlen(s);
 for(i=0;i<len;i++)
 {
  c=p[i];
  if(c==0x10) outbyte(0x10);
  outbyte(c);
 }
 outbyte(0x10);
 outbyte(0x3);

 return(0);
}


int sgetsid(int fp)
{
 int    len;
 int    s;
 char * p;
 int    i;
 char   buffer[32];
 int    txrx;
 int    checkid;
 int    code;

 s=stack[fp];
 txrx=stack[fp+1];
 checkid=stack[fp+2];

 p=stringptr(s);
 len=stringlen(s);

 i=0;
 while(i<20)
 {
  buffer[19-i]=p[i+3];
  i++;
 }
 buffer[20]=0;

 code=1;

 if(txrx)
 {
  xfaxrxid(buffer);
  if(checkid) code=rxidoks(buffer);
 }
 else
 {
  xfaxtxid(buffer); 
  if(checkid) code=txidoks(buffer);
 }

 if(!code) logreasonx("Bad ID");

 return(code);
}




/* int  sgetc(int timeout);            // get byte from port */
/* int  sputc(int c);                  // put byte to port   */


int sgetc(int fp)
{
 int timeout=stack[fp]+clock();
 int code;

 do
 {
  if((code=getbyte())!=-1) break;
  if(scriptstop()) break;
  if(scriptpoll) pollzt();
 }
 while(clock()<timeout);

 return(code);
}


int sputc(int fp)
{
 return(outbyte(stack[fp]));
}




/* attempt to get prompt, return 1, else 0 (fail) */

static int getprompt(char * string,int time)
{
 char result[128];
 int  len;
 int  match;
 int  code;
 int  byte;

 if(convert(string,result,&len,128)) return(0);

 time=clock()+time;
 code=0;
 match=0;

 while(clock()<time)
 {
  byte=getbyte();

  if(byte!=-1)
  {
   if(result[match]==byte)
   {
    match++;
    if(match==len)
    {
     code=1;
     break;
    }
   }
   else match=0;
  }
  else
  {
   if(scriptpoll) pollzt();
   if(scriptstop()) break;
  }
 }

 return(code);
}



int ourgetprompt(int fp)
{
 return(getprompt(stringptr(stack[fp]),stack[fp+1]));
}


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




void hsystdheader(FILE * fp,char * name)
{
 char string[64];
 rfprintf(fp,"//->%s\n",name);
 writesystimedate(string);
 rfprintf(fp,"// Produced by ArcFax at %s\n//\n//\n\n\n",string);
}



static void addfiles(char * name,int remove)
{
 fxstat f;
 char   temp[256];
 int    code;

 startscan();
 while(1)
 {
  strcpy(temp,name);

  if(!nextitem(temp,&f,NULL)) break;

  if(f.f.object==1)
  {
   strcat(temp,".");
   strcat(temp,f.name);

   code=xaddfile(temp,0,1);
   if(remove && code) xremfile();

   changedriver();
  }
 }
}


/* return 1==OK 0==ERROR */

int runscript(char * filename,int exec)
{
 int code;
 code=xaddfile(filename,0,exec);
 if(code && exec) xremfile();
 changedriver();
 return(code);
}


void runscriptpost(void)
{
 xexec("main",NULL,NULL,NULL);
 xremfile();
 changedriver();
}


int xexecstuff(char * stuff)
{
 int code;
 code=xaddfile(stuff,1,1);
 if(code) xremfile();
 changedriver();
 return(code);
}



void scriptstart(int quiet,int hold)
{
 xstart();                  /* start up x language    */

 addfiles(path(LIBP),0);     /* do library */

 xexec("device_initiate",NULL,NULL,NULL);

 addfiles(path(AUTOP),1);     /* auto run */                      

/* checkunsent(); */        /* after load sched, before boot target */

 if(!isalt && !quiet && !quietboot) 
 {
  checkunsent(hold);        /* after load sched, before boot target */ 
  stategoanswer();
 }
}


