/* at_putdata.c */
/*************************************************************************
 ***                    AskTask PutData Module                         ***
 *** Date begun: 2/4/89.                                               ***
 *** Last modified: 2/4/89.                                            ***
 *************************************************************************/
/*** This contains supplementary display functions cut from asktask.c  ***
 *************************************************************************/

#include "asktask.h"

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

extern void input(struct Window *,char *,char *,char *,int,int,int,int,int);

char    thbuf[21];
char    tlbuf[21];
struct IntuiText    taskhead = {1,0,JAM2,4,11,NULL,&thbuf[0],NULL};
struct IntuiText    taskline = {3,0,JAM1,0,0,NULL,&tlbuf[0],NULL};
char    dhbuf[51];
struct IntuiText    datatask = {3,2,JAM1,218,11,NULL,&dhbuf[0],NULL};
struct IntuiText    datahead = {1,2,JAM1,170,11,NULL,"Task: ",&datatask};

struct IntuiText    msgline = {1,2,JAM1,4,135,NULL,NULL,NULL};
struct IntuiText    notask = {0,3,JAM1,0,0,NULL,"No current task",NULL};

struct IntuiText    datafixd = {1,2,JAM1,170,105,NULL,"E:",NULL};
struct IntuiText    datafixc = {1,2,JAM1,170,97,NULL,"R:",&datafixd};
struct IntuiText    datafixb = {1,2,JAM1,170,89,NULL,"W:",&datafixc};
struct IntuiText    datafixa = {1,2,JAM1,170,81,NULL,"A:",&datafixb};
struct IntuiText    datafix9 = {1,2,JAM1,220,71,NULL,"Signals",&datafixa};
struct IntuiText    datafix8 = {1,2,JAM1,358,65,NULL,"Rm",&datafix9};
struct IntuiText    datafix7 = {1,2,JAM1,358,57,NULL,"Sz",&datafix8};
struct IntuiText    datafix6 = {1,2,JAM1,358,49,NULL,"Up",&datafix7};
struct IntuiText    datafix5 = {1,2,JAM1,358,41,NULL,"Lw",&datafix6};
struct IntuiText    datafix4 = {1,2,JAM1,358,33,NULL,"Rg",&datafix5};
struct IntuiText    datafix3 = {1,2,JAM1,386,23,NULL,"Stack",&datafix4};
struct IntuiText    datafix2 = {1,2,JAM1,170,39,NULL,"Flag:",&datafix3};
struct IntuiText    datafix1 = {1,2,JAM1,170,31,NULL,"State:",&datafix2};
struct IntuiText    datafix = {1,2,JAM1,170,23,NULL,"Priority:",&datafix1};
char    dvbuf[41];
struct IntuiText    datavar = {0,2,JAM1,0,0,NULL,&dvbuf[0],NULL};

char    *anon = "---- Anonymous ----";
char    *state[8] = {
    "TS_INVALID",   "TS_ADDED",     "TS_RUN",       "TS_READY",
    "TS_WAIT",      "TS_EXCEPT",    "TS_REMOVED",   "BEYOND ME!"};
char    *flag[9] = {
    "TB_PROCTIME",  "NOTHING",      "NOTHING",      "NOTHING",
    "TB_STACKCHK",  "TB_EXCEPT",    "TB_SWITCH",    "TB_LAUNCH",
    "BEYOND ME!"};

unsigned long bitsput(char *);          /* Convert bit string to ULONG */
void    putbits(char *,unsigned long);  /* Convert ULONG to bit string */
void    prevpage();                     /* Previous task page */
void    nextpage();                     /* Next task page */
void    puttname(int,int);              /* Put task name n at line y */
void    puttasks();                     /* Display current task page */
void    puttaskdata();                  /* Display current task's data */
void    setupwindow();                  /* Draws boxes and things */
void    putmessage(char *,int);         /* Display a message line */
char    getchfromw();                   /* Get a character from Window */
int     yesno();                        /* Return user's yes or no */

