#include "Tasks.h"

/*   Start of Local Function Prototypes */

/* Breakpoint handling will be in the way of very lowlevel
   when a breakpoint is inserted, the old instruction is 
   removed and replaced by either something illegal or a 
   trap instruction, and in the trap instruction is a not
   so lowlevel msgport thing, that updates the main system
   monitor.
*/

/*   End of Local Function Prototypes */

struct TaskNode
{
    struct Node tn_Node;
    UBYTE tn_Name[33];
};


void Tasks_Display( void)
{     
  struct List     *ourtasklist;
  struct List     *exectasklist;
  struct TaskNode *node, *tnode;
  struct Task     *Plain_Task;
  struct Node     *execnode;
 
 
  if(ourtasklist = AllocMem(sizeof(struct List),MEMF_CLEAR))
      { 

          ourtasklist->lh_Head = (struct Node *)&ourtasklist->lh_Tail;
          ourtasklist->lh_Tail = 0;
          ourtasklist->lh_TailPred = (struct Node *)&ourtasklist->lh_Head;
     
          Disable();
        
          exectasklist = &(SysBase->TaskWait);
          for(execnode = exectasklist->lh_Head;  execnode->ln_Succ; execnode = execnode->ln_Succ)
              {
                 if(tnode = AllocMem(sizeof(struct TaskNode), MEMF_CLEAR))
                    {
                      strncpy(tnode->tn_Name, execnode->ln_Name, 32);
                      AddTail(ourtasklist, (struct Node *)tnode);
                     }  
                      else 
                     {
                       // Some Smart Error Routine Here
                          break;
                     }
              }
      
          exectasklist = &(SysBase->TaskReady);
          for(execnode = exectasklist->lh_Head; execnode->ln_Succ; execnode = execnode->ln_Succ)
              {
                  if(tnode = AllocMem(sizeof(struct TaskNode),MEMF_CLEAR))
                     {
                      strncpy(tnode->tn_Name, execnode->ln_Name,32);
                      AddTail(ourtasklist, (struct Node *)tnode);
                     }
                      else 
                     {
                       // Some Smart Error Routine here
                          break;
                     }
              }
             
          exectasklist = &(SysBase->IntrList);
          for(execnode = exectasklist->lh_Head; execnode->ln_Succ; execnode = execnode->ln_Succ)
              {
                Plain_Task = (struct Task *)execnode;
                if(Plain_Task->tc_State==8)
                  {
                    if(tnode = AllocMem(sizeof(struct TaskNode),MEMF_CLEAR))
                       {
                        strncpy(tnode->tn_Name, execnode->ln_Name,32);
                        AddTail(ourtasklist, (struct Node *)tnode);
                       }
                        else 
                       {
                          // Some Smart Error Routine here
                            break;
                       }
                  }
              }
   
             
        Enable();
        
        node = (struct TaskNode *)(ourtasklist->lh_Head);
        while (tnode = (struct TaskNode *)node->tn_Node.ln_Succ)
            {
            
             Print_Tasks(node->tn_Name);                      // This Is The Actuall Routine That Outputs
             FreeMem(node,sizeof(struct TaskNode));
             node = tnode;       
            }   
            FreeMem(ourtasklist, sizeof(struct List));           

      }
      else
       {
        // Some Smart Error Routine here
        }
}


void Terminate_Task( void )
{
       APTR  **Message;
       struct Task *Selected_Task;
       struct List     *ourtasklist;
       struct List     *exectasklist;
       struct TaskNode *node, *tnode;
       struct Node     *execnode;
 
       
       int  Active_One;
       int  User_In=0;

       DoMethod(App->MainWindow_Task_List,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&Message);
       if(Message)
          {
            User_In = MUI_Request(App->App,App->Main_Window,0,"Remove Task","*_Remove|_Freeze|_Abort","\33cAre You Sure To Terminate: \n\33c\33b %s",(UBYTE *)Message[1]);
            switch(User_In)
              {
                 case 1:		// Terminate Task!
               
                /* 
                  1) Remove Any Interrupts That Task May Have Started
                  2) Warn Of Any Child Tasks The Task May Have Started
                  3) Remove Any Portsor Rights To Semaphores That The Task May Have
                  4) Free Any Locks The Task Might Have
                  5) Find And Close Any Windows/Screens The Task May Have Had
                  6) Find And PutAway Any AppIcons The Task May Have Had
                  7) Find And Quit Any Commoditys The Task May Have Started
                  8) Remove The Task
                */
                  
                     Selected_Task = FindTask((UBYTE *)Message[1]);
                     RemTask(Selected_Task);
                     get(App->MainWindow_Task_List,MUIA_List_Active,&Active_One);
                     DoMethod(App->MainWindow_Task_List,MUIM_List_Clear);
                     set(App->MainWindow_Task_List,MUIA_List_Quiet,TRUE);
                     Tasks_Display();
                     set(App->MainWindow_Task_List,MUIA_List_Quiet,FALSE);
                     set(App->MainWindow_Task_List,MUIA_List_Active,&Active_One);
                   break;
                                    
                 case 2:		// Freeze Task!
                     exectasklist = &(SysBase->TaskWait);                            
                            Selected_Task  =(struct Task *) FindName(exectasklist,(UBYTE *)Message[1]);
                            if(Selected_Task)
                             {
                               
                                get(App->MainWindow_Task_List,MUIA_List_Active,&Active_One);
                                DoMethod(App->MainWindow_Task_List,MUIM_List_Clear);
                                set(App->MainWindow_Task_List,MUIA_List_Quiet,TRUE);
                                Remove((struct Node *)Selected_Task);
                                AddTail(&(SysBase->IntrList),(struct Node *)Selected_Task);
                                Tasks_Display();
                                set(App->MainWindow_Task_List,MUIA_List_Quiet,FALSE);
                                set(App->MainWindow_Task_List,MUIA_List_Active,&Active_One);
                                Selected_Task->tc_State=8;
                                Selected_Task->tc_Flags=0;
                                break;
                            }
                            else
                            {
                                printf("Unable To Lock The Task: %s\n",(UBYTE *)Message[1]);
                            }
                     
                   break;
                                    
                 case 3:               // Abort Action!
                  
                    break;
              }
          }
         else
          {
            printf("No Entrys Selected!\n");
          }
}

