/*
  InfoBar.c - by Rj Schack.
  Placed in the public domain.

  07 November 91 - v0.01 - Initial and final release.

  SAS/C (5.10b):
    LC -cfist -O InfoBar.c

  BLink (5.10b):
    FROM LIB:cback.o+InfoBar.o TO InfoBar LIB LIB:lc.lib LIB:amiga.lib 
     DEFINE __main=__tinymain SC SD ND
*/

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/dos.h>

/********************** DEFINES AND TYPEDEFS ***********************/

#define RPort IBWindow->RPort

#define Prototype
typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned char text;

/********************* PROTOTYPES AND MACROS ***********************/

Prototype int  CXBRK(void);
int CXBRK() { return(0); }

Prototype void CleanExit(void);
Prototype void Initialize(void);
Prototype int  main(int, text *[]);
Prototype void MainLoop(void);

/**************** DATA STRUCTURES AND GLOBAL DATA ******************/

long _stack = 2048L;
char *_procname = "InfoBar";
long _priority = 0;
long _BackGroundIO = 1;
extern BPTR _Backstdout;

struct NewWindow IBWindowType =
{
  2, 1, 514, 10, 2, 1, MENUPICK,
  SMART_REFRESH|BACKDROP|BORDERLESS,
  NULL, NULL, NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, WBENCHSCREEN
};

struct IntuiText QuitText =
{
  2, 1, JAM2, 2, 1, NULL, " Quit", NULL
};

struct MenuItem QuitMenu =
{
  NULL, 0, 0, 65, 10, ITEMTEXT|ITEMENABLED|HIGHCOMP,
  0, (APTR) &QuitText, NULL, NULL, NULL, MENUNULL
};

struct Menu ProjectMenu =
{
  NULL, 0, 0, 65, 0, MENUENABLED, "Project", &QuitMenu
};

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase = NULL;
struct Window        *IBWindow = NULL;

/*************************** MAIN BODY *****************************/

int main(argc, argv)
int argc;
text *argv[];
{
  Initialize();
  MainLoop();
  CleanExit();
}

void Initialize()
{
  if (!(IntuitionBase = (struct IntuitionBase *)
   OpenLibrary("intuition.library", 0)))
  {
    if (_Backstdout)
      Write(_Backstdout, "Couldn't open intuition.library.", 32);
    CleanExit();
  }

  if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0)))
  {
    if (_Backstdout)
      Write(_Backstdout, "Couldn't open graphics.library.", 31);
    CleanExit();
  }

  if (!(IBWindow = (struct Window *) OpenWindow(&IBWindowType)))
  {
    if (_Backstdout)
      Write(_Backstdout, "Couldn't open window.", 21);
    CleanExit();
  }

  SetAPen(RPort, 1); RectFill(RPort, 0, 0, 614, 10);
  SetAPen(RPort, 0); SetBPen(RPort, 1);
  Move(RPort, 121, 7); Text(RPort, "DATE:", 5);
  Move(RPort, 225, 7); Text(RPort, "CHIP:", 5);
  Move(RPort, 327, 7); Text(RPort, "RAM:", 4);
  Move(RPort, 423, 7); Text(RPort, "TIME:", 5);
  SetMenuStrip(IBWindow, &ProjectMenu);
  ShowTitle(IBWindow->WScreen, FALSE);
  SetAPen(RPort, 2);

  if (_Backstdout)
    Close(_Backstdout);
}

void MainLoop()
{
  struct IntuiMessage *IntMsg;
  uchar DateStr[6], ChipStr[8], RAMStr[8], TimeStr[6], toggle = 1;
  uchar Clock[8], PDay = 0;
  ulong Chip, RAM, PChip = 0, PRAM = 0;

  while (1)
  {
    if (IntMsg = (struct IntuiMessage *) GetMsg(IBWindow->UserPort))
    {
      if (IntMsg->Code != MENUNULL)
      {
        ReplyMsg((struct Message *) IntMsg);
        break;
      }
    }

    Chip = AvailMem(MEMF_CHIP);
    RAM = AvailMem(MEMF_FAST) + Chip;

    if (Chip != PChip)
    {
      stcl_d(ChipStr, Chip);

      if (Chip > 1000000)
      { ChipStr[4] = 'k'; ChipStr[5] = 0x00; }
      else
      if (Chip > 100000)
      { ChipStr[3] = 'k'; ChipStr[4] = 0x00; strins(ChipStr, " "); }
      else
      if (Chip > 10000)
      { ChipStr[2] = 'k'; ChipStr[3] = 0x00; strins(ChipStr, "  "); }
      else
      if (Chip > 1000)
      { ChipStr[1] = 'k'; ChipStr[2] = 0x00; strins(ChipStr, "   "); }
      else
        strcpy(ChipStr, "  <1k");

      Move(RPort, 271, 7);
      Text(RPort, ChipStr, 5);
      PChip = Chip;
    }

    if (RAM != PRAM)
    {
      stcl_d(RAMStr, RAM);

      if (RAM > 1000000)
      { RAMStr[4] = 'k'; RAMStr[5] = 0x00; }
      else
      if (RAM > 100000)
      { RAMStr[3] = 'k'; RAMStr[4] = 0x00; strins(RAMStr, " "); }
      else
      if (RAM > 10000)
      { RAMStr[2] = 'k'; RAMStr[3] = 0x00; strins(RAMStr, "  "); }
      else
      if (RAM > 1000)
      { RAMStr[1] = 'k'; RAMStr[2] = 0x00; strins(RAMStr, "   "); }
      else
        strcpy(RAMStr, "  <1k");

      Move(RPort, 367, 7);
      Text(RPort, RAMStr, 5);
      PRAM = RAM;
    }

    if (toggle)
    {
      getclk(&Clock[0]);

      if (Clock[3] != PDay)
      {
        sprintf(DateStr, "%02d/%02d", Clock[2], Clock[3]);
        Move(RPort, 169, 7);
        Text(RPort, DateStr, 5);
        PDay = Clock[3];
      }

      sprintf(TimeStr, "%02d:%02d", Clock[4], Clock[5]);
      Move(RPort, 471, 7);
      Text(RPort, TimeStr, 5);

      toggle--;
    }
    else
    {
      Move(RPort, 487, 7);
      Text(RPort, " ", 1);
      toggle++;
    }

    Delay(50);
  }
}

void CleanExit()
{
  if (IBWindow)      ClearMenuStrip(IBWindow);
  if (IBWindow)      CloseWindow(IBWindow);
  if (GfxBase)       CloseLibrary((struct Library *) GfxBase);
  if (IntuitionBase) CloseLibrary(IntuitionBase);

  exit(0);
}