unsigned long bitsput(cp) /*=============================================*/
char    *cp;              /* Converts bit string cp to unsigned long. If */
{                         /* string is too small, the missing bits are   */
unsigned long   r;        /* left as zero.                               */
int     i;
    r = 0;  i = 31;
    while (*cp && (i > -1)) {
        if (*cp == '1') r = r + (1L << i);
        i--;    cp++;
    }
    return(r);
}

void    putbits(cp,l) /*=================================================*/
char    *cp;          /* Converts ULONG l into a 32-bit string cp. Uses  */
unsigned long   l;    /* 33 characters including the zero string ender.  */
{
int     j;
    for (j = 0; j < 32; j++) cp[j] = (l & (1L << (31-j))) ? '1':'0';
    cp[32] = 0;
}

void    prevpage() /*====================================================*/
{                  /* Display previous task page.                        */
    putmessage("",1);
    if (page == 0) {
        putmessage("There's no previous task page!",3);
        return;
    }
    page--;
    puttasks();
}

void    nextpage() /*====================================================*/
{                  /* Display next task page                             */
    putmessage("",1);
    if (numtasks <= (page + 1)*14) {
        putmessage("There's no next task page!",3);
        return;
    }
    page++;
    puttasks();
}

void    puttname(n,y) /*=================================================*/
int     n,y;
{
    if (tnp[n][0]) sprintf(tlbuf,"%-.20s",tnp[n]);
    else strcpy(tlbuf,anon);
    PrintIText(Window->RPort,&taskline,4,21+y*8);
}

void    puttasks() /*====================================================*/
{                  /* Write the current page of task names */
int     i,j;
    putmessage("",1);
    while (numtasks < page * 14) page--;
    sprintf(thbuf," Task    (page %.1d/%.1d) ",1 + page,1 + (numtasks-1)/14);
    PrintIText(Window->RPort,&taskhead,0,0);
    SetAPen(Window->RPort,0);
    RectFill(Window->RPort,4,21,165,132);
    j = page * 14;  i = 0;
    while ((j < numtasks) && (i < 14)) {
        puttname(j,i);
        i++; j++;
    }
}

void    puttaskdata() /*=================================================*/
{                     /* Display the current task's data                 */
int     s;
long    stack[3];
unsigned long   sigs[4];
    putmessage("",1);
    if (ct < 0) {
        SetAPen(Window->RPort,1);
        RectFill(Window->RPort,168,10,471,132);
        SetAPen(Window->RPort,2);
        RectFill(Window->RPort,176,14,463,128);
        SetAPen(Window->RPort,3);
        RectFill(Window->RPort,289,22,350,120);
        RectFill(Window->RPort,229,52,410,80);
        PrintIText(Window->RPort,&notask,260,62);
        return;
    }
    SetAPen(Window->RPort,2);
    RectFill(Window->RPort,168,10,471,132);
    SetAPen(Window->RPort,1);
    Move(Window->RPort,170,19);     Draw(Window->RPort,469,19);
    if (tnp[ct][0]) strcpy(dhbuf,tnp[ct]);
    else strcpy(dhbuf,anon);
    PrintIText(Window->RPort,&datahead,0,0);
    PrintIText(Window->RPort,&datafix,0,0);
    Move(Window->RPort,376,31);
    Draw(Window->RPort,444,31); Draw(Window->RPort,444,73);
    Draw(Window->RPort,376,73); Draw(Window->RPort,376,31);
    Move(Window->RPort,375,31); Draw(Window->RPort,375,73);
    Move(Window->RPort,445,31); Draw(Window->RPort,445,73);
    Move(Window->RPort,188,79);
    Draw(Window->RPort,448,79);     Draw(Window->RPort,448,113);
    Draw(Window->RPort,188,113);    Draw(Window->RPort,188,79);
    Move(Window->RPort,187,79);     Draw(Window->RPort,187,113);
    Move(Window->RPort,449,79);     Draw(Window->RPort,449,113);
    s = (int)task[ct]->tc_Node.ln_Pri;
    sprintf(dvbuf,"%3d",s); PrintIText(Window->RPort,&datavar,250,23);
    s = (int)task[ct]->tc_State;
    if ((s < 0) || (s > 7)) s = 7;
    strcpy(dvbuf,state[s]); PrintIText(Window->RPort,&datavar,226,31);
    s = (int)task[ct]->tc_Flags;
    if ((s < 0) || ( s > 8)) s = 8;
    strcpy(dvbuf,flag[s]); PrintIText(Window->RPort,&datavar,226,39);
    SetAPen(Window->RPort,0);
    RectFill(Window->RPort,377,32,443,72);
    if (tnp[ct][0]) {
        datavar.FrontPen = 2;
        Disable();
        stack[0] = (long)(task[ct]->tc_SPReg);
        stack[1] = (long)(task[ct]->tc_SPLower);
        stack[2] = (long)(task[ct]->tc_SPUpper);
        Enable();
        sprintf(dvbuf,"%08lx",stack[0]);
        PrintIText(Window->RPort,&datavar,378,33);
        sprintf(dvbuf,"%08lx",stack[1]);
        PrintIText(Window->RPort,&datavar,378,41);
        sprintf(dvbuf,"%08lx",stack[2]);
        PrintIText(Window->RPort,&datavar,378,49);
        sprintf(dvbuf,"%08lx",stack[2]-stack[1]);
        PrintIText(Window->RPort,&datavar,378,57);
        sprintf(dvbuf,"%08lx",stack[0]-stack[1]);
        PrintIText(Window->RPort,&datavar,378,65);
        datavar.FrontPen = 0;
    }
    Disable();
    sigs[0] = task[ct]->tc_SigAlloc;    sigs[1] = task[ct]->tc_SigWait;
    sigs[2] = task[ct]->tc_SigRecvd;    sigs[3] = task[ct]->tc_SigExcept;
    Enable();
    putbits(dvbuf,sigs[0]);     PrintIText(Window->RPort,&datavar,190,81);
    putbits(dvbuf,sigs[1]);     PrintIText(Window->RPort,&datavar,190,89);
    putbits(dvbuf,sigs[2]);     PrintIText(Window->RPort,&datavar,190,97);
    putbits(dvbuf,sigs[3]);     PrintIText(Window->RPort,&datavar,190,105);
}

