/*-------------------------------------------------------------------------*
 *                                    AppTime 
 *                                    ~~~~~~~        
 *                Version 1.1                       par XAVIER LECLERCQ
 *                ~~~~~~~~~~~                       ~~~~~~~~~~~~~~~~~~~
 *-------------------------------------------------------------------------*/

/*  DICE C 
    ~~~~~~
  -> A68k AppTime.ASM --> AppTime.o
 
  -> dcc <file>.c -a -f <file>.a
     das -oT:<file>.o T:<file>.a 
     dlink dlib:c.o AppTime.o T:<file>.o dlib:c.lib dlib:reqtools.lib 
           dlib:amigas20.lib dlib:auto.lib dlib:x.o  -o <file>
*/

/*-------------------------------------------------------------------------*
 * #include
*/
#include <stdio.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/datetime.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/devices.h>
#include <exec/interrupts.h>
#include <devices/timer.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include "libraries/reqtools.h"
#include <workbench/startup.h>
#include <workbench/workbench.h>

/*-------------------------------------------------------------------------*
 * #define
*/
#define MSG_ERR_1     "ERR 01 : You need 'LIBS:reqtools.library' !!"
#define MSG_ERR_2     "ERR 02 : You need 'intuition.library' >= v36 !!"
#define MSG_ERR_3     "ERR 03 : Error open 'graphics.library' !!"
#define MSG_ERR_4     "ERR 04 : You need 'workbench.library' >= v36 !!"
#define MSG_ERR_5     "ERR 05 : Workbench message port creation error !"
#define MSG_ERR_6     "ERR 06 : OpenWindowTags error !"
#define MSG_ERR_7     "ERR 07 : AppMenuItem error !"
#define MSG_ERR_8     "ERR 08 : Timer message port creation error !"
#define MSG_ERR_9     "ERR 09 : TimerRequest creation error !"
#define MSG_ERR_10    "ERR 10 : Timer device Open error !"
#define MSG_ERR_11    "ERR 11 : inputdevice_port creation error !"
#define MSG_ERR_12    "ERR 12 : inputdevice request creation error !"
#define MSG_ERR_13    "ERR 13 : 'input.device' Open error !"
#define MSG_ERR_14    "ERR 14 : 'input.device' signal allocation error !"
#define MSG_ERR_15    "ERR 15 : Memory allocation error !"
#define MSG_BLANKER   "Entrez le délai en secondes :"
#define MSG_ERROR     "Erreur!"
#define MSG_QUIT      "Quitter ..."
#define MSG_OK        "OK"
#define MSG_APPTIME1  "---------------------"
#define MSG_APPTIME2  "Ecran noir après..."
#define MSG_APPTIME3  "A propos d'AppTime..."
#define MSG_APPTIME4  "Quitter AppTime"
#define MSG_APPTIME5  "---------------------"
#define TITLE_ABOUT   "A propos ..."
#define SYSTEMFAIL    (-1L)
#define WINDOWFAIL    (-2L)
#define MSG_ABOUT   \
"AppTime version 1.1\n"\
"~~~~~~~~~~~~~~~~~~~\n"\
"Utilitaire servant de Blanker/Timer.\n"\
"De plus vous pouvez Utiliser le fichier sys:s/TOOLS_MENU.AppTime\n"\
"Pour avoir la facilité de lancer des programmes à partir du menu\n"\
"du Workbench. AppTime nécessite le system 2.0 au minimum pour un\n"\
"bon fonctionnement. La structure du sys:s/TOOLS_MENU.apptime est\n"\
"la suivante :\n"\
"Première ligne : Nom du menu          \n"\
"Deuxième ligne : commande CLI utilisée\n"\
"et ainsi de suite ...                 \n\n"\
"XAVIER LECLERCQ\n"\
"Vieux chemin d'ath n°12\n"\
"B-7548 Warchin BELGIQUE\n"

