/* asktask.c */
/*************************************************************************
 ***                    ASK TASK - EXAMINES EXEC TASKS                 ***
 *** Date begun: 31/3/89.                                              ***
 *** Last modified: 2/4/89.                                            ***
 ***                23/4/89 - added line to start from WB without con: ***
 *************************************************************************/

int     noWBcons = 1;       /* This is it! */

#include "asktask.h"

struct GfxBase          *GfxBase;
struct IntuitionBase    *IntuitionBase;
struct ExecBase         *ExBase;
struct Window           *Window;
struct NewWindow        NewWindow = {
    0,0,640,145,0,1,RAWKEY|MOUSEBUTTONS|CLOSEWINDOW|GADGETUP,
    WINDOWDEPTH|WINDOWCLOSE|WINDOWDRAG|SMART_REFRESH|ACTIVATE,
    NULL,NULL,"AskTask - JJB TEMPLAR",NULL,NULL,0,0,0,0,WBENCHSCREEN};

struct  Task    *task[NUM_TASKS];
char            tnames[NUM_TASKS*TNAMESIZE];
char            *tnp[NUM_TASKS];
int             numtasks,page,ct;

char    *notaskerror = "But there's no task! What are you trying to do?";

char        mypri;
struct Task *me;
int         mycolors;
UWORD       cmap[4] = {0x000,0x455,0x999,0x600};
UWORD       tmap[4];

extern struct Gadget *firstgadg;

extern void help();
extern void about();
extern void input(struct Window *,char *,char *,char *,int,int,int,int,int);
extern void rmv();
extern void kill();
extern unsigned long bitsput(char *);
extern void putbits(char *,unsigned long);
extern void prevpage();
extern void nextpage();
extern void puttname(int,int);
extern void puttasks();
extern void puttaskdata();
extern void setupwindow();
extern void putmessage(char *,int);
extern char getchfromw();
extern int  yesno();
extern void setsignal();
extern void changepri();

void    gettasks();
void    cleanup(int);
void    doclick(short,short);

void    gettasks() /*====================================================*/
{
int     i,j;
struct  Task *tp,**th;
    j = i = 0;
    Disable();
    th = (struct Task **)(ExBase->TaskReady.lh_Head);
    tp = *th;
    while (tp && (j < NUM_TASKS)) {
        task[j] = tp;
        strcpy(&tnames[i],tp->tc_Node.ln_Name);
        tnp[j] = &tnames[i];
        i += strlen(tnp[j]) + 1;
        j++;
        tp = (struct Task *)(tp->tc_Node.ln_Succ);
    }
    th = (struct Task **)(ExBase->TaskWait.lh_Head);
    tp = *th;
    while (tp && (j < NUM_TASKS)) {
        task[j] = tp;
        strcpy(&tnames[i],tp->tc_Node.ln_Name);
        tnp[j] = &tnames[i];
        i += strlen(tnp[j]) + 1;
        j++;
        tp = (struct Task *)(tp->tc_Node.ln_Succ);
    }
    Enable();
    numtasks = j;
    page = 0;   ct = -1;
}

void    doclick(x,y) /*==================================================*/
short   x,y;
{
    putmessage("",1);
    if ((x >= 2) && (x <= 165)) {
        if ((y < 21) || (y > 132)) return;
        y -= 21;
        y = (page * 14) + (y / 8);
        if (y >= numtasks) return;
        ct = y;
        puttaskdata();
        if (!tnp[y][0]) putmessage("WARNING: nameless tasks are dubious!",3);
    }
    else if ((x >= 168) && (x <= 471)) {
        if ((y < 10) || (y > 132)) return;
        puttaskdata();
    }
}

