#include <stdio.h>
#include <ctype.h>
#include "config.h"
#include "proto.h"
#include "portab.h"
#include "unixlib.h"

#if defined(ATARI_ST)
#include <string.h>
#include <stdlib.h>
#include <ext.h>

#elif defined(MSDOS)
#include <string.h>
#include <stdlib.h>
#include <sys\stat.h>

#elif defined(SUN)
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>

#elif defined(SEQUENT386) || defined(AVIION)
#include <sys/types.h>
#include <sys/stat.h>

#else
#error Wrong machine type. Edit config.h and follow the instructions.

#endif


#include "version.h"
#include "picstat.h"


void printline __P((char *name, struct picstat *buf,
                    unsigned long opts));
int lst_files __P((char *path, unsigned long opts));
int lst_dirs __P((char *path, unsigned long opts));
int is_directory __P((char *path));


#if defined(ATARI_ST)
#define MY_NAME "lspic"
#else
#define MY_NAME  argv[0]
#endif

#if defined(ATARI_ST) || defined(MSDOS)
#define USAGE   "Usage: %s [-C|-F|-H|-R|-V|-T] [filelist]    %s (%s)\n"
#else
#define USAGE   "Usage: %s [-c|-f|-h|-r|-v|-t] [filelist]    %s (%s)\n"
#endif

#define OPTS    "cfhrtCFHRT"


#define O_TYPE     0x00000001L
#define O_NFRAMES  0x00000002L
#define O_NCOLS    0x00000004L


/*
 *  print one line of output
 */

void printline (name, buf, opts)
char *name;
struct picstat *buf;
unsigned long opts;

{
  printf ("%8ld ", buf->p_fsize);
  printf ("%4dx%4d ", buf->p_sizex, buf->p_sizey);
  if (opts & O_NFRAMES)
    {
      if ((buf->p_nframes>1) || (buf->p_speed>0))
        {
          printf ("%4d/%-2d ", buf->p_nframes, buf->p_speed);
        }
      else
        {
          printf ("        ");
        }
    }
  if (opts & O_NCOLS)
    {
      if (buf->p_ncol > 999)
        {
          printf ("   ");
        }
      else
        {
          printf ("%3d", buf->p_ncol);
        }
    }
  printf ("%c%-3d ", buf->p_coltype, buf->p_colrez);
  if (opts & O_TYPE)
    {
      printf ("%-6s ", buf->p_type);
    }
  printf ("%s  ", name);
  printf ("  \n");
}


/*
 *  list all picture files in a directory
 */

int lst_files (path, opts)
 char *path;
unsigned long opts;

{
  char name[MAXPATH];
  struct direct **namelist;
  int bufcount;
  struct picstat buf;
  int i;

  bufcount = scandir (path, &namelist, no_pointdir, alphasort);
  if (bufcount == -1)
   return (-1);
  for (i=0; i<bufcount; i++)
    {
      if (strcmp(path, POINTDIR_STR) == 0)
        strcpy (name, "");
      else
        strcpy (name, path);
      strcat (name, namelist[i]->d_name);
      if (!flistat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!gifstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!ilbmstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!jpegstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!pbmstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!pcxstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
      else if (!rasterstat (name, &buf, 0))
        {
          printline(namelist[i]->d_name, &buf, opts);
        }
    }
  free (namelist);
  return (0);
}


/*
 *  call lst_files() for every directory in a directory
 */

int lst_dirs (path, opts)
char *path;
unsigned long opts;

{
  char name[MAXPATH];
  struct direct **namelist;
  int bufcount;
  int i;

  bufcount = scandir (path, &namelist, no_pointdir, alphasort);
  if (bufcount == -1)
   return (-1);
  for (i=0; i<bufcount; i++)
    {
      if (strcmp(path, POINTDIR_STR) == 0)
        strcpy (name, "");
      else
        strcpy (name, path);
      strcat (name, namelist[i]->d_name);
      if (is_directory(name))
        {
          printf("\n%s:\n", name);
          strcat (name, SLASH_STR);
          (void) lst_files (name, opts);
          (void) lst_dirs (name, opts);
        }
    }
  free (namelist);
  return (0);
}



/*
 *  
 */

int is_directory (path)
 char *path;

{
  struct stat sbuf;

  if ((strcmp(path, POINTDIR_STR) == 0) ||
      (strcmp(path, BPOINTDIR_STR) == 0))
    return (1);
  if (stat(path, &sbuf) == 0)
    if ((sbuf.st_mode & S_IFDIR) &&(sbuf.st_mode & S_IREAD))
      return (1);
  return (0);
}


/*
 *  
 */

void main (argc, argv)
 int argc;
 char *argv[];

{
  char path[MAXPATH];
  char old_path[MAXPATH];
  int c;
  int recflg=0, errflg=0;
  unsigned long opts=O_NCOLS;
  struct picstat buf;
  char *nextarg;
  int i;

  while ((c = getopt(argc, argv, OPTS)) != EOF)
    switch (c)
      {
        case 'c':
        case 'C':
          opts &= ~O_NCOLS;
          break;
        case 'f':
        case 'F':
          opts |= O_NFRAMES;
          break;
        case 'r':
        case 'R':
          recflg++;
          break;
        case 't':
        case 'T':
          opts |= O_TYPE;
          break;
        case 'h':
        case 'H':
        case OPT_UNKNOWN:
        default:
          errflg++;
          break;
       }
  if (errflg)
    {
      (void) fprintf (stderr, USAGE, MY_NAME, VERSION, MACHINE);
      exit (-1);
    }
  if (getwd (old_path) == NULL)
    {
      (void) fprintf (stderr, "%s: Can't get current path\n", MY_NAME);
      exit (-1);
    }
  nextarg = getarg(argc, argv, OPTS);
  if (nextarg == NULL)
    { 
      strcpy(path, POINTDIR_STR);
      nextarg = path;
    }
  while (nextarg != NULL)
    {
      if (!is_directory(nextarg))
        {
          if (!flistat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!gifstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!ilbmstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!jpegstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!pbmstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!pcxstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          else if (!rasterstat (nextarg, &buf, 0))
            {
              printline(nextarg, &buf, opts);
            }
          nextarg = getarg(argc, argv, OPTS);
          continue;
        }
      strcpy (path, nextarg);
#if defined (MSDOS) || defined(ATARI_ST)
      for (i=0; i < strlen (path); i++)
        {
          path[i] = (char) toupper (path[i]);
        }
#endif
      if (path[strlen(path)-1] == SLASH_CHAR)
        {
          path[strlen(path)-1] = 0;
        }
      printf("\n%s:\n", path);
      strcat(path, SLASH_STR);
      (void) lst_files (path, opts);
      if (recflg)
        {
          (void) lst_dirs (path, opts);
        }
      nextarg = getarg(argc, argv, OPTS);
    }
  if (chdir (old_path) == -1)
    {
      (void) fprintf (stderr, "%s: Can't restore old path\n", MY_NAME);
      exit (-1);
    }
  exit (0);
}
