/* Include files */
#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/rdargs.h>
#include <clib/dos_protos.h>

#include <stdio.h>
#include <stdlib.h>

#include "global.h"
#include "load.h"
#include "list.h"
#include "flush.h"
#include "output.h"


/* ReadArgs structure and related constants */
#define LA_TEMPLATE	"LIBS=LIBNAMES/M,A=ALL/S,L=LIST/S,F=FLUSH/S"

struct LibArgs {
  /* These will be set by ReadArgs() ... */
  STRPTR  *LIBNAMES;
  ULONG   ALL;
  ULONG   LIST;
  ULONG   FLUSH;
  
  /* And this will be set by me */
  ULONG   Flags;
};

/* LibArgs.Flags bit numbers */
#define LAFB_LIBNAMES	31
#define LAFB_ALL	0
#define LAFB_LIST	1
#define	LAFB_FLUSH	2

/* LibArgs.Flags values */
#define LAFF_NONE	0
#define LAFF_LIBNAMES	(1<<LAFB_LIBNAMES)
#define LAFF_ALL	(1<<LAFB_ALL)
#define LAFF_LIST	(1<<LAFB_LIST)
#define LAFF_FLUSH	(1<<LAFB_FLUSH)



extern struct ExecBase *SysBase;
struct RDArgs *rdargs;


/* Initialise global variables */
void init_globals(void)
{
  rdargs = NULL;
}


/* Exit without hassle */
/* RC - return code eg 5=warning, 10=error, 20=failure, 100=armageddon etc */
void clean_exit(int RC)
{
  /* Free the ReadArgs structure if allocated */
  if (rdargs) FreeArgs(rdargs);
  
  exit(RC);
}

/* Disable automatic program abortion if present */
void chkabort(void) {return;}


/* Start of the Program */
int main(int argc, char *argv[])
{
  struct LibArgs LibArgs = {NULL, FALSE, FALSE, FALSE, LAFF_NONE};
  int i;
  
  init_globals();
  OutputHeader();
  
  /* Check the OS version */
  if (SysBase->LibNode.lib_Version < 36)
  {
    /* I don't know, some people... *sigh* */
    fputs("Hey! What's the matter with you? 1.3 sux! Get OS2 now, then\n",stderr);
    fputs("you too can run this cool program!\n",stderr);
    clean_exit(20);
  }
  
  /* Collect the arguments */
  rdargs = ReadArgs(LA_TEMPLATE,(LONG *)&LibArgs,NULL);
  if (!rdargs)
  {
    OutputUsage();
    clean_exit(5);
  }
  
  LibArgs.Flags = ((LibArgs.LIBNAMES != NULL) << LAFB_LIBNAMES) |
                  ((LibArgs.ALL & 1) << LAFB_ALL) |
                  ((LibArgs.LIST & 1) << LAFB_LIST) |
                  ((LibArgs.FLUSH & 1) << LAFB_FLUSH);
  
  switch (LibArgs.Flags)
  {
  
  /*-- No library names, ALL flag set --*/
  case (LAFF_ALL):
    LoadLibs();
    break;
  
  /*-- No library names, LIST flag, or ALL and LIST flags set --*/
  case (LAFF_LIST):
  case (LAFF_LIST | LAFF_ALL):
    ListLibs();
    break;
  
  /*-- No library names, FLUSH flag, or ALL and FLUSH flags set --*/
  case (LAFF_FLUSH):
  case (LAFF_FLUSH | LAFF_ALL):
    FlushLibs();
    FlushLibs();  /* Seems we need to do this twice.  I wonder why? */
    break;
  
  /*-- Library names, no flags set --*/
  case (LAFF_LIBNAMES):
    for (i=0; LibArgs.LIBNAMES[i] != NULL; i++)
      LoadLib(LibArgs.LIBNAMES[i],REPORT);
    break;
  
  /*-- Library names, LIST flag set --*/
  case (LAFF_LIBNAMES | LAFF_LIST):
    OutputLibInfoHeader();
    for (i=0; LibArgs.LIBNAMES[i] != NULL; i++)
      ListLib(LibArgs.LIBNAMES[i]);
    break;
  
  /*-- Library names, FLUSH flag set --*/
  case (LAFF_LIBNAMES | LAFF_FLUSH):
    for(i=0; LibArgs.LIBNAMES[i] != NULL; i++)
      FlushLib(LibArgs.LIBNAMES[i]);
    break;
  
  /*-- Default --*/
  default:
    OutputUsage();
  }
  
  /* that's all for now, folks! */
  clean_exit(0);
  
  return 0; /* Keep the compiler happy */
}
/* End of the program */
