/*
 *  Request.c - open an "EasyRqeuester()" from script files
 *
 *  PUBLIC DOMAIN
 *
 *  by Stefan Sticht
 *
 *  V1.00             Stefan Sticht initial release
 *  V1.01             Stefan Sticht using cres.o for residentability
 *  V1.02 08 Sep 1991 Stefan Sticht added options "defpubscreen", "frontpubscreen"
 *                                  renamed option "screen" in "pubscreen"
 *  V1.03 16 Sep 1991 Stefan Sticht removed error in lockfrontpubscr()
 *  V1.04 03 Apr 1992 Stefan Sticht changed version string
 */

#define VERSION "V1.04"

#include <stdlib.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>

struct Screen *lockfrontpubscr(void);

/*
 *  some SAS/C specularities, change for other compilers!
 */
#ifdef __SASC
extern struct Library *DOSBase; /* Library base pointer from startup code */
extern struct Library *SysBase; /* Library base pointer from startup code */
void chkabort(void) {}          /* disable Ctrl-C detect */
#endif

#define PROGRAMTITLE "Request"

/*
 *  a string, which will be found by Version
 */
char version[] ="\0$VER: " VERSION;

struct IntuitionBase *IntuitionBase;

/*
 *  dummy window, we have to open
 */
struct NewWindow dummywindow = {
    0, 0,
    1, 1,
    -1, -1,
    0l,
    BORDERLESS | BACKDROP | SIMPLE_REFRESH,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    0, 0,
    0, 0,
    CUSTOMSCREEN
};

struct EasyStruct textreq = {
    sizeof (struct EasyStruct), /* ULONG es_StructSize      */
    0l,                         /* ULONG es_Flags           */
    NULL,                       /* UBYTE *es_Title          */
    NULL,                       /* UBYTE *es_TextFormat     */
    NULL,                       /* UBYTE *es_GadgetFormat   */
    };

#define TEMPLATE "Text/A,Title/K,Gadgets/K,PubScreen/K,DefaultPubScreen/S,FrontPubScreen/S"
#define OPT_TEXT            0
#define OPT_TITLE           1
#define OPT_GADGETS         2
#define OPT_PUBSCREEN       3
#define OPT_DEFPUBSCREEN    4
#define OPT_FRONTPUBSCREEN  5
#define OPT_COUNT           6

/*
 *  this array will be filled by ReadArgs()
 */
long options[OPT_COUNT];

struct Screen *lockfrontpubscr(void)
{
    struct Screen *scr;
    struct Screen *pubscr = NULL;
    struct List *pslist;
    struct PubScreenNode *psnode;
    unsigned long lock;
    unsigned short screentype;

    lock = LockIBase(0l);

    if (scr = IntuitionBase->FirstScreen) {

        screentype = scr->Flags & SCREENTYPE;

        UnlockIBase(lock);

        if (screentype == PUBLICSCREEN || screentype == WBENCHSCREEN) {

            if (pslist = LockPubScreenList()) {

                for (psnode = (struct PubScreenNode *)pslist->lh_Head;
                     psnode->psn_Node.ln_Succ && (psnode->psn_Screen != scr);
                     psnode = (struct PubScreenNode *)psnode->psn_Node.ln_Succ);

                if (psnode && (psnode->psn_Screen == scr) && !(psnode->psn_Flags & PSNF_PRIVATE)) {

                    pubscr = LockPubScreen(psnode->psn_Node.ln_Name);

                    }

                UnlockPubScreenList();

                }

            }

        }

    else UnlockIBase(lock);

    return(pubscr);
}

void _main(char *line)
{
    struct RDArgs *args;
    struct Screen *scr = NULL;
    struct Window *win;
    char *screen = NULL;
    long rc;
    unsigned short defpubscreen = TRUE;

    if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37l)) {

        if (args = ReadArgs((UBYTE *)TEMPLATE, options, NULL)) {

            if (options[OPT_TITLE])   textreq.es_Title = (UBYTE *)options[OPT_TITLE];
            if (options[OPT_GADGETS]) textreq.es_GadgetFormat = (UBYTE *)options[OPT_GADGETS];
            else textreq.es_GadgetFormat = "Ok";
            if (options[OPT_TEXT])    textreq.es_TextFormat = (UBYTE *)options[OPT_TEXT];
            if (options[OPT_PUBSCREEN]) {
                screen = (char *)options[OPT_PUBSCREEN];
                defpubscreen = FALSE;
                }
            if (options[OPT_DEFPUBSCREEN]) defpubscreen = TRUE;

            /*
             *  try to lock a screen according to switches
             */
            if ((options[OPT_FRONTPUBSCREEN] && (scr = lockfrontpubscr())) ||
                (!scr && screen && *screen && (scr = LockPubScreen(screen))) ||
                (!scr && defpubscreen && (scr = LockPubScreen(NULL)))) {

                dummywindow.Screen = scr;
                /*
                 *  try to open visitor window
                 */
                win = OpenWindow(&dummywindow);
                /*
                 *  now open the requester (win may be NULL)
                 */
                rc = EasyRequestArgs(win, &textreq, NULL, NULL);
                /*
                 *  don't forget closing the window
                 */
                if (win) CloseWindow(win);
                /*
                 *  now unlock the screen
                 */
                UnlockPubScreen(NULL, scr);
                }

            else {
                /*
                 * public screen not found
                 */
                PutStr("Can't find or lock screen!\n");
                rc = 20l;
                }

            }

        else {
            /*
             * error parsing options
             */
            PutStr("wrong number of arguments\n");
            rc = 40l;
            }

        /*
         *  free arguments and close the lib
         */
        FreeArgs(args);
        CloseLibrary((struct Library *)IntuitionBase);

        }

    else {
        /*
         *  we really need intuition lib
         *
         *  don't use PutStr() here, because dos.library could be < v36
         */
        Write(Output(), "Can't open intuition.library V37+!\n", 35l);
        rc = 30l;
        }

    exit(rc);
}
