/*->c.batch */

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


#include "h.os"
#include "h.bbc"
#include "h.wimp"
#include "h.flex"
#include "h.akbd"

#include "h.Drawlevel0"

#include "h.wos"
#include "h.timex"
#include "h.key"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.strdef"

#include "h.file"
#include "h.serial"
#include "h.view"
#include "h.dir"
#include "h.xext"
#include "h.sched"
#include "h.pic"
#include "h.vx"
#include "h.replay"
#include "h.copy"
#include "h.mess"
#include "h.trans"

#include "h.batch"


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

int autoremove;               /* auto remove files from batch on send  */
int retainbatch=1;            /* retain batch info    */
int batchmodded;              /* modified bat         */
int batdiscard;               /* discard short files  */
int batpopup;
int txbatpopup;
int newfaxpopup;
int unsentwarn;               /* warn if unsent files on start up */
int batforward;               /* forward faxes */
char batforwardname[NUMLEN];
int bataftertime;             /* after time */
int batbeforetime;
int batchlimit=1;
int batchlimitn=70;

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


void bootbatch(void)
{
 FILE * fp;
 int    i;

 setnofiles(TXBFILE,0);
 setnofiles(RXBFILE,0);

 fp=fopen(path(BATP),"rb");
 if(fp)
 {
  for(view=0;view<BATN;view++)
  {
   fread(&vnofiles[view],sizeof(int),1,fp);
   if(vnofiles[view]<0) vnofiles[view]=0;
   setnofiles(view,vnofiles[view]);
   fread(vtable[view],sizeof(ficon),vnofiles[view],fp);
   for(i=0;i<vnofiles[view];i++)
   {
    if(strlen(vtable[view][i].oldname))
    {
     strcpy(vtable[view][i].name,vtable[view][i].oldname);
     *vtable[view][i].oldname=0;
    }
   }
  }
  fclose(fp);
 }
}




void savebatch(void)
{
 FILE * fp;

 if(retainbatch && batchmodded)
 {
  fp=fopen(path(BATP),"wb");
  if(fp!=NULL)
  {
   for(view=0;view<BATN;view++)
   {
    fwrite(&vnofiles[view],sizeof(int),1,fp);
    fwrite(vtable[view],sizeof(ficon),vnofiles[view],fp);
   }
   fclose(fp);
   batchmodded=0;
  }
 }
}



static int firstnew(int view)
{
 int i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].new) return(i);
 }

 return(-1);
}


void opentxbatch(void)
{
 int new;
 view=TXBFILE;
 new=firstnew(view);
 if(new<0) new=0;
 openview(new);
}



void openrxbatch(void)
{
 int new;
 view=RXBFILE;
 new=firstnew(view);
 if(new<0) new=0;
 openview(new);
}



void batchpop(void)
{
 if(batpopup)
 {
  view=RXBFILE;
  if(firstnew(RXBFILE)>=0) openrxbatch();
 }

 batchcheck();
}



static char * batarray[]=
{
 "BAT00",
 "BAT01",
 "BAT02",
};


#define BATLIMIT batchlimitn



void batchcheck(void)
{
 int    code;
 char * p;
 int    handle;

 code=0;

 if(batchlimit && vnofiles[TXBFILE]>=BATLIMIT) code|=1;
 if(batchlimit && vnofiles[RXBFILE]>=BATLIMIT) code|=2;


 if(code)
 {
  code--;

  p=batarray[code];

  if(whandle[DWARN]) forward(whandle[DWARN]);
  else
  {
   handle=createwindow(DWARN);
   if(!handle) return;
   popup(handle,0);
  }

  writeiconf(whandle[DWARN],0,"%s %s",transtoken(p),transtoken("BAT03"));
 }
 else
 if(whandle[DWARN]) closedownt(DWARN);

}







/* called when a file is dropped into a window */
/* return 0      on error                      */
/* return insert posn+1                        */
/* view/file already set up                    */
/* adding to TX batch                          */