static char *VERSION = " $VER: AppTime 1.1 (09.09.92)";
/*-------------------------------------------------------------------------*
 * GLOBAL
*/
struct ReqToolsBase  *ReqToolsBase     = NULL;
struct IntuitionBase *IntuitionBase    = NULL;
struct WorkbenchBase *WorkbenchBase    = NULL;
struct MsgPort       *msgport          = NULL;
struct MsgPort       *timerport        = NULL;
struct MsgPort       *inputdevice_port = NULL;
struct MsgPort       *timedevice_port  = NULL;
struct timerequest   *timereq          = NULL;
struct Message       *timermsg         = NULL;    
struct AppMessage    *appmsg           = NULL;
struct Window        *window           = NULL;
struct RastPort      *rastport         = NULL;
struct GfxBase       *GfxBase          = NULL;
struct IOStdReq      *inputreq         = NULL;
struct Interrupt     *InputHandler     = NULL;
struct Screen        *BlankScreen      = NULL;
struct Task          *AppTime_task     = NULL;
BOOL   noerr        = FALSE , flagstart = TRUE , flagecran = FALSE;
BYTE   InputSig     = -1;
ULONG  InputSigMask = 0 , Sig = 0 , Timecount = 0xffffffff;
ULONG  TimeDelay    = 180 , result;
ULONG  appmenuitem[60] , ptrdatas[120] , i , j;
extern VOID HandlerIO();
struct NewScreen NewScreen =
{ 0,0,320,12,1,0,0,NULL,SCREENQUIET,NULL,NULL,NULL,NULL };
FILE  *fp = NULL;
BPTR  file;
UBYTE *command , *ptrmenu;
/*--------------------------------------------------------------------------*/
WR(char *str) { Write(Output(), str ,strlen(str)); }
/*--------------------------------------------------------------------------*/
MsgErr(char *str) {  
  rtEZRequestTags (str,MSG_QUIT,NULL,NULL,RT_ReqPos , REQPOS_CENTERSCR ,
                  RTEZ_ReqTitle , MSG_ERROR , TAG_END), FermeAll(); }
