#include "config.h"
#include <string.h>
#include <stdio.h>
#ifndef vms
#include <sys/types.h>
#include <sys/stat.h>
#else
#include <types.h>
#include <stat.h>
#endif

int stat();

char *path_segment();
char *pprint();
extern void  Warning();
extern bool  G_quiet;
extern int   Debug;

#ifdef MAKETEXPK
extern bool    makeTexPK ;
#endif

#ifdef unix
#ifdef DO_SUBDIRECTORIES
#include <glob.h>
#endif
#endif

#ifdef unix
  static char* raster_table[] = {
#ifdef USEPXL
    "%P/%N.%Rpk",
    "%P/%N.%Rpxl",
    "%P/dpi%R/%N.pk",
    "%P/%R/%N.pxl",
    "%P/dpi%R/%N.pxl",
    "%P/pxl%M/%N.pk",
    "%P/pxl%M/%N.pxl",
    "%P/%N.%R",
#else
    "%P/%N.%Rgf",
    "%P/%N.%Mgf",
#endif
    NULL
  };
#endif

#ifdef vms
  static char* raster_table[] = {
#ifdef USEPXL
    "%P[%R]%N.pk;",
    "%P%N.%Rpk;",
    "%P:[%R]%N.pk;",
    "%P:%N.%Rpk;",
    "%P[%R]%N.pk;",
    "%P%N.%Mpxl;",
    "%P:[%M]%N.pxl;",
    "%P:%N.%Mpxl;",
#else
    "%P%N.%Rgf;",
    "%P:%N.%Rgf;",
    "%P%N.%Mgf;",
    "%P:%N.%Mgf;",
#endif
    NULL
  };
#endif

#ifdef MSDOS
  static char* raster_table[] = {
#ifdef USEPXL
    "%P/dpi%R/%N.pk",
    "%P/%R/%N.pk",
    "%P/dpi%R/%N.pxl",
    "%P/%R/%N.pxl",
    "%P/pxl%M/%N.pk",
    "%P/pxl%M/%N.pxl",
    "%P/%N.%R",
#else
    "%P/%R/%N.gf",
    "%P/dpi%R/%N.gf",
    "%P/pxl%M/%N.gf",
#endif
    NULL
  };
#endif

#ifdef _AMIGA
  static char* raster_table[] = {
#ifdef USEPXL
    "%P/%N.%Rpk",
    "%P/%N.%Rpxl",
    "%P/dpi%R/%N.pk",
    "%P/%R/%N.pxl",
    "%P/dpi%R/%N.pxl",
    "%P/pxl%M/%N.pk",
    "%P/pxl%M/%N.pxl",
    "%P/%R/%N.%Rpk",
    "%P/%N.%R",
#else
    "%P/%N.%Rgf",
    "%P/%N.%Mgf",
#endif
    NULL
  };
#endif