int batchload(int type,char * filename,int xvolatile)
{
 ficon   fi;
 int     i;
 int     ow;

 memset(&fi,0,sizeof(ficon));

 strcpy(fi.name,leaf(filename));

 for(i=0;i<vnofiles[view];i++)
 {
  if(cstrcmp(vtable[view][i].name,fi.name)>=0) break;
 }

 ow=(i<vnofiles[view]) && !cstrcmp(vtable[view][i].name,fi.name);

 stat(filename,&fi.stat);

 if(type==DIR || type==APP)
 {
  fi.stat.type=ARCHIVE;
  fi.tsum.maxwidth=1;
 }

 xvolatile=0;

 insertentry(i,&fi,ow);

 batchmodded=1;

 return(i+1);
}




/* file/view not set up                                         */
/* have to provide either view for root, or a dummy unused view */

int addtotxbatch(int type,char * filename,int xvolatile,int popup)
{
 int code;

 view=TXBFILE;

 code=batchload(type,filename,xvolatile);
 addschedule(&vtable[view][code-1].schedule);
 viewupdatetexticon(code-1);

 messageout(NewFax,0,TXBFILE,code-1,vtable[view][code-1].schedule);

 if(popup) opentxbatch();

 return(code);
}



int addtorxbatch(int type,char * filename,int xvolatile,int popup)
{
 int code;

 view=RXBFILE;

 code=batchload(type,filename,xvolatile);
 vtable[view][code-1].new=1;
 viewupdatetexticon(code-1);

 messageout(NewFax,0,RXBFILE,code-1,0);

 if(popup) openrxbatch();

 return(code);
}



/* high level batch load                        */
/* the file has already been saved to the batch */

int batchxload(int type,char * filename,int xvolatile)
{
 os_error * ep;
 int        code;
 tiffsum    tsum;
 char       destname[FSMAXLEAF];

 ep=NULL;

 code=NOLOAD; /* which is 0 */

 if(!ep)
 {
  memset(&tsum,0,sizeof(tiffsum));

  if(type==TIFF) ep=checktiff(&tsum,filename);
  else
  if(type==ASND) ep=checksnd(&tsum,filename);
  else
  if(type==APP || type==DIR) 
  {
   tsum.maxwidth=1;
  }
 }

 if(!ep)
 {
  code=batchload(type,filename,xvolatile);
  if(code)
  {
   if(view==TXBFILE)
   {
    addschedule(&vtable[view][code-1].schedule);
   }
   else
   if(view==RXBFILE)
   {
    vtable[view][code-1].new=1;
   }

   if(!xvolatile)  /* must be a real file */
   {
    sprintf(destname,"%s.%s",xvname(view),vtable[view][code-1].name);
    ep=copyfile(destname,filename,isshift,(type==APP || type==DIR));
   }

   if(type==DIR || type==APP)
   {
    stat(destname,&vtable[view][code-1].stat);
   }

   vtable[view][code-1].tsum=tsum;
   viewupdatetexticon(code-1);
  }
 }

 report(ep);

 return(code);
}


/*****************************************************************************/
/* script language interface */


void trashbatch(int view)
{
 int  i;
 char lname[FSMAXLEAF];

 for(i=0;i<vnofiles[view];i++)
 {
  sprintf(lname,"%s.%s",xvname(view),vtable[view][i].name);
  remove(lname);
 }

 if(vactive[view]) trashicons(i);

 vnofiles[view]=0;
 setnofiles(view,0);

 refreshallviews();

 batchmodded=1;
}


void emptybatch(int fp)
{
 if(stack[fp]==0) trashbatch(TXBFILE);
 else 
 if(stack[fp]==1) trashbatch(RXBFILE);            
}



int addtobatch(int fp)
{
 os_error * err;
 char       name[256];
 fstat      f;
 int        posn;
 tiffsum    tsum;


 strcpy(name,stringptr(stack[fp]));
 stat(name,&f);

 memset(&tsum,0,sizeof(tiffsum));

 if(f.type==TIFF) err=checktiff(&tsum,name);
 else
 if(f.type==ASND) err=checksnd(&tsum,name);
 else
 if(f.type==APP || f.type==DIR) 
 {
  tsum.maxwidth=1;
 }

 view=TXBFILE;

 posn=batchload(f.type,name,0);
 addschedule(&vtable[view][posn-1].schedule);
 vtable[view][posn-1].tsum=tsum;

 viewupdatetexticon(posn-1);

 messageout(NewFax,0,TXBFILE,posn-1,vtable[view][posn-1].schedule);

 return(posn);
}




