/* diablomonitor.c -- main file for Diavolo Backup i2c LED monitor */

/* Structure:
 *
 * setup i2c communication
 * setup timer
 * connect to Diavolo & monitor status until CTRL-C or Diavolo is terminated
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <exec/types.h>
#include <exec/io.h>
#include <dos/dos.h>
#include <devices/timer.h>

#include <clib/exec_protos.h>

#include "dev:devs/timer/timerhandle.h"
#include "dev:diavolo/diavolohandle.h"
#include "dev:i2c/LED/i2cLEDhandle.h"

#define DELAY_SECS   5
#define SEEK_MICROS  80000
#define REW_MICROS   10000

char VERSTAG[]="\0$VER: DiabloMonitor 1.1";

struct timerequest * TimeReq;
struct timeval TempVal;

ULONG timesigmask, tempsigs;

int main(int argc, char ** argv)
{
#ifdef TAPE_SCROLL
    int s_count = 0;
    int r_count = 0;
    BOOL seek_f = FALSE;
    BOOL rewind_f =FALSE;
#endif
    BOOL finished = FALSE;
    BOOL terminate = FALSE;
    struct MsgPort * TimerMsgPort;
    char messageN[10];
    char messageO[10];

    printf("DiabloMonitor V1.1 by James Ruvior\nMonitors Diavolo backup via i2c LED display\n");

#ifdef VERBOSE
    printf("DiabloMonitor.c: timer setup with %d secs delay using unit VBLANK\n", DELAY_SECS );
#endif
    TimeReq = create_timer(UNIT_VBLANK);
    if ( TimeReq == NULL)
    {
       printf("DiabloMonitor.c: timer setup problems opening unit VBLANK\n");
       exit(20);
    }

    TimerMsgPort = TimeReq->tr_node.io_Message.mn_ReplyPort;
    if (TimerMsgPort != NULL)
        timesigmask = 1L << TimerMsgPort->mp_SigBit;
    else {
        printf("DiabloMonitor.c: timer setup problems in the message port\n");
        exit(30);
    }

    /* dummy wait for removing timer.device safely in case of errors */
    /* stupid workaround 8-( */
    TempVal.tv_secs  = (ULONG) 0;
    TempVal.tv_micro = (ULONG) 5;
    wait_for_timer(TimeReq, &TempVal);
    TempVal.tv_secs  = (ULONG) DELAY_SECS;
    TempVal.tv_micro = (ULONG) 0;


    if (setup_diavolo() != TRUE)
    {
       printf("DiabloMonitor.c: problems connecting with Diavolo\n");
       delete_timer(TimeReq);
       exit(30);
    }

    /* dummy call to recognise application release (3.4 or 2000) */
    if (!inquiry_diavolo(NULL))
    {
       printf("DiabloMonitor.c: problems deciding Diavolo Release\n");
       delete_timer(TimeReq);
       cleanup_diavolo();
       exit(30);
    }

    if (setup_i2cLED() != TRUE)
    {
       printf("DiabloMonitor.c: problems setting up SAA1064 via i2c\n");
       delete_timer(TimeReq);
       cleanup_diavolo();
       exit(30);
    }


    /* main loop */
    send_timer(TimeReq, &TempVal);
    while (!finished)
    {
        tempsigs = Wait(timesigmask | SIGBREAKF_CTRL_C);

        if (tempsigs & SIGBREAKF_CTRL_C)
        {
            finished = TRUE;
            terminate = TRUE;
        }

        if (tempsigs & timesigmask)
        {
            GetMsg(TimerMsgPort);
#ifdef TAPE_SCROLL
            if ((!seek_f )&&(!rewind_f))
#endif
                finished = !(inquiry_diavolo(messageN));
#ifdef TAPE_SCROLL
            else if (seek_f &&  ((SEEK_MICROS) * s_count >= (DELAY_SECS) * 1000000 ) )
            {
                finished = !(inquiry_diavolo(messageN));
                s_count = 0;
            }
            else if (rewind_f && ((REW_MICROS) * r_count >= (DELAY_SECS) * 1000000 ) )
            {
                finished = !(inquiry_diavolo(messageN));
                r_count = 0;
            }

#endif

            if ( strcmp(messageN, messageO) )  /* send new i2c message only if different */
                                               /* from the previous one ! */
            {
                LED_echo(messageN);            /* show current status on the LED display */
#ifdef DEBUG
                printf("DiabloMonitor.c: status-> %s\n", messageN);
#endif
                strcpy(messageO, messageN);

#ifdef TAPE_SCROLL
                if (!strcmp(messageN, "BACK"))
                {
                    rewind_f = TRUE;
                    r_count = 0;
                }
                else {
                    rewind_f = FALSE;

                    if (!strcmp(messageN, "SEEK"))
                    {
                        seek_f = TRUE;
                        s_count = 0;
                    }
                    else seek_f = FALSE;
                }
#endif
            }
#ifdef TAPE_SCROLL
            if ((!seek_f)&&(!rewind_f))        /* normal cycle */
            {
#endif
                /* next timer event */
                TempVal.tv_secs  = (ULONG) DELAY_SECS;
                TempVal.tv_micro = (ULONG) 0;
                send_timer(TimeReq, &TempVal);
#ifdef TAPE_SCROLL
            }
            else if (seek_f)                   /* tape is seeking */
            {
                TapeSeek();
                s_count += 1;
                /* next timer event */
                TempVal.tv_secs  = (ULONG) 0;
                TempVal.tv_micro = (ULONG) SEEK_MICROS;
                send_timer(TimeReq, &TempVal);
            }
            else if (rewind_f)                 /* tape is rewinding */
            {
                TapeScroll();
                r_count += 1;
                /* next timer event */
                TempVal.tv_secs  = (ULONG) 0;
                TempVal.tv_micro = (ULONG) REW_MICROS;
                send_timer(TimeReq, &TempVal);
            }
#endif
        }
    }

#ifdef VERBOSE
    if (terminate) printf("DiabloMonitor.c: got CTRL-C! Cleaning up\n");
        else printf("DiabloMonitor.c: normal termination. Cleaning up\n", TempVal.tv_secs );
#endif

    /* cleanup */
    cleanup_i2cLED();
    cleanup_diavolo();
    delete_timer(TimeReq);
    if (terminate) exit(10);
        else exit(0);
}

