/******************************************************************************

    MODUL

    HISTORY

******************************************************************************/

/**************************************
		Includes
**************************************/

#include "all.h"
#include <rexx/errors.h>
#include <clib/rexxsyslib_protos.h>
#include <pragmas/rexxsyslib_pragmas.h>

/**************************************
	    Globale Variable
**************************************/

extern struct Library *IconBase,
		      *RexxSysBase;

/**************************************
	       Typedefs
**************************************/
typedef struct WBStartup    WBS;
typedef struct DiskObject   DISKOBJ;

/**************************************
	    Interne Variable
**************************************/
static ULONG	 newxdme;	    /* force new xdme */

static const char default_startupfile[] = ".edrc";
static const char default_projectfile[] = "XDME_Project_File";

static const char tmplate[] = "Files/M,"
			      "Startup=-S/K,"
			      "New=-N/S,"
			      "Iconify=-I/S,"
			      "Autoload=-A/S,"
			      "PubScreen=-PS/K,"
			      "ProjectFile=-PF/K";

struct __XDMEArgs XDMEArgs =
{
    NULL,	    /* Files */
    NULL,	    /* Startup-Filename */
    FALSE,	    /* NEW */
    FALSE,	    /* Iconify */
    FALSE,	    /* Autoload */
    NULL,	    /* PublicScreen */
    NULL,	    /* ProjectFile */
    /* ... */
};

/**************************************
	   Interne Prototypes
**************************************/



#ifdef _DCC
extern int wbmain (WBS * wbs); /* !!! No Prototype !!! */
int wbmain (WBS * wbs)
{
    return (main (0, (char **)wbs));
} /* wbmain */
#endif

#ifdef __SASC
/* disable ^C checking */
extern void __regargs __chkabort (void);
       void __regargs __chkabort (void) { /* empty */ }
#endif


int do_rexx (char *port_name, char *command)
{
    struct MsgPort *rp, *port;
    struct RexxMsg *rm, *msg;
    int replied = 0;

    if ((rp = CreateMsgPort())) {

	if ((rm = CreateRexxMsg(rp, NULL, NULL))) {
	    rm->rm_Args[0] = command;
	    if (FillRexxMsg(rm, 1, 0)) {

		Forbid();

		port = FindPort( (UBYTE *) port_name );
		if( port )
		    PutMsg( port, (struct Message *) rm );

		Permit();

		if (port) {
		    while (!replied) {
			WaitPort (rp);
			while (msg = (struct RexxMsg *)GetMsg (rp)) {
			    if (msg != rm) {
				msg->rm_Result1 = RC_ERROR;
				msg->rm_Result2 = ERR10_008; /* ne bessere Idee ? */
				ReplyMsg ((struct Message *)msg);
			    } else
				replied = 1;

			} /* while */
		    } /* while */
		} /* if */

		ClearRexxMsg(rm, 1);
	    } /* if */
	    DeleteRexxMsg(rm);
	} /* if */

	DeleteMsgPort(rp);
    } /* if */

    return replied;
} /* do_rexx */




/* Parse WB-ToolTypes */

void ops (char ** toolarray)
{
    char * tooltype;

    if (tooltype = FindToolType (toolarray, "ICONIFY"))
	XDMEArgs.iconify = MatchToolValue (tooltype, "YES");
    else
	XDMEArgs.iconify = FALSE;

    if (tooltype = FindToolType (toolarray, "AUTOLOAD"))
	XDMEArgs.autoload = MatchToolValue (tooltype, "YES");
    else
	XDMEArgs.autoload = FALSE;

    if (tooltype = FindToolType (toolarray, "PUBSCREEN"))
	XDMEArgs.publicscreenname = tooltype;	/* no strdup() here ! */

    if (tooltype = FindToolType (toolarray, "PROJECTFILE"))
	XDMEArgs.projectfilename = tooltype;   /* no strdup() here ! */

#ifdef DEBUG
    D(bug("sfile: %s\nnew %ld\niconify %ld\nauto %ld\n"
	    "PSName: `%s'\npf: `%s'\n", XDMEArgs.startupfile,
	    XDMEArgs.newxdme, XDMEArgs.iconify, XDMEArgs.autoload,
	    XDMEArgs.publicscreenname ? XDMEArgs.publicscreenname : "(nul)",
	    XDMEArgs.projectfilename ? XDMEArgs.projectfilename : "(nul)"));
#endif
} /* ops */


