#include "Control_Include.h"
#include "Cray_Protos.c"

struct TaskNode
{
    struct Node tn_Node;
    ULONG tn_TaskAddress;
    ULONG tn_SigAlloc;
    ULONG tn_SigWait;
    ULONG tn_Flags;
    ULONG tn_State;
    UBYTE tn_Name[33];
};

void Tasks_Display( void)
{           //     |                                |   |         |         |
   char  Header[]="State Task Name                     Flags  SigAlloc  SigWait Address";
  struct List     *ourtasklist;
  struct List     *exectasklist;
  struct Task     *task;
  struct TaskNode *node, *tnode, *rnode = NULL;
  struct Node *execnode;
  char   *buffer;
  buffer = AllocRemember(&General_Memory,200,MEMF_CLEAR);
  if(!buffer)Problem("Failed To Allocate Enough Memory For A 200 byte Buffer",0);
 /* Allocate Memory For Our List */
 
  if(ourtasklist = AllocMem(sizeof(struct List),MEMF_CLEAR))
     { /* Initialise List Structure AlA NewList() */
        ourtasklist->lh_Head = (struct Node *)&ourtasklist->lh_Tail;
        ourtasklist->lh_Tail = 0;
        ourtasklist->lh_TailPred = (struct Node *)&ourtasklist->lh_Head;
        
        /* Make Sure Tasks Wont Switch Lists or Go Away */
        Disable();
        
        /* Snapshot Task WAIT List */
        exectasklist = &(SysBase->TaskWait);
        for(execnode = exectasklist->lh_Head; 
               execnode->ln_Succ; execnode = execnode->ln_Succ)
            {
                if(tnode = AllocMem(sizeof(struct TaskNode), MEMF_CLEAR))
                   {
                    /* Save Task Information We Want To Print */
                    strncpy(tnode->tn_Name, execnode->ln_Name, 32);
                    tnode->tn_Node.ln_Pri = execnode->ln_Pri;
                    tnode->tn_TaskAddress = (ULONG)execnode;
                    tnode->tn_Flags = ((struct Task *)execnode)->tc_Flags;
                    tnode->tn_State = ((struct Task *)execnode)->tc_State;
                    tnode->tn_SigAlloc = ((struct Task *)execnode)->tc_SigAlloc;
                    tnode->tn_SigWait = ((struct Task *)execnode)->tc_SigWait;
                    AddTail(ourtasklist, (struct Node *)tnode);
                   }  
                else 
                  {
                    Problem("Failed To Allocate Enough memory For A NOde",0);
                    break;
                  }
            }
        /* Snapshot Task READY List */
        exectasklist = &(SysBase->TaskReady);
        for(execnode = exectasklist->lh_Head; 
                execnode->ln_Succ; execnode = execnode->ln_Succ)
             {
                if(tnode = AllocMem(sizeof(struct TaskNode),MEMF_CLEAR))
                   {
                    /* Save Task Information We Want To Print */
                    strncpy(tnode->tn_Name, execnode->ln_Name,32);
                    tnode->tn_Node.ln_Pri = execnode->ln_Pri;
                    tnode->tn_TaskAddress = (ULONG) execnode;
                    tnode->tn_Flags = ((struct Task *)execnode)->tc_Flags;
                    tnode->tn_State = ((struct Task *)execnode)->tc_State;
                    tnode->tn_SigAlloc = ((struct Task *)execnode)->tc_SigAlloc;
                    tnode->tn_SigWait = ((struct Task *)execnode)->tc_SigWait;
                    AddTail(ourtasklist, (struct Node *)tnode);
                    if(!rnode) rnode = tnode; /* First Ready Task */
                   }
                 else 
                 {
                    Problem("Failed To Allocate Enough Memory For A Node",0);
                     break;
                    }
             }
             
             /* Re-Enable Interrupts and taskSwitching */
        Enable();
        
        GT_SetGadgetAttrs(ControlGadgets[GD_HEADERS],ControlWnd,NULL,
                         GTTX_Text, &Header,TAG_END);
        //Print_Routine("",0);
        
        node = (struct TaskNode *)(ourtasklist->lh_Head);
        
        
        while (tnode = (struct TaskNode *)node->tn_Node.ln_Succ)
            {
                if(tnode == rnode)
                   {
                   }
         //       tnode->tn_Flags = ((struct Task *)execnode)->tc_Flags;
        //        tnode->tn_State = ((struct Task *)execnode)->tc_State;
       //         State  Task Name Flags  Priority SigAlloc  SigWait Address";
       sprintf(buffer,"$%08lx   %s     $%08lx  $%08lx %d",
       node->tn_TaskAddress, Space( node->tn_Name, 32),
       node->tn_SigAlloc,node->tn_SigWait,node->tn_Node.ln_Pri);
                  
                   Print_Routine(buffer,0);
                   
               
                     FreeMem(node,sizeof(struct TaskNode));
                    node = tnode;
                    
                    
            }
           
            FreeMem(ourtasklist, sizeof(struct List));
            task = FindTask(NULL);
            //sprintf(buffer,"%s     %d   $%07lx  $%08lx  $%08lx <<<<- This Task!",
            //Space( task->tc_Node.ln_Name, 32),task->tc_Node.ln_Pri, task, task->tc_SigAlloc,
            //task->tc_SigWait);         
            //Print_Routine(buffer,0);
            
      }
      else
      {
        Problem("Failed To Allocate The Memory Required For The List",0);
       }
}

char * Space( char *CName, int length)
{
     int stringlen;
     char *New_Chars;
     New_Chars = AllocRemember(&General_Memory,length+2,MEMF_CLEAR);
     if(!New_Chars)Problem("Could Not Allocate Enough Memory For The Space Function",0);
     strcpy(New_Chars,CName);
     stringlen = strlen(New_Chars);
     while(stringlen<=length)
           {
             New_Chars[stringlen]=' ';
             stringlen++;
           }
     New_Chars[length]=00;                                            
     return(New_Chars);
}