/****************************************************************************
 *                                                                          *
 * Program   : Sclock.c                                                     *
 * Programmer: David C. Lauri Jr.   [DLAURI  PeopleLink, Genie, BIX]        *
 *                                                                          *
 * This is a digital titlebar clock with seconds and AM/PM indicator.       *
 * Its special feature is that it always stays on the active screen, even   *
 * if the active screen is a custom one belonging to another program.       *
 * (Finally, a clock for AMIC PD term!)                                     *
 *                                                                          *
 * User beware:                                                             *
 * Because this clock sometimes "trespasses" on custom screens, special     *
 * care must be taken in its use.  If a custom screen on which it resides   *
 * closes, you will be visited by the GURU.  Therefore, before closing a    *
 * custom screen, close the clock first.  For example, if you want to exit  *
 * AMIC PD term, first close Sclock and then close AMIC PD term.  Then, you *
 * can run Sclock again.                                                    *
 *                                                                          *
 * Having said that, I hereby disclaim any responsibility for damages       *
 * caused by use of this program.  Anyone who feels he can't follow the     *
 * above guideline should not use this program!                             *
 *                                                                          *
 * This program is released into the public domain.  Anyone may do whatever *
 * he wants with it.                                                        *
 *                                                                          *
 ****************************************************************************/

#include <libraries/dos.h>
#include <intuition/intuitionbase.h>
#include <lattice/stdio.h>

#define    WIN_WIDTH   131                  /* width of the clock's window */
#define    WAIT_TIME   250000               /* how long to wait between
                                               updates in micro-seconds */

struct NewWindow newwindow =
{ 459, 0,                                   /* Upper left corner
                                               (puts clock just to left
                                                of the Back/Front gadgets */
  131, 10,                                  /* Width, Height */
  1, 1,                                     /* Foreground, background */
  CLOSEWINDOW,                              /* IDCMP flags */
  WINDOWCLOSE                               /* flags */
    | WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH,
  NULL,                                     /* First gadget */
  NULL,                                     /* Check mark */
  "",                                       /* Title */
  NULL,                                     /* Screen */
  NULL,                                     /* Bit map */
  0, 0, 0, 0,                               /* minimum/maximum sizes */
  WBENCHSCREEN                              /* Workbench type */
};
struct Window *window, *OpenWindow();
struct timerequest timer;
struct MsgPort *timerport, *CreatePort();
struct Screen *workbenchscreen, *currentscreen;

char datestring[20];                         /* Place to keep the date */
struct IntuiText datetext =
{ 2, 1,                                     /* Foreground, background */
  JAM2,                                     /* Use both pens */
  0, 0,                                     /* Upper left corner */
  NULL,                                     /* Text attributes */
  datestring,                               /* Buffer */
  NULL                                      /* Next IntuiText */
};

struct IntuitionBase *IntuitionBase;

void
main()
{  int                 notclosed = TRUE;
   register short      hours, minutes;
   char                *time, *am="AM", *pm="PM";
   struct DateStamp    now;
   struct IntuiMessage *message, *GetMsg();
   struct Task         *FindTask();
   
   if((IntuitionBase = (struct IntuitionBase *)
           OpenLibrary("intuition.library", 0)) != NULL)
   { if((timerport = CreatePort("Timer Port", 0)) != NULL)
     { if(OpenDevice(TIMERNAME, UNIT_VBLANK, (char *)&timer, 0) == NULL)
       { timer.tr_node.io_Message.mn_ReplyPort = timerport;
         timer.tr_node.io_Command = TR_ADDREQUEST;
         timer.tr_node.io_Flags = 0;
         timer.tr_node.io_Error = 0;
         
         if((window = OpenWindow(&newwindow)) != NULL)
         { workbenchscreen = window->WScreen;
           currentscreen = window->WScreen;
           
           (void)SetTaskPri(FindTask((char *) 0), 20);
           
           while(notclosed)
           { DateStamp(&now);
             hours = now.ds_Minute / 60;
             if(hours >= 12)
               time = pm;
             else
               time = am;
             if(hours > 12)
               hours = hours - 12;
             if(hours == 0)
               hours = 12;
             minutes = now.ds_Minute % 60;
             
             sprintf(datestring, " %02d:%02d:%02d %2s ",
                        hours, minutes, now.ds_Tick / TICKS_PER_SECOND, time);
             
             PrintIText(window->RPort, &datetext, 28, 1);
             
             timer.tr_time.tv_secs = 0;
             timer.tr_time.tv_micro = WAIT_TIME;
             SendIO((char *) &timer.tr_node);
             Wait(1 << window->UserPort->mp_SigBit
                    | 1 << timerport->mp_SigBit);
             
             while(message = GetMsg(window->UserPort))
             { if(message->Class == CLOSEWINDOW)
                 notclosed = FALSE;
               ReplyMsg(message);
             } /* end while */
             
             (void)GetMsg(timerport);
             if(currentscreen != IntuitionBase->ActiveScreen)
             { newwindow.LeftEdge = window->LeftEdge;
               newwindow.TopEdge = window->TopEdge;
               if(newwindow.TopEdge >= IntuitionBase->ActiveScreen->Height)
                 newwindow.TopEdge = IntuitionBase->ActiveScreen->Height - 1;
               if(window)
                 CloseWindow(window);
               if(IntuitionBase->ActiveScreen == workbenchscreen)
               { newwindow.Screen = NULL;
                 newwindow.Type = WBENCHSCREEN;
               } /* end if(IntuitionBase->ActiveScreen...) */
               else
               { newwindow.Screen = IntuitionBase->ActiveScreen;
                 newwindow.Type = CUSTOMSCREEN;
               } /* end else */
               if((window = (struct Window *)OpenWindow(&newwindow)) != NULL)
                 currentscreen = window->WScreen;
               else
                 notclosed = FALSE;
             } /* end if(currentscreen...) */
           } /* end while(notclosed) */
           if(window)
             CloseWindow(window);
         } /* end if((window = ...) */
         CloseDevice(&timer);
       } /* end if(OpenDevice(TIMERNAME...) */
       DeletePort(timerport);
     } /* end if((timerport = CreatePort("Timer Port", 0)) != NULL) */
     CloseLibrary(IntuitionBase);
   } /* end if((IntuitionBase = (struct IntuitionBase *)...) */
} /* end main () */
