/* Subroutines for change.c */

#include <dos.h>
#include <string.h>
#include <stdio.h>

extern char *buffer;
extern long nc,fsize,quiet,show;

/*
 * Now perform the search and replace function
 * It is after all, what we are here for!
 */
void search(strings,count,fh)
char **strings;
long count,fh;  
{
  struct pair
  {
    char *old,*new,*ptr;
  };
  struct pair s[10];
  long wrtlen;
  short i;
  char *pos=buffer;  /* pos points to char under consideration  */
  char *fpos=pos;    /* fpos points to next character to output */
  char *bufend=buffer+fsize;
  char *line=buffer; /* saves line start for character at pos */
  nc=0;          /* zero change count */
  if(!show) count>>=1;
  if(count>10)
  {
    puts("Only first 10 changes done");
    count=10;
  }
/* Read string pointers into array */
  for(i=0;i<count;i++)
  {
    s[i].old=*strings++;
    if(!show) s[i].new=*strings++;
    s[i].ptr=s[i].old;
  }
  while(pos<bufend)         /* while more buffer */
  {
    if(*pos=='\n' || *pos=='\r') line=pos+1; /* update line start */
    for(i=0;i<count;i++)    /* for each search string */
    {
      if(*pos!=*s[i].ptr++) /* test for match, step pointer on */
        s[i].ptr=s[i].old;  /* no match, reset pointer */
      if(*s[i].ptr=='\0')   /* test for complete match */
      {                     /* matched!! */
        pos++;
	if(!quiet)
	  if(query(line,pos,strlen(s[i].old))) break;
        /* get length of data to write minus the matched string */
        wrtlen=(pos-fpos)-strlen(s[i].old);
        if(wrtlen)                           /* write the data (if any) */
        Write(fh,fpos,wrtlen);
        Write(fh,s[i].new,strlen(s[i].new)); /* write new string to file */
        fpos=pos;                            /* update fpos */
        /* reset all search pointers,
           don't worry about i, outer loop breaks anyway */
        for(i=0;i<count;i++) s[i].ptr=s[i].old;
        nc++;                                /* count changes */  
        break;                               /* restart scan in while loop */
      }
    }
    pos++;
  }
  /* write remainder of file */
  wrtlen=pos-fpos;
  if(wrtlen) Write(fh,fpos,wrtlen);
}

long filesize(file)
char *file;
{
  struct FILEINFO *info;
  struct Lock *lock;
  long  size;

  /* Ensure info is longword aligned */
  info=(struct FILEINFO *)AllocMem(sizeof(struct FILEINFO),0);
  if( (lock=(struct Lock *)Lock(file,ACCESS_READ))==NULL )
  {
    printf("Cannot find file : %s\n",file);
    exit(0);
  }
  if(Examine(lock,info))
    UnLock(lock);
  {
    if(info->fib_DirEntryType>0)
    {
      puts("Cannot change directory\n");
      exit(1);
    }
  }
  size=info->fib_Size;
  FreeMem(info,sizeof(struct FILEINFO));
  return(size);
}

void dobackup(fname)
char *fname;
{
  char bakfile[30];
  int fnlen;
/*
 * Produce "fname.bak" from "fname" chopping off the path (if any)
 * and trailing characters if 30 character limit will be exceeded
 */
  fnlen=stcgfn(bakfile,fname);
  if(fnlen>26) fnlen=26;
  strcpy(bakfile+fnlen,".bak");
/*
 *  Save input file by renaming it
 */
  (void) remove(bakfile);
  if(rename(fname,bakfile))
  {
    puts("Cannot create .bak file\n");
    exit(1);
  }
}

int query(line,pos,len)
char *line,*pos;
int  len;
{
  #define ulon  "\x9B4;31;40m"
  #define uloff "\x9B0;31;40m"
  #define nputs(s,n) for(i=0;i<(n);i++)putchar(*((s)+i));
  char c;
  long i;
  nputs(line,(pos-line)-len);
  nputs(ulon,strlen(ulon));
  nputs(pos-len,len);
  nputs(uloff,strlen(uloff));
  while(*pos != '\n' && *pos != '\r')
    putchar(*pos++);
  putchar('\n');
  if(show) return(1);
  nputs("Replace (Y/N)?",14);
  (void)fflush(stdout);        /* ensure promt is printed */
  while(c=toupper(getchar()),c != 'Y' && c != 'N');
  return(c=='N');
}