void    setupwindow() /*=================================================*/
{                     /* Draw boxes and things.                          */
    SetAPen(Window->RPort,1);
    Move(Window->RPort,166,10);     Draw(Window->RPort,166,132);
    Move(Window->RPort,167,10);     Draw(Window->RPort,167,132);
    Move(Window->RPort,472,10);     Draw(Window->RPort,472,132);
    Move(Window->RPort,473,10);     Draw(Window->RPort,473,132);
    PrintIText(Window->RPort,&taskhead,0,0);
    Move(Window->RPort,4,19);       Draw(Window->RPort,163,19);
    Move(Window->RPort,2,133);      Draw(Window->RPort,637,133);
    SetAPen(Window->RPort,2);
    RectFill(Window->RPort,2,134,636,143);
}

void    putmessage(cp,c) /*==============================================*/
char    *cp;             /* Display a message line cp, in color c.       */
int     c;
{
    SetAPen(Window->RPort,2);
    RectFill(Window->RPort,4,135,636,142);
    msgline.IText = cp;
    msgline.FrontPen = (UBYTE)c;
    PrintIText(Window->RPort,&msgline,0,0);
}

char    getchfromw() /*==================================================*/
{                    /* Return a character from the Window.              */
struct IntuiMessage *msg;
int     loop;
char    ch;
    loop = 1;
    while (loop) {
        Wait(1<<Window->UserPort->mp_SigBit);
        while (msg = (struct IntuiMessage *)GetMsg(Window->UserPort)) {
            if (msg->Class != RAWKEY) {
                ReplyMsg((struct Message *)msg);
                continue;
            }
            ch = (char)msg->Code;   loop = 0;
            ReplyMsg((struct Message *)msg);
        }
    }
    return(ch);
}

int     yesno() /*=======================================================*/
{               /* Get a y/n answer from the window.                     */
char    ch;
    while (1) {
        ch = getchfromw();
        if ((ch == 0x15)||(ch == 0x36)||(ch == 0x45)) break;
    }
    return((ch == 0x15)? 1:0);
}
