/* (C) Tim Graves 20th April 1994
   This code is supplied AS IS. no warrantee either expressed or implied 
   is provided. This code may be freeley modified and modified as long as my
   origional authorship is acknowledged. 
   
   Tim Graves
    Sun Microsystems
     
     */
/* this file contains the filter subsystem, it is used to automaticaly 
perform filter operations on programs
NOTE filters are set throughout the psion program and are not affected by 
calling run 
NOTE it is nessecary that the pscmd files will leave the output in the 
same file as the input */
#include <stdio.h>
#include "psion.h"
#include "psfilt.h"
#include <ctype.h>
#include <string.h>
extern int debugcall ;
static char vsn[]="@(#) psfilt.c 2.4@(#)" ;
/* the structures to hold the filter entries */
struct filterstruct * filters;
initfilters()
{
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: initfilters()\n") ;
	filters == NULL ;
}

setupfilter (filttype, suffix, pscmd)
int filttype ;
char * suffix, *pscmd ;
{
	struct filterstruct * current;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: setupfilter (filttype = %d, suffix = %s, pscmd = %s)\n",filttype, suffix, pscmd) ;
	current = filters ;
	/* first of all does the filter already exist for the direction 
	   we want to go ? if so overwrite it */
	while (current != NULL)
	{
		if ((current->direction == filttype) && (strcmp(current->suffix, suffix) == 0))
		{
			return (installfilter(filttype, suffix, pscmd, current)) ;
		}
		current = current->nextfilter ;
	}
	/* we've got here and not found a filter to overwrite and there
	   is space, install at the end of the list */
	return (newfilter(filttype, suffix, pscmd)) ;
}
removefilter (filttype, suffix)
int filttype ;
char * suffix ;
{
	struct filterstruct * current, *prev;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: removefilter (filttype = %d, suffix = %s, )\n",filttype, suffix) ;
	if (filters == NULL) 
		return(OK) ;
	current = filters ;
	/* check if the filter is the first in the list */
	if ((filters->direction == filttype) && (strcmp(filters->suffix, suffix) == 0))
	{
		/* make sure we have a start pointer */
		filters = filters->nextfilter ;
		/* free the data */
		free(current) ;
		return(OK) ;
	}
	prev = filters ;
	while (current != NULL)
	{
		if ((current->direction == filttype) && (strcmp(current->suffix, suffix) == 0))
		{
			/* remove from the list */
			prev->nextfilter = current->nextfilter ;
			/* free the data */
			free (current);
			return (OK);
		}
		/* next item on the list */
		prev = current ;
		current = current->nextfilter ;
	}
}
	
/* install a filter into slot */
installfilter (filttype, suffix, pscmd, current)
int filttype;
struct filterstruct *current ;
char * suffix, *pscmd ;
{
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: installfilter (filttype = %d, suffix = %s, pscmd = %s, current = (OMITED))\n",filttype, suffix, pscmd) ;
	/* lets do the setup */
	/* the direction */
	current->direction = filttype ;
	/* the suffix, if their is a . remove it */
	if (suffix[0] == '.')
		suffix ++ ;
	strcpy(current->suffix, suffix) ;
	/* and the pscmd file */
	strcpy(current->pscmd , pscmd) ;
	return (OK) ;
}

/* newfilter, create a filter add it to the list then fill it */
newfilter(filttype, suffix, pscmd)
int filttype;
char * suffix, *pscmd ;
{
	struct filterstruct *new ;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: newfilter (filttype = %d, suffix = %s, pscmd = %s, )\n",filttype, suffix, pscmd) ;
	new = (struct filterstruct *) calloc (1, sizeof (struct filterstruct)) ;
	/* add it to the head of the list */
	new->nextfilter = filters ;
	filters = new ;
	/* create the filter */
	return (installfilter(filttype, suffix, pscmd, filters));
}
char * filtertype (direction)
int direction ;
{
	if (direction == OUTFILTER)
		return("Output, ") ;
	else if (direction == INFILTER)
		return("Input,  ") ;
	else
		return("Restore,") ;
}
/* print each item in the filter list */
printfilters()
{
	struct filterstruct *current ;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: printfilters ()\n") ;
	/* initialise to the head of the list */
	current = filters ;
	if (filters == NULL) 
	{
		printf("No filters currently installed\n") ;
		return(OK) ;
	}
	printf("Current installed filters\n") ;
	/* run through the list */
	while (current != NULL)
	{
		printf("Direction %s Suffix %s, Pscmd %s\n", filtertype(current->direction) , current->suffix, current->pscmd) ;
		/* next item on the list */
		current = current->nextfilter ;
	}
}


/* locate the filter and return a pointer to the pscmd string 
return NULL is there is no filter */
char * locatefilter(direction, suffix)
int direction ;
char * suffix ;
{
	struct filterstruct * current;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: locatefilter (direction = %d, suffix = %s)\n",direction, suffix) ;
	current = filters ;
	/* lets doit */
	while (current != NULL)
	{
		if ((current->direction == direction) && (strcmp(current->suffix, suffix) == 0))
		{
			return (current->pscmd) ;
		}
		current = current->nextfilter ;
	}
	/* we've got here and not found a filter return NULL*/
	return (NULL) ;
}
filefilt(direction,fname)
int direction ;
char * fname ;
{
	char tmp[1000] ;
	char * suffix ;
	char * pscmd ;
	if (debugcall >= FILTCALLDEBUG)
		printf("CALL: filefilt (direction = %d, fname = %s )\n",direction, fname) ;
	/* locate the . in the suffix, if it does not exist just return
	   unless the helpfull variable is set inwhich case print out a 
	   suitable massage before returning */
	if ((suffix = strchr(fname,'.')) == NULL)
	{
		if (findvar(VAR_HELPFULL) == NULL)
			return(OK) ;
		else
		{
			printf("HELP: You have initiated a transfer of (%s) for which there\n", fname) ;
			printf("is no suffix, no filter will be run\n") ;
			return(OK) ;
		}
	}
	/* suffix will point to the . so increment one */
	suffix ++ ;
	/* locate the filter to call */
	if ((pscmd = locatefilter(direction, suffix)) == NULL)
		return(OK) ;
	/* build the filter command */
	strcpy(tmp, "run ") ;
	strcat(tmp, pscmd) ;
	strcat(tmp," ") ;
	strcat(tmp,fname) ;
	/* be talkative is we want */
	if (findvar(VAR_VERBOSE) != NULL)
		printf("Calling %s filter (%s)\n", filtertype(direction),tmp) ;
	/* call the command interpreter to do the work */
	cmdintr(tmp) ;
}
