//********
//
// Name : Read.c
//
// This routine parses the OnGo.Config file for the pop up menu;
// appmenu items; and "sticky" windows.  I keep meaning to write
// a prefs editor, so that I can have a binary based config file
// which will be faster, and more reliable than this one.  I
// suspect there is a bug which causes it to crash on some
// machines.  It works perfectly on mine, which makes debugging it
// rather tricky.  Further more, I do not have any docs to rdargs().
//
// Ray Price has sugguested that it is because FGets gives a null
// terminated string, but rdargs expects a \n terminated line.
// Thanks Ray.  I hope this now works.
//
//  1/09/96 Added a line of code to replace tabs with spaces.
//  I'm told that it crashed before if it encountered tabs.
//
//  2/10/1996 Added code to AllocDosObject readargs.  Thanks Bert.
//
//********

//********
//
// WARNING!
//
// This code is _really_ crap!
//
//********

//******** Header files

//** OS Include files
#include <dos/dos.h>
#include <dos/rdargs.h>

//** OS function prototypes
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

//** OS function inline calls
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>

//** ANSI C includes
#include <string.h>

//** Application Header files
#include "MPMGClass.h"
#include "Node.h"
#include "Read.h"
#include "Prefs.h"
#include "Tree.h"
#include "App.h"
#include "GrList.h"
#include "TDEBUG.H"

extern struct Library *DOSBase;


//******** Local Definitions

#define TEMPLATE  "TYPE/A,TEXT,FILE,DIR,LC/N,STACK/N,PRI/N,ICON"
#define OPT_TYPE        0
#define OPT_TEXT        1
#define OPT_FILE        2
#define OPT_DIR         3
#define OPT_CODE        4
#define OPT_STACK       5
#define OPT_PRI         6
#define OPT_ICON        7
#define OPT_COUNT       8
#define BUFSIZE         256

static char *TypeS[]={
  "ITEM",
  "MENU",
  "APPM",
  "LABEL",
  "QUIT",
  "HIDE",
  "RELOAD",
  "DISK",
  "STICKY",
  NULL
};

#define TYPE_ITEM 0
#define TYPE_MENU 1
#define TYPE_APPM 2
#define TYPE_LABEL 3
#define TYPE_QUIT 4
#define TYPE_HIDE 5
#define TYPE_RELOAD 6
#define TYPE_DISK 7
#define TYPE_STICKY 8

//******** Public functions

