/**
 * Scout - The Amiga System Monitor
 *
 *------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * You must not use this source code to gain profit of any kind!
 *
 *------------------------------------------------------------------
 *
 * @author Andreas Gelhausen
 * @author Richard Körber <rkoerber@gmx.de>
 */



#include "system_headers.h"

static char alcnonalc[] = "<free>";
static char alcunknown[] = "<allocated>";
static char alcnotavail[] = "<not available>";

static ULONG __asm __saveds __interrupt DummyIntFunc( void )
{
    return 0;
}

static char * AlcMiscUser(ULONG unit)
{
  struct Library *MiscBase;
  char * name;

  if(!(MiscBase = OpenResource(MISCNAME))) return(alcnotavail);

  if(!(name = AllocMiscResource(unit,"Scout")))
    FreeMiscResource(unit);
  return(name ? name : alcnonalc);
}

static char * AlcCiaAUser(WORD unit)
{
  struct Library *CiaBase;
  struct Interrupt DummyInt, *intr;
  char * name;

  if(!(CiaBase = OpenResource(CIAANAME))) return(alcnotavail);

  memset(&DummyInt, 0x00, sizeof(struct Interrupt));
  DummyInt.is_Node.ln_Type = NT_INTERRUPT;
  DummyInt.is_Node.ln_Pri = -127;
  DummyInt.is_Node.ln_Name = "« Scout's Dummy Int »";
  DummyInt.is_Code = (void (*)())DummyIntFunc;
  Disable();
  if(!(intr = AddICRVector(CiaBase, unit, &DummyInt))) {
    RemICRVector(CiaBase, unit, &DummyInt);
    Enable();
    return(alcnonalc);
  }
  Enable();
  name = intr->is_Node.ln_Name;
  return(name ? name : alcunknown);
}

static char * AlcCiaBUser(WORD unit)
{
  struct Library *CiaBase;
  struct Interrupt DummyInt, *intr;
  char * name;

  if(!(CiaBase = OpenResource(CIABNAME))) return(alcnotavail);

  memset(&DummyInt, 0x00, sizeof(struct Interrupt));
  DummyInt.is_Node.ln_Type = NT_INTERRUPT;
  DummyInt.is_Node.ln_Pri = -127;
  DummyInt.is_Node.ln_Name = "« Scout's Dummy Int »";
  DummyInt.is_Code = (void (*)())DummyIntFunc;
  Disable();
  if(!(intr = AddICRVector(CiaBase, unit, &DummyInt))) {
    RemICRVector(CiaBase, unit, &DummyInt);
    Enable();
    return(alcnonalc);
  }
  Enable();
  name = intr->is_Node.ln_Name;
  return(name ? name : alcunknown);
}


void PrintAllocations (char *filename) {
   BPTR  handle;

   handle = HandlePrintStart (filename);
   if (handle) {
      if (clientstate) {
         char  tmpbuffer[256];

         if (SendDaemon ("Allocations")) {
            while ((sgets (client_socket, tmpbuffer, 256)) \
              && (strcmp (tmpbuffer, CMD_DONE)) \
              && (strcmp (tmpbuffer, CMD_ERROR))) {
               PrintOneLine (handle, tmpbuffer);
            }
         }
      } else {
         if (PrintOneLine (handle, "\nCIA A:\n\n")) {
            _sprintf(tmpstr2, "Timer A: %s\nTimer B: %s\n  Alarm: %s\n Serial: %s\n   Flag: %s",AlcCiaAUser(0),AlcCiaAUser(1),AlcCiaAUser(2),AlcCiaAUser(3),AlcCiaAUser(4));
            PrintOneLine (handle, tmpstr2);

            PrintOneLine (handle, "\n\n\nCIA B:\n\n");
            _sprintf(tmpstr2, "Timer A: %s\nTimer B: %s\n  Alarm: %s\n Serial: %s\n   Flag: %s",AlcCiaBUser(0),AlcCiaBUser(1),AlcCiaBUser(2),AlcCiaBUser(3),AlcCiaBUser(4));
            PrintOneLine (handle, tmpstr2);

            PrintOneLine (handle, "\n\n\nSerial & Parallel Ports:\n\n");
            _sprintf(tmpstr2, "     Serial Port: %s\n  Serial Control: %s\n   Parallel Port: %s\nParallel Control: %s",AlcMiscUser(MR_SERIALPORT),AlcMiscUser(MR_SERIALBITS),AlcMiscUser(MR_PARALLELPORT),AlcMiscUser(MR_PARALLELBITS));
            PrintOneLine (handle, tmpstr2);
         }
      }
   }
   HandlePrintStop();
}