int batchgetname(int fp)
{
 int n;
 int local;
 int view;

 if(stack[fp]==0) view=TXBFILE;
 else
 if(stack[fp]==1) view=RXBFILE;
 else             return(0);

 n=stack[fp+1]-1;
 local=stack[fp+2];

 if(n<0 || n>=vnofiles[view]) return(0);
 else
 {
  if(local) assignstring(stack[fp+3],vtable[view][n].name);
  else      assignstring(stack[fp+3],vtable[view][n].name);

  return(n+1);
 }
}



static char typename[3][16]=
{
 "Fax",
 "Message",
 "File"
};


static int nameflag;


void setbatchnames(int fp)
{
 strcpy(typename[0],stringptr(stack[fp]));
 strcpy(typename[1],stringptr(stack[fp+1]));
 strcpy(typename[2],stringptr(stack[fp+2]));
 nameflag=stack[fp+3];
}


void setbatchlimit(int fp)
{
 batchlimit=stack[fp];
 batchlimitn=stack[fp+1];

}




/* generate a file name */

void genbatchname(int bat,char * string,int ftype)
{
 int i;
 int j;
 int len;
 int max;
 int looped;
 int type;


 if(ftype==ASND) type=1;
 else
 if(ftype==TIFF) type=0;
 else            type=2;


 view=bat;

 if(nameflag & 0x1)
 {
  sprintf(string,"%s.%s",bat==TXBFILE?path(TXBP):path(RXBP),
                                                  typename[type]);
  if(!fexists(string)) return;
 }


 max=0;

 for(i=0;i<vnofiles[view];i++)
 {
  len=strlen(vtable[view][i].name);

  for(j=0;j<3;j++)
  {
   if(!isdigit(vtable[view][i].name[len-3+j])) break;
  }

  if(j==3) 
  {
   j=atoi(&vtable[view][i].name[len-3]);
   if(j>max) max=j;
  }
 }

 looped=0;
 while(1)
 {
  max++;
  if(max>999)
  {
   max=0;
   looped++;
   if(looped>1) break;
  }

  sprintf(string,"%s.%s%03d",bat==TXBFILE?path(TXBP):path(RXBP),
                                          typename[type],max);
  if(!fexists(string)) break;
 }
}



void makefilename(char * oldname,char * newname,char * path,int over)
{
 int        i;
 int        j;
 int        lenfile;
 int        lentemp;
 char    *  p;
 char       newfile[20];
 char       temp[20];


 strncpy(newfile,oldname,19);
 newfile[19]=0;


 j=0;
 for(i=0;i<strlen(newfile);i++)
 {
  newfile[i] &=0x7F;

  switch(newfile[i])
  {
   case  32: continue;
   case '.': newfile[j]='_';
             break;

   case '"':
   case '#':
   case '$':
   case '%':
   case '&':
   case '*':
   case ',':
   case ':':
   case '@':
   case'\\':
   case '^':
   case '|':
   case 127:
            newfile[j]='X';
            break;

   default :
            newfile[j]=newfile[i];
            break;
  }
  j++;
 }

 if(strlen(newfile)==0) strcpy(newfile,"File");
 else
 if(strlen(newfile)>10) newfile[10]=0;


 strcpy(newname,path);
 if(*newname) strcat(newname,".");
 p=newname+strlen(newname);
 strcpy(p,newfile);
 lenfile=strlen(newfile);

 for(i=0;i<1000;i++)
 {
  if((!fexists(newname)) || over) break;
  sprintf(temp,"%02d",i);
  lentemp=strlen(temp);
  if((lentemp+lenfile)>10) lenfile=10-lentemp;
  strcpy(p+lenfile,temp);
 }
}