BOOL loadfile (BPTR lock, char * name)
{
    char buf[512];

    /* Load project ? */
    if (!stricmp (name, XDMEArgs.projectfilename))
    {
	    strcpy (buf, "cd `");

	    if (NameFromLock (lock, buf + 4, sizeof (buf) - 4))
	    {
		strcat (buf, "' projectload");

		do_rexx ("XDME.1", buf);
	    }
    } else
    {
	    strcpy (buf, !newxdme ? "newwindow cd `" : "          cd `");
	    newxdme = 0;

	    if (NameFromLock (lock, buf + 14, sizeof (buf) - 14))
	    {
		sprintf (buf + strlen (buf), "' newfile `%s'%s",
		    name, (XDMEArgs.iconify ? " iconify" : ""));
		do_rexx ("XDME.1", buf);
	    }
    } /* No PROJECTFILE */

    return (TRUE);
} /* loadfile */







int main (int mac, char ** mav)
{
    WBS *Wbs = NULL;
    WORD   i;		    /* temp. counter		   */
    ULONG  nf;		    /* # files on command line	   */
    BPTR   origlock;	    /* Start-Lock		   */
    PROC * proc        = (PROC *)FindTask(NULL);   /* our Task    */

    /* cd to dir of shell */
    origlock = CurrentDir (DupLock (proc->pr_CurrentDir));


    if (mac == 0)
    {		  /*  WORKBENCH STARTUP   */
	Wbs = (WBS *)mav;
    }

/* EYYYYY - how about that:
    if there is not yet a XDME Process or if a "New"
    Process is repested, we just call

    if (new_xdme_needed) {
	if (!Wbs) {
	    sprintf (buffer "run XDME %s", args);
	    system  (buffer);
	} else {
	    // aehm ... we would probably need something like this ...
	    WBStart ("XDME", Wbs);
	}
	return 0;
    }
*/

    {
	struct MsgPort * mp;

	Forbid ();
	mp = FindPort ("XDME.1");
	Permit ();

	if (!mp) {
	    system ("run XDME t:");

	    Delay (20);

	    Forbid ();
	    mp = FindPort ("XDME.1");
	    Permit ();

	    if (!mp) {
		puts("Cannot open XDME main process - exiting\n");
		return 10;
	    } /* if */

	    newxdme = 1;
	} /* if */
    }


    nf = 0;
    XDMEArgs.projectfilename = default_projectfile;
    XDMEArgs.startupfile     = default_startupfile;

    /* WB-Startup or CLI ? */
    if (Wbs)
    {
	/* Work on TOOLTypes */
	if (Wbs->sm_ArgList[0].wa_Lock)
	{
	    DISKOBJ	 * dobj;	/* For WB-Startup */
	    struct WBArg * wbarg;
	    BPTR	   current;

	    for (i=0; i<Wbs->sm_NumArgs; i++)
	    {
		wbarg = &Wbs->sm_ArgList[i];

		UnLock (CurrentDir (current = DupLock (wbarg->wa_Lock)));

		if (dobj = GetDiskObjectNew (wbarg->wa_Name))
		{
		    /* Only process names for ToolTypes, not for the the
		       program itself ! */

		    ops (dobj->do_ToolTypes);

		    if (i)
		    {
			if (loadfile (wbarg->wa_Lock, wbarg->wa_Name))
			    nf ++;
			else
			{
			    FreeDiskObject (dobj);
			    break;
			}
		    }

		    FreeDiskObject (dobj);
		}
	    }

	    /* CD to new base-dir */
	    UnLock (CurrentDir (DupLock (Wbs->sm_ArgList[0].wa_Lock)));
	}
    } else
    {
	XDMEArgs.newxdme = newxdme;

	/* Parse CLI-args */
	if ((XDMEArgs.ra = ReadArgs (tmplate, (LONG *)&XDMEArgs, NULL))
		&& XDMEArgs.files)
	{
#ifdef DEBUG
	    UWORD count = 0;
#endif
	    char ** nameptr;

	    for (nameptr=XDMEArgs.files; *nameptr; nameptr ++)
	    {
#ifdef DEBUG
		D(bug("Loading %ld %s ...\n", count ++, *nameptr));
#endif

		if (loadfile (origlock, *nameptr))
		    nf ++;
		else
		    break;
	    }
	}
    }

#ifdef DEBUG
    D(bug("Parsed ARGS\n"));
#endif

    /* Free args */
    if (XDMEArgs.ra)
	FreeArgs (XDMEArgs.ra);

    if (!nf)
    {  /* no files to edit: Open simple empty window */
	if (newxdme)
	{
	    do_rexx ("XDME.1", "chfilename unnamed arpload");
	} else
	if (XDMEArgs.iconify)
	{
	    do_rexx ("XDME.1", "newwindow iconify");
	} else
	{
	    do_rexx ("XDME.1", "newwindow");
	}
    } /* No files */


    /* Free Lock */
    UnLock (CurrentDir (origlock));

#ifdef DEBUG_MEM_H
    _debug_FreeAllMem ();
#endif /* DEBUG_MEM_H */

    /* All OK. */
    return 0;
} /* main */


/******************************************************************************
*****  ENDE main.c
******************************************************************************/