/*--------------------------------------------------------------------------*/
About()
{
  rtEZRequestTags (MSG_ABOUT , MSG_OK , NULL , NULL ,RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERSCR ,RTEZ_ReqTitle , TITLE_ABOUT, 
                  RTEZ_Flags , EZREQF_CENTERTEXT , TAG_END );
}
/*--------------------------------------------------------------------------*/
OuvreAll()
{
 if(!(ferror(fp=fopen("sys:s/TOOLS_MENU.AppTime","rb")))) {
    while(!(feof(fp))) {
      ptrdatas[i]=malloc(132);
      if(!(ptrdatas[i])) MsgErr(MSG_ERR_15);
      fgets((char *)ptrdatas[i++],132,fp);
      ptrmenu=(char *)ptrdatas[i-1]+strlen((char *)ptrdatas[i-1])-1;
      *ptrmenu = 0x00;
      ptrdatas[i]=malloc(132);
      if(!(ptrdatas[i])) MsgErr(MSG_ERR_15);
      fgets((char *)ptrdatas[i++],132,fp);
      ptrmenu=(char *)ptrdatas[i-1]+strlen((char *)ptrdatas[i-1])-1;
      *ptrmenu = 0x00;
    } 
   fclose(fp);
   i--;
   if (ptrdatas[i]) free(ptrdatas[i]),ptrdatas[i]=0L;
   i--;
   if (ptrdatas[i]) free(ptrdatas[i]),ptrdatas[i]=0L;
 }
 else  
   WR("\n\tWARNING : SYS:S/TOOLS_MENU.AppTime open trouble...\n"\
        "\t~~~~~~~\n");
 ReqToolsBase  = (struct ReqToolsBase  *) OpenLibrary("reqtools.library",0L);
 if (!(ReqToolsBase))  WR(MSG_ERR_1"\n\n"),FermeAll();
 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36);
 if (!(IntuitionBase)) MsgErr(MSG_ERR_2);
 GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L);
 if (!(GfxBase)) MsgErr(MSG_ERR_3);
 WorkbenchBase = (struct WorkbenchBase *) OpenLibrary("workbench.library",36);
 if (!(WorkbenchBase)) MsgErr(MSG_ERR_4);
 if (!(msgport = (struct MsgPort *) CreateMsgPort())) MsgErr(MSG_ERR_5);
 if (!(window  = (struct Window *) OpenWindowTags(NULL, WA_Left, 540,
                 WA_Top, 2, WA_Width, 70,WA_Flags , BORDERLESS,
                 WA_Height, 8 , TAG_END))) MsgErr(MSG_ERR_6);
 if (!(appmenuitem[1] = (struct AppMenuItem *)
   AddAppMenuItem(1,0,MSG_APPTIME1,msgport,NULL))) MsgErr(MSG_ERR_7);
 if (!(appmenuitem[2] = (struct AppMenuItem *)
   AddAppMenuItem(2,0,MSG_APPTIME2,msgport,NULL))) MsgErr(MSG_ERR_7);
 if (!(appmenuitem[3] = (struct AppMenuItem *)
   AddAppMenuItem(3,0,MSG_APPTIME3,msgport,NULL))) MsgErr(MSG_ERR_7);
 if (!(appmenuitem[4] = (struct AppMenuItem *)
   AddAppMenuItem(4,0,MSG_APPTIME4,msgport,NULL))) MsgErr(MSG_ERR_7);
 if (!(appmenuitem[5] = (struct AppMenuItem *)
   AddAppMenuItem(5,0,MSG_APPTIME5,msgport,NULL))) MsgErr(MSG_ERR_7);
 i = 0;
 j = 0;
 while(ptrdatas[j])
 {
   ptrmenu=(char *)ptrdatas[j];
   appmenuitem[6+i] = NULL;
   if (!(appmenuitem[6+i] = (struct AppMenuItem *)
     AddAppMenuItem(6+i,0,ptrmenu,msgport,NULL))) MsgErr(MSG_ERR_7);
   i++;
   j+=2;
 }
 if (!(timerport = (struct MsgPort *) CreatePort(0,0))) MsgErr(MSG_ERR_8);
 if (!(timereq = (struct timerequest *) 
   CreateExtIO(timerport,sizeof(struct timerequest)))) MsgErr(MSG_ERR_9);
 if (OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)timereq,0L))
   MsgErr(MSG_ERR_10);
   noerr = TRUE;
 if (!(inputdevice_port = (struct MsgPort *)CreatePort(0,0))) 
   MsgErr(MSG_ERR_11);
 if (!(inputreq = (struct IOStdReq *)
   CreateExtIO(inputdevice_port,sizeof(struct IOStdReq)))) MsgErr(MSG_ERR_12);
 if (OpenDevice("input.device",NULL,(struct IORequest *)inputreq,NULL)) 
   MsgErr(MSG_ERR_13);
 if((InputSig = AllocSignal(-1L)) == -1) MsgErr(MSG_ERR_14);
 if(!(InputHandler =(struct Interrupt *)
   AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR))) 
 MsgErr(MSG_ERR_15);
}
/*--------------------------------------------------------------------------*/
FermeAll()
{
 i = 0;
 while(ptrdatas[i]) {
   free((char *)ptrdatas[i++]);
 }
 if (inputreq != NULL)
 {
   if (inputreq->io_Device !=NULL)
   {
     inputreq->io_Command = IND_REMHANDLER;
     inputreq->io_Data= (APTR)InputHandler;
     DoIO((struct IORequest *)inputreq);
     CloseDevice((struct IORequest *)inputreq);
   }
   DeleteExtIO((struct IORequest *)inputreq);
 }
 if (InputHandler  ) FreeMem      (InputHandler,sizeof(struct Interrupt)    );
 if (InputSig != -1) FreeSignal   (InputSig                                 );
 if (inputdevice_port) DeletePort (inputdevice_port                         );
 i = 1;
 while(appmenuitem[i])
 {
 if (appmenuitem[i]) RemoveAppMenuItem((struct AppeMenuItem *)appmenuitem[i]);
 i++;
 }
 if (msgport       ) DeleteMsgPort((struct MsgPort          *) msgport      );
 if (window        ) CloseWindow  ((struct Window           *) window       );   
 if (noerr         ) CloseDevice  ((struct IORequest        *) timereq      );
 if (timereq       ) DeleteExtIO  ((struct IORequest        *) timereq      );
 if (timerport     ) DeletePort   ((struct MsgPort          *) timerport    );
 if (IntuitionBase ) CloseLibrary ((struct IntuitionBase    *) IntuitionBase);
 if (GfxBase       ) CloseLibrary ((struct GfxBase          *) GfxBase      );
 if (WorkbenchBase ) CloseLibrary ((struct WorkbenchBase    *) WorkbenchBase);
 if (ReqToolsBase  ) CloseLibrary ((struct ReqToolsBase     *) ReqToolsBase );
 exit(0);
}
/*-------------------------------------------------------------------------*/
Affiche(LONG x,LONG y,char *Msg)
{
 rastport = window->RPort;
 SetAPen(rastport, 2L);
 SetBPen(rastport, 1L);
 Move(rastport, x , y);
 Text(rastport, Msg , strlen(Msg) );
}
/*-------------------------------------------------------------------------*/
LONG beginCommand(UBYTE *command)
{
  UBYTE *autocon="CON:0/40/640/150/AppTime Window if Needed/auto/close/wait";
  struct TagItem stags[5];
  LONG result = WINDOWFAIL;
  BPTR file;
     
  if(file = Open(autocon, MODE_OLDFILE)) {
    stags[0].ti_Tag = SYS_Input;
    stags[0].ti_Data = file;
    stags[1].ti_Tag = SYS_Output;
    stags[1].ti_Data = NULL;
    stags[2].ti_Tag = SYS_Asynch;
    stags[2].ti_Data = TRUE;
    stags[3].ti_Tag = SYS_UserShell;
    stags[3].ti_Data = TRUE;
    stags[4].ti_Tag = TAG_DONE;
    result = System(command, stags);
    if(result == -1L) Close(file);
  }
  return(result);
}
/*-------------------------------------------------------------------------*/
void main(int argc , char **argv[])
{
 Delay(50L);
 if (argc > 1) {
   if (atol(argv[1]) > 1L ) 
     TimeDelay = atol(argv[1]);
 } 
 OuvreAll();
 long TimeNow[3], *TN = TimeNow , arg[3];
 char Buff[8]; 

 AppTime_task = (struct Task *)FindTask(NULL);
 SetTaskPri(AppTime_task , -20);  

 InputSigMask = 1L << InputSig;

 InputHandler->is_Code=(VOID (*)())HandlerIO; /* AppTime.ASM */
 InputHandler->is_Data=NULL;
 InputHandler->is_Node.ln_Pri=51;
 InputHandler->is_Node.ln_Name="AppTime_Handler";
 inputreq->io_Data=(APTR)InputHandler;
 inputreq->io_Command=IND_ADDHANDLER;
 DoIO((struct IORequest *)inputreq);

 FOREVER /* MACRO <intuition/intuition.h> == for(;;) */
 {
   DateStamp(TN);
 
   arg[0] = TimeNow[1]/60;
   arg[1] = TimeNow[1] - (arg[0] * 60);
   arg[2] = TimeNow[2]/50;
  
   Convertir(Buff,"%02ld:%02ld:%02ld ",arg); /* AppTime.ASM */
 
   Affiche(0,6,Buff);
 
   timereq->tr_node.io_Command = TR_ADDREQUEST;
   timereq->tr_time.tv_secs    = 0;
   timereq->tr_time.tv_micro   = 12000;
   SendIO((struct IORequest *)timereq);

   Sig = Wait((1 << msgport->mp_SigBit) | (1 << timerport->mp_SigBit)
               |InputSigMask);
   if (Sig & InputSigMask) 
     {
      Timecount = 0xffffffff, flagstart = TRUE;
      if (flagecran)
       {
          CloseScreen(BlankScreen);
          MouseON(); 
          flagecran = FALSE,BlankScreen = NULL; 
       }  
     }
   else if (flagstart)
      {   
        Timecount = (arg[1] * 60 ) + arg[2] + TimeDelay;
        flagstart = FALSE;
      }
   if ((((arg[1] * 60 ) + arg[2] >= Timecount )) & (flagstart == FALSE))
   {
     BlankScreen = (struct Screen *)OpenScreen(&NewScreen);
     if (BlankScreen != NULL)
     {
       SetRGB4(&(BlankScreen->ViewPort),0,0,0,0);
       MouseOFF(); 
       flagecran = TRUE , Timecount = 0xffffffff;
     } 
   }
   while (timermsg = (struct Message *) GetMsg(timerport));
   if (appmsg = (struct AppMessage *) GetMsg(msgport))
   {
     ReplyMsg(appmsg);
     if (appmsg->am_ID == 2) 
     {
       while (appmsg = (struct AppMessage *) GetMsg(msgport))
         ReplyMsg(appmsg);
       if (rtGetLong (&TimeDelay, MSG_BLANKER, NULL,
            RT_ReqPos , REQPOS_CENTERWIN ,
            RTGS_Width , strlen(MSG_BLANKER)*12 , RT_WaitPointer , TRUE ,
            RTGL_Min  , (ULONG) 1 , RTGL_Max  , (ULONG) 3600 ,
            RTGL_ShowDefault, TRUE , TAG_END)) {
       }     
     } 
     else if (appmsg->am_ID == 3) 
     {
       while (appmsg = (struct AppMessage *) GetMsg(msgport))
         ReplyMsg(appmsg);
       About();
     } 
     else if (appmsg->am_ID == 4) 
     {  
       Wait((1 << msgport->mp_SigBit) | (1 << timerport->mp_SigBit));
       while (timermsg = (struct Message *) GetMsg(timerport));
       while (appmsg = (struct AppMessage *) GetMsg(msgport))
         ReplyMsg(appmsg);
       FermeAll();
     }
     else if (appmsg->am_ID >= 6) 
     {  
       result = ((appmsg->am_ID - 6) * 2) + 1;
       Wait((1 << msgport->mp_SigBit) | (1 << timerport->mp_SigBit));
       while (timermsg = (struct Message *) GetMsg(timerport));
       while (appmsg = (struct AppMessage *) GetMsg(msgport))
         ReplyMsg(appmsg);
       command = (char *)ptrdatas[result];
       result = beginCommand(command);
     }
   }
 }
}
/*-------------------------------------------------------------------------*/
