/* cmdline.c
 * File conversion package.  Parse the command-line options and convert them
 * into a useful format.
 *
 * Peter Webb, Summer 1990.
 */

/* X include files */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/* Standard include files */

#include <stdio.h>

/* Package include files */

#include "reformat.h"
#include "types.h"
#include "error.h"
#include "extern.h"

/* The constants, HDF, TIFF, etc, are defined in types.h. This is a global
 * variable.  This contains the mappings from the string representations
 * of the type names to their representations in an enumerated type. 
 */

FileCvt FileTypeMap[] = {
  { HDF, hdf },
  { TIFF, tiff },
  { GIF, gif },
  { FITS, fits },
  { XWD, xwd },
  { SUNRAST, sunrast},
  { RAW8, raw8 },
  { "None", none }
};

/* Set up a single (command-line specified) conversion */

static ErrorCode SetFileType(av, i, cvt_blk, type)
     char *av[];
     int i;
     CvtBlkPtr cvt_blk;
     DataType type;
{
  
  if (FROM_FILE(cvt_blk) == NULL)
    {
      if (av[i] == NULL)
	return(err_msg(ParseCvt, BadInputFile));
      if (*InputDirectory != NULL) sprintf(ScratchBuf, "%s/%s", InputDirectory,
					   av[i]);
      else strcpy(ScratchBuf, av[i]);
      FROM_FILE(cvt_blk) = strsave(ScratchBuf);
      FROM_TYPE(cvt_blk) = type;
    }
  else
    {
      if (av[i] == NULL)
	return(err_msg(ParseCvt, BadOutputFile));
      if (*OutputDirectory != NULL) sprintf(ScratchBuf, "%s/%s",
					    OutputDirectory, av[i]);
      else strcpy(ScratchBuf, av[i]);
      TO_FILE(cvt_blk) = strsave(ScratchBuf);
      TO_TYPE(cvt_blk) = type;
    }
  return(AllOk);
}

#ifndef XGUI

/* Parse the command line options.  See the list in options.h.  As each 
 * option is recognized, remove it (and any arguments) from the argument 
 * list.
 */

ErrorCode ParseOptions(argc, argv)
  int *argc;
  char *argv[];
{
  int count, i, j;

/* Initialize the Input and Output Directories */

  for (i=0; i<FILE_SIZE; i++)
    InputDirectory[i] = OutputDirectory[i] = (char) NULL;

  InputDirectory[0] = OutputDirectory[0] = '.' ;

/* Process the arguments */

  for (i=0, count=0; i < *argc; i++)
    {
      if (strcmp(argv[i], "-compress") == 0)
	{
	  argv[i] = NULL;
	  CompressHDF = TRUE;
	  count++;
	}
      else if (strcmp(argv[i], "-height") == 0)
	{
	  argv[i++] = NULL;
	  Height = (long)atoi(argv[i++]);
	  argv[i++] = NULL;
	  count++;
	}
      else if (strcmp(argv[i], "-width") == 0)
	{
	  argv[i++] = NULL;
	  Width = (long)atoi(argv[i++]);
	  argv[i++] = NULL;
	  count++;
	}
      else if (strcmp(argv[i], "-inputdir") == 0)
	{
	  argv[i++] = NULL;
	  strcpy(InputDirectory, argv[i]);
	  argv[i++] = NULL;
	  count += 2;
	}
      else if (strcmp(argv[i], "-outputdir") == 0)
	{
	  argv[i++] = NULL;
	  strcpy(OutputDirectory, argv[i]);
	  argv[i++] = NULL;
	  count += 2;
	}
    }

/* Now that all of the arguments have been processed, remove them from the
 * list.  They have been replaced with NULL already, so just shift the 
 * remaining arguments until they are contigious again.
 */

  for (i=0; i < *argc; i++)
    if (argv[i] == NULL)
      {
	j = i;
	while (argv[j] == NULL) j++;
	argv[i] = argv[j];
	argv[j] = NULL;
      }
  *argc -= count;

}

#endif

/* Convert a string representation of a file type into the internal 
 * enumerated type representation.
 */

DataType LookUpFileType(s)
  char *s;
{
  FileCvt *p;

  if (s == NULL) return(none);
  p = FileTypeMap;
  while (p->t != none && strcmp(p->str, s) != 0) p++;
  return(p->t);
}

ErrorCode ParseConversion(argc, argv, cvt_blk)
  int *argc;
  char *argv[];
  CvtBlkPtr cvt_blk;
{
  int i;
  ErrorCode error;
  DataType t;

/* Check the parameters */

  if (argc == NULL || argv == NULL || cvt_blk == NULL) 
    return(err_msg(ParseCvt, NullPtr));
  if (*argc == 0) return(AllOk);
  if (*argc < 0) return(err_msg(ParseCvt, BadInput));
  if (argv == NULL || cvt_blk == NULL) 
    return(err_msg(ParseCvt, NullPtr));

/* If there are any arguments left, they specify a file conversion operation.
 * Return this operation in the arg_block array.
 */

  if (*argc != 1)  /* 1 means just argv[0] is left */
    for (i = 1; i < *argc; i++)

/* Check for specifications of file names and types */
      
      if (*argv[i] == '-')
	{
/*	  if (argv[i+1] == NULL) usage();
	  else
	    { */
	      t = LookUpFileType(argv[i]+1);
	      if (t == none)
		{
		  err_msg(ParseCvt, BadOption);
		  usage();
		}
	      else
		if ((error = SetFileType(argv, i+1, cvt_blk, t, *argc))
		    != AllOk)
		  return(error);
/*	    } */
	  i += 1;
	}
      else
	{
	  err_msg(ParseCvt, BadOption);
	  usage();
	}
  return(AllOk);
}