void GetAllocations (void) {
   if (clientstate) {
      char  tmpbuffer[256];

      if (SendDaemon ("GetAlcList")) {
         if (sgets (client_socket, tmpbuffer, 256)) {
            MySetContents (alctext1, tmpbuffer);
            if (sgets (client_socket, tmpbuffer, 256)) {
               MySetContents (alctext2, tmpbuffer);
               if (sgets (client_socket, tmpbuffer, 256)) {
                  MySetContents (alctext3, tmpbuffer);
                  if (sgets (client_socket, tmpbuffer, 256)) {
                     strcmp (tmpbuffer, CMD_DONE);
                  }
               }
            }
         }
      }
   } else {
      Forbid();
      MySetContents (alctext1, "%s\n%s\n%s\n%s\n%s",AlcCiaAUser(0),AlcCiaAUser(1),AlcCiaAUser(2),AlcCiaAUser(3),AlcCiaAUser(4));
      MySetContents (alctext2, "%s\n%s\n%s\n%s\n%s",AlcCiaBUser(0),AlcCiaBUser(1),AlcCiaBUser(2),AlcCiaBUser(3),AlcCiaBUser(4));
      MySetContents (alctext3, "%s\n%s\n%s\n%s",AlcMiscUser(MR_SERIALPORT),AlcMiscUser(MR_SERIALBITS),AlcMiscUser(MR_PARALLELPORT),AlcMiscUser(MR_PARALLELBITS));
      Permit();
   }
}

void SendAlcList (void) {
   SendClient (ESC "r%s\n%s\n%s\n%s\n%s",AlcCiaAUser(0),AlcCiaAUser(1),AlcCiaAUser(2),AlcCiaAUser(3),AlcCiaAUser(4));
   SendClient (ESC "r%s\n%s\n%s\n%s\n%s",AlcCiaBUser(0),AlcCiaBUser(1),AlcCiaBUser(2),AlcCiaBUser(3),AlcCiaBUser(4));
   SendClient (ESC "r%s\n%s\n%s\n%s",AlcMiscUser(MR_SERIALPORT),AlcMiscUser(MR_SERIALBITS),AlcMiscUser(MR_PARALLELPORT),AlcMiscUser(MR_PARALLELBITS));
}


char allocations_title[WINDOWTITLELEN];
static char *AllocationsPages[] = { "CIA","Ports",NULL };

void AllocationsWindow (BOOL state) {
   if (state) {
      if (WI_Allocations) {
         GetAllocations();
      } else {
         WI_Allocations = WindowObject,
         MUIA_Window_Title, MyGetWindowTitle (allocations_title, "ALLOCATIONS"),
         MUIA_HelpNode, AllocationsText,
         MUIA_Window_ID, MakeListID('A','L','L','C'),
         WindowContents, VGroup,

            Child, RegisterGroup(AllocationsPages),

               Child, HGroup,
                  Child, HGroup,
                     GroupFrameT("CIA A"),
                     Child, HGroup,
                        Child, MyLabel2 (ESC "rTimer A:\nTimer B:\nAlarm:\nSerial:\nFlag:"),
                        Child, alctext1 = MyTextObject(),
                     End,
                  End,

                  Child, HGroup,
                     GroupFrameT("CIA B"),
                     Child, HGroup,
                        Child, MyLabel2 (ESC "rTimer A:\nTimer B:\nAlarm:\nSerial:\nFlag:"),
                        Child, alctext2 = MyTextObject(),
                     End,
                  End,
               End,

               Child, HGroup,
                  GroupFrameT("Ports"),
                  Child, HGroup,
                     Child, MyLabel2 (ESC "rSerial Port:\nSerial Control:\nParallel Port:\nParallel Control:"),
                     Child, alctext3 = MyTextObject(),
                  End,
               End,
            End,

#ifndef WINDOW_PROBLEMS
            Child, MyVSpace(4),
#endif
            Child, HGroup, MUIA_Group_SameSize, TRUE,
               Child, BT_AlcUpdate = KeyButtonA (UpdateText,ID_ALCUPDATE),
               Child, BT_AlcPrint  = KeyButtonA (PrintText ,ID_ALCPRINT),
               Child, BT_AlcExit   = KeyButtonA (ExitText  ,ID_ALCEXIT),
            End,
         End, End;

         DoMethod (AP_Scout,OM_ADDMEMBER,WI_Allocations);
         DoMethod (WI_Allocations,MUIM_Window_SetCycleChain,BT_AlcUpdate,BT_AlcPrint,BT_AlcExit,NULL);
         SetCloseRequest (WI_Allocations,ID_ALCEXIT);

         GetAllocations();

         SetWindowOpen (WI_Allocations,NULL,ID_ALCEXIT);
      }
   } else if ((! state) && (WI_Allocations)) {
      SetWindowClose (WI_Allocations,TRUE);

//      FreeAllocations();

      DoMethod (AP_Scout,OM_REMMEMBER,WI_Allocations);
      MUI_DisposeObject (WI_Allocations);
      WI_Allocations = NULL;
   }
}