void Information_Task( void )
{   APTR **Message;
    char *Buffer;
    char *T_Buffer;
    int x=300;
    // extern struct LIBRARY *IntuitionBase;
    extern __asm __saveds Dissassemble( register __a1 char *, register __a0 APTR);
    struct Process *Selected_Task;
    DoMethod(App->MainWindow_Task_List,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&Message);
    if(Message)
     {
      set(App->Task_Info_Window,MUIA_Window_Open,TRUE);
      set(App->MainWindow_Task_StatusBar,MUIA_Text_Contents,(UBYTE *)Message[1]);
      Buffer = AllocMem(2000,MEMF_ANY);
      T_Buffer = AllocMem(200,MEMF_ANY);
      if(Buffer)
       {
        Selected_Task = (struct Process *)FindTask((UBYTE *)Message[1]);
        sprintf(Buffer,"\33b\33uTask Structure\33n\n");
        sprintf(T_Buffer,"Address    : $%08lx \nName       : \33b%s\33n\n",&Selected_Task->pr_Task.tc_Node,Selected_Task->pr_Task.tc_Node.ln_Name);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"IDNestCnt  : $%08lx \nTDNestCnt  : $%08lx\n",Selected_Task->pr_Task.tc_IDNestCnt,Selected_Task->pr_Task.tc_TDNestCnt);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"SigAlloc   : $%08lx \nSigWait    : $%08lx\n",Selected_Task->pr_Task.tc_SigAlloc,Selected_Task->pr_Task.tc_SigWait);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"SigRecvd   : $%08lx \nSigExcept  : $%08lx\n",Selected_Task->pr_Task.tc_SigRecvd,Selected_Task->pr_Task.tc_SigExcept);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"Trap Alloc : $%08lx \nTrapAble   : $%08lx\n",Selected_Task->pr_Task.tc_TrapAlloc,Selected_Task->pr_Task.tc_TrapAble);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"ExceptData : $%08lx \nExceptCode : $%08lx\n",Selected_Task->pr_Task.tc_ExceptData,Selected_Task->pr_Task.tc_ExceptCode);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"TrapData   : $%08lx \nTrapCode   : $%08lx\n",Selected_Task->pr_Task.tc_TrapData,Selected_Task->pr_Task.tc_TrapCode);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"SPReg      : $%08lx \nSPLower    : $%08lx\n",Selected_Task->pr_Task.tc_SPReg,Selected_Task->pr_Task.tc_SPLower);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"SPUpper    : $%08lx \nSwitch     : $%08lx\n",Selected_Task->pr_Task.tc_SPUpper,Selected_Task->pr_Task.tc_Switch);
        strcat(Buffer,T_Buffer);
        sprintf(T_Buffer,"Launch     : $%08lx \nUserData   : $%08lx\n",Selected_Task->pr_Task.tc_Launch,Selected_Task->pr_Task.tc_UserData);
        strcat(Buffer,T_Buffer);
        if(Selected_Task->pr_Task.tc_Node.ln_Type==13)
          {
            sprintf(T_Buffer,"\n\33b\33uProcess Structure\33n\n");
            strcat(Buffer,T_Buffer);
            sprintf(T_Buffer,"MsgPort    : $%08lx \nSegList   : $%08lx\n",&Selected_Task->pr_MsgPort,&Selected_Task->pr_SegList);
            strcat(Buffer,T_Buffer);
          }
          
       while(x!=0)
        {
        Dissassemble(T_Buffer,(APTR)x);    
        strcat(Buffer,T_Buffer);
        strcat(Buffer,"\n");
        x=x-4;
       }
        set(App->TaskInfo_Struct_List,MUIA_Floattext_Text,Buffer);
       
        FreeMem(Buffer,2000);
        FreeMem(T_Buffer,200);
       }
     }
     
     // printf("The Task Owning The Window Is At %p\n",IntuitionBase->ActiveWindow.UserPort.mp_SigTask);
}


void Handle_Task_Input( int Main_Message)
{
    
    switch(Main_Message)
            {
                case TaskInfo_SaveTask:
                       printf("Cray-1 Was Here\n");
                     break;
                     
            }
            
            
}