ULONG MyMenuMake(char *FileName) {
  char buffer[BUFSIZE];
  BPTR fh;
  BOOL reading;
  long opts[OPT_COUNT];
  ULONG MyMenus;
  STRPTR value;
  struct ProgNode *pn;
  ULONG NextLeaf=0;
  struct GrNode *gr;
  int typeid;
  char *tab;
  struct RDArgs *rdargs;
#ifdef TDEBUG
  ULONG lineno=0;
#endif

  // Try to open file specified in tooltype, or look in current
  // directory
  if (NULL==(fh=Open(FileName,MODE_OLDFILE))) {
    if (NULL==(fh=Open(ONGOCFG,MODE_OLDFILE))) {
      DPRINT("ReadPrefs ERROR : Could not open file %s\n",FileName);
      return 0L;
    }
  } // if open


  if (1==InitList()) {
    rdargs=(struct RDArgs *)AllocDosObject(DOS_RDARGS,NULL);
    if ((rdargs)&&(MyMenus=MPMG_MenuBuildNew())) {
      AddLevel(0);

      // Set up for rdargs()
      memset(rdargs,0,sizeof(rdargs));
      rdargs->RDA_Flags=RDAF_NOPROMPT;
      rdargs->RDA_Source.CS_Buffer=buffer;
      rdargs->RDA_Source.CS_Length=BUFSIZE;

      for (reading=TRUE; TRUE==reading ; ) { //lineno++) {
	if (NULL==FGets(fh,buffer,BUFSIZE)) {
	  reading=FALSE;
	  break;
	} // if

	// replace tabs with spaces (for Stefan :-)
	for (tab=buffer; tab=strchr(tab,'\t'); tab++) *tab=' ';

	strcat(buffer,"\n");  // Fixed by rprice@thenet.co.uk
			      // Thanks Ray!

	DPRINT("Reading line %ld\n",++lineno);
	rdargs->RDA_Source.CS_CurChr=0;
	memset(&opts,0,sizeof(opts));
	if (ReadArgs(TEMPLATE,opts,rdargs)) {
	  value=(char *)opts[OPT_TYPE];
	  if (NULL!=opts[OPT_ICON]) {
	    gr=NewNodeGr((char *)opts[OPT_ICON]);
	  } else {
	    gr=NULL;
	  }

	  // determine which dodah it is
	  for (typeid=0; TypeS[typeid]; typeid++) {
	    if (0==strcmp(value,TypeS[typeid])) break;
	  }

	  switch (typeid) {
	    case TYPE_ITEM:
	    case TYPE_APPM:
	      if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		pnSetFilename(pn,(char *)opts[OPT_FILE]);
		pnSetDirectory(pn,(char *)opts[OPT_DIR]);
		pn->pn_LaunchCode=(ULONG)*(ULONG *)opts[OPT_CODE];
		pn->pn_Stack=(ULONG)*(ULONG *)opts[OPT_STACK];
		pn->pn_Priority=(LONG)*(LONG *)opts[OPT_PRI];
		pn->pn_appmenu=NULL;
		if (TYPE_ITEM==typeid) {
		  pn->pn_Type=PNT_NULL;
		  MPMG_MenuBuildAdd(MPM_ITEM, pn->pn_Node.ln_Name, NULL, (APTR)pn, (APTR)gr, ACT_RUN );
		} else {
		  pn->pn_Type=PNT_APPMENU;
		}
	      }
	      break;
	    case TYPE_MENU:
	      if (0==strcmp((char *)opts[OPT_TEXT],"END")) {
		MPMG_MenuBuildAdd(MPM_MEND, NULL, NULL, NULL, NULL,NULL);
	      } else if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		MPMG_MenuBuildAdd(MPM_MENU, pn->pn_Node.ln_Name, NULL, NULL, (APTR)gr, NULL);
	      }
	      break;
	    case TYPE_QUIT:
	      if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		MPMG_MenuBuildAdd(MPM_ITEM, pn->pn_Node.ln_Name, NULL, NULL, (APTR)gr, ACT_QUIT );
	      }
	      break;
	    case TYPE_HIDE:
	      if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		MPMG_MenuBuildAdd(MPM_ITEM, pn->pn_Node.ln_Name, NULL, NULL, (APTR)gr, ACT_HIDE );
	      }
	      break;
	    case TYPE_RELOAD:
	      if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		MPMG_MenuBuildAdd(MPM_ITEM, pn->pn_Node.ln_Name, NULL, NULL, (APTR)gr, ACT_RELOAD );
	      }
	      break;
	    case TYPE_LABEL:
	      if (pn=NewNode()) {
		pnSetItem(pn,(char *)opts[OPT_TEXT]);
		MPMG_MenuBuildAdd(MPM_LABEL, pn->pn_Node.ln_Name, NULL, NULL, (APTR)gr, ACT_NULL );
	      }
	      break;
	    case TYPE_DISK:
	      value=AddBranch((char *)opts[OPT_TEXT],(char *)opts[OPT_FILE]);
	      MPMG_MenuBuildAdd(MPM_PROM, value, NULL, (APTR)(NextLeaf++) , (APTR)gr, ACT_NULL);
	      break;
	    case TYPE_STICKY:
	      NewNodeSticky((char *)opts[OPT_TEXT]);
	      break;
	    default:
	      //intf("Bad rdargs line %ld\n",lineno);
	      break;
	  } // switch

	  FreeArgs(rdargs);
	} else {
	  DPRINT("Read: bad rdargs1 line %d\n",lineno);
	} // if ReadArgs
      } // for

      MPMG_MenuBuildAdd(MPM_END, NULL, NULL, NULL, NULL, NULL );
      Close(fh);
      BindMenus();
      if (rdargs) FreeDosObject(DOS_RDARGS, rdargs);
      return MyMenus;
    }
    if (rdargs) FreeDosObject(DOS_RDARGS, rdargs);
  }
  return 0L;
} // MyMenuMake


void MyMenuFree(ULONG mm) {
  FreeMenus();
  MPMG_DisposeMenus(mm);
  FreeList(1);
} // MyMenuFree

//******** End of file