bool
findfile(path,n,fontmag,name,tfm,level)
char path[STRSIZE];   /* PIXEL path */
char n[STRSIZE];      /* name of font */
long fontmag;         /* magnification */
char name[STRSIZE];   /* full name of PXL file  (returned) */
bool tfm;             /* are we searching for a tfm file? */
int level;            /* recursion level to prevent calling of MakeTeXPK */ 
{
  char local_path[STRSIZE];
#ifdef MAKETEXPK
  char MakePKCommand[STRSIZE];
#endif
  char *pathpt;
  struct stat s;
  int resolution, i;
  char **pattern;

  if (tfm) {
    resolution = 0; /* dont'care */
#ifdef DEBUG
    if (Debug) 
      fprintf(stderr, 
	      "locating tfm %s, path %s, depth=%d\n",
	      n, path, level);
#endif
  } else {
    resolution = (int)(fontmag/5.0 + 0.5);
#ifdef DEBUG
    if (Debug) 
      fprintf(stderr, 
	      "locating raster %s, resolution %d on path %s, depth=%d\n",
	      n, resolution, path, level);
#endif
  }


#ifndef vms
    for( i=0; (pathpt = path_segment(i, path, local_path)) != NULL; i++) {
      if (tfm) {
	if (!stat( pprint(name,"%P/%N.tfm",pathpt,n,resolution,fontmag), &s))
	  return(TRUE);
      } else {
	for (pattern = raster_table; *pattern; pattern++) {
	  if (!stat( pprint(name,*pattern,pathpt,n,resolution,fontmag), &s))
	    return(TRUE);
	}
      }
    }
#else
  if (tfm) {
    if ( !stat(pprint(name,"%P/%N.tfm",pathpt,n,resolution,fontmag), &s))
      return(TRUE);
  } else {
    for (pattern = raster_table; *pattern; pattern++) {
      if (!stat( pprint(name,*pattern,path,n,resolution,fontmag), &s))
	return(TRUE);
    }
  }
#endif

#ifdef FUTURE
    for(i=0; (pathpt=path_segment((bool)(i==0),VFPATH,local_path))!=NULL;i++) {
      sprintf(name,"%s/%s.vfm",pathpt,n);
      printf("searching virtual font <%s>\n",name);
      if (stat(name,&s) == 0) return(TRUE);
    }
#endif

#ifdef DO_SUBDIRECTORIES
  if (level < MAX_SUBDIR_SEARCH_DEPTH) {
    for( i=0; (pathpt = path_segment(i, path, local_path)) != NULL; i++) {
      glob_t globbuf;
      char   glob_path[STRSIZE + 3];
      int    i;
      sprintf( glob_path, "%s/*", pathpt );
      if (glob( glob_path, 0, NULL, &globbuf ) == 0) {
	for (i = 0; i < globbuf.gl_pathc; i++) {
	  if ((stat( globbuf.gl_pathv[i], &s) == 0) && S_ISDIR(s.st_mode)) {
	    if (findfile(globbuf.gl_pathv[i],
			 n,
			 fontmag,
			 name,
			 tfm,
			 level+1 ) == TRUE) {
	      globfree( &globbuf );
	      return(TRUE);
	    }
	  }
	}
	globfree( &globbuf );
      }
    }
  } else {
    Warning("maximal searchdepth (%d) exceeded, path=%s",
	    MAX_SUBDIR_SEARCH_DEPTH, path);
  }
#endif

#ifdef MAKETEXPK
  if (makeTexPK && level == 0 && !tfm) {
    sprintf(MakePKCommand,"%s %s %d %d %.4f %s",MAKETEXPK,
	    n,resolution,RESOLUTION,
	    (float)((float)resolution/RESOLUTION),MFMODE);
    if (!G_quiet) 
      fprintf(stderr,"calling: %s\n",MakePKCommand);
    system(MakePKCommand);
    if (findfile(path,n,fontmag,name,tfm,1)) 
      return(TRUE);
  }
#endif

  if (level == 0) {
    /* return error message */
    if (tfm) {
      sprintf(name, "tfm file not found: path=%s, name=%s", path,n);
    } else {
      sprintf(name,
#ifdef USEPXL
	 "pk or pxl font not found: path=%s, name=%s, resolution=%d, magn=%ld",
#else
	 "gf font not found: path=%s, name=%s, resolution=%d, magn=%ld",
#endif
	  path,n,resolution,fontmag);
    }
  }
  return(FALSE);
}


char *
pprint (buffer, input, path, name, resolution, fontmag)
char *buffer;
char *input;
char *path;
char *name;
int  resolution;
long fontmag;
{
  char *output = buffer;
  
  /*  fprintf(stderr, "pprint called with <%s>\n", input);*/
  for (; *input != '\0'; input++)
    {
      if (*input == '%') {
	switch (*(++input)) 
	  {
	  case 'P':
	    strcpy(output, path);
	    output += strlen(output);
	    break;

	  case 'N':
	    strcpy(output, name);
	    output += strlen(output);
	    break;

	  case 'R':
	    sprintf(output, "%d", resolution);
	    output += strlen(output);
	    break;

	  case 'M':
#ifdef vms
	    sprintf(output, "%d", fontmag);
#else
	    sprintf(output, "%ld", fontmag);
#endif
	    output += strlen(output);
	    break;

	  default:
	    *output++ = '%';
	    *output++ = *input;
	    break;
	  }
      } else {
	*output++ = *input;
      }
    }
  *output = '\0';
  /* fprintf(stderr, "pprint returns <%s>\n", buffer); */
  return buffer;
}


char *
path_segment(index,full_path,local_path)
int index;
char *full_path, *local_path;
{
  static char *pppt;
  char *pathpt;

  if (index == 0) pathpt = strcpy(local_path,full_path);
  else pathpt = pppt;
  if (pathpt != NULL) {
#ifdef unix
    pppt = strchr(pathpt , ':' );
#else
    pppt = strchr(pathpt , ';' );
#endif
    if (pppt != NULL) {
      *pppt = '\0';
      pppt++;
    }
  }
  return pathpt;
}