void    main(argc,argv) /*===============================================*/
int     argc;
char    *argv[];
{
struct IntuiMessage *msg,m;
struct Gadget       *gp;
int         event,j;
long        *hook;

    /* My default running priority is 15 */
    mypri = 15;     mycolors = 0;
    j = 1;
    while (j < argc) {
        if (argv[j][0] == '?') {
            printf("
[32m
[1m
[3mAskTask
[0m by 
[33m
[42m-+- JJB TEMPLAR -+-
[0m for examining task data.\n");
            printf("USAGE: %s [<-opt>]\n",argv[0]);
            printf("    where opt = c       - use intended (my) colors.\n");
            printf("                p{n}    - set asktask priority to n.\n");
            printf("    NOTE: [] = optional, <> = 1 or more, {} = mandatory.\n");
            exit(0);
        }
        if (argv[j][0] == '-') {
            switch (argv[j][1]) {
                case ('c'): mycolors = 1; break;
                case ('p'): sscanf(&argv[j][2],"%d",&mypri); break;
                default: printf("WARNING: unknown option: %s\n",&argv[j][1]);
            }
        }
        else printf("WARNING: unknown option: %s\n",argv[j]);
        j++;
    }
    me = (struct Task *)FindTask(NULL);
    if (me->tc_Node.ln_Pri < mypri) SetTaskPri(me,mypri);

    hook = (long *)0x4L;
    ExBase = (struct ExecBase *)*hook;

    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L))) {
        printf("ERROR: unable to open graphics.library!\n");
        cleanup(0);
    }
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L))) {
        printf("ERROR: unable to open intuition.library!\n");
        cleanup(1);
    }
    NewWindow.FirstGadget = firstgadg;
    if (!(Window = (struct Window *)OpenWindow(&NewWindow))) {
        printf("ERROR: unable to open window!\n");
        cleanup(2);
    }

    if (mycolors) {
        for (j = 0; j < 4; j++)
            tmap[j] = GetRGB4(Window->WScreen->ViewPort.ColorMap,j);
        LoadRGB4(&(Window->WScreen->ViewPort),cmap,4);
    }

    setupwindow();      /* Draw boxes and things */

    gettasks();
    puttasks();
    puttaskdata();
    putmessage("Welcome to AskTask...  (version dated 2/4/89)",1);

    event = 1;
    while (event) {
        Wait(1<<Window->UserPort->mp_SigBit);
        while (msg = (struct IntuiMessage *)GetMsg(Window->UserPort)) {
            m = *msg;
            ReplyMsg((struct Message *)msg);
            switch (m.Class) {
                case (CLOSEWINDOW): event = 0;  break;
                case (RAWKEY): switch (m.Code) {
                    case (0x45): event = 0;     break;  /* ESC */
                    case (0x50): gettasks();            /* F1 */
                                 puttasks();
                                 puttaskdata();
                                 putmessage("[Task data refreshed]",1);
                                 break;
                    case (0x51): puttaskdata(); break;  /* F2 */
                    case (0x54): kill();        break;  /* F5 */
                    case (0x55): rmv();         break;  /* F6 */
                    case (0x56): setsignal();   break;  /* F7 */
                    case (0x57): changepri();   break;  /* F8 */
                    case (0x59): about();       break;  /* F10 */
                    case (0x4c): prevpage();    break;  /* CSR UP */
                    case (0x4d): nextpage();    break;  /* CSR DN */
                    case (0x5f): help();        break;  /* HELP */
                }
                break;
                case (MOUSEBUTTONS):
                    if (m.Code == SELECTDOWN) doclick(m.MouseX,m.MouseY);
                    break;
                case (GADGETUP): gp = (struct Gadget *)msg->IAddress;
                switch (gp->GadgetID) {
                    case (G_QUIT):     event = 0;   break;
                    case (G_HELP):     help();      break;
                    case (G_NEXTPAGE): nextpage();  break;
                    case (G_PREVPAGE): prevpage();  break;
                    case (G_SETSIG):   setsignal(); break;
                    case (G_CHANGE_P): changepri(); break;
                    case (G_REF_TASK): puttaskdata(); break;
                    case (G_EXITTASK): kill();      break;
                    case (G_REMOVE):   rmv();       break;
                    case (G_REFRESH):  gettasks();
                                       puttasks();
                                       puttaskdata();
                                       putmessage("[Task data refreshed]",1);
                                       break;
                }
                break;
                default: putmessage("Unused input!",1);
            }
        }
    }

    cleanup(ENDNORMAL);
}

void    cleanup(n) /*====================================================*/
int     n;
{
    switch (n) {
        case (3): if (mycolors) LoadRGB4(&(Window->WScreen->ViewPort),tmap,4);
                  CloseWindow(Window);
        case (2): CloseLibrary(IntuitionBase);
        case (1): CloseLibrary(GfxBase);
        case (0): break;
        default: printf("Error in cleanup call - parameter = %d\n",n);
    }
    exit(0);
}
