/*
 * main.c:
 *
 * Copyright (c) 2000 James McKenzie <james@fishsoup.dhs.org>.
 * All rights reserved.
 *
 * $Log: main.c,v $
 * Revision 1.5  2000/09/24 01:46:06  root
 * #
 *
 * Revision 1.4  2000/09/24 01:12:49  root
 * #
 *
 * Revision 1.3  2000/09/03 03:21:53  root
 * #
 *
 * Revision 1.1  2000/09/03 02:03:28  root
 * #
 *
 * Revision 1.2  2000/09/02 17:15:27  root
 * #
 *
 * Revision 1.1  2000/09/02 17:14:58  root
 * #
 *
 * Revision 1.6  2000/02/21 04:11:27  root
 * #
 *
 * Revision 1.5  2000/02/21 04:01:00  root
 * #
 *
 * Revision 1.4  2000/02/20 03:03:53  root
 * #
 *
 * Revision 1.3  2000/02/20 02:52:13  root
 * #
 *
 * Revision 1.2  2000/02/16 13:51:59  root
 * #
 *
 * Revision 1.1  2000/02/16 13:50:11  root
 * Initial revision
 *
 *
 */

static char rcsid[] = "$Id: main.c,v 1.5 2000/09/24 01:46:06 root Exp $";

#include "project.h"

#define USE_ITIMER

#ifdef USE_ITIMER
#define TIGHT_BUSY 0.002
#endif
#ifdef USE_NANOSLEEP
#define TIGHT_BUSY 0.000
#endif

When_list whens;
Lcd l;

static void
donothing (void *dummy)
{
}


static void
myclock (void *dummy)
{
  struct timeval tv;
  char *buf;

  gettimeofday (&tv, NULL);
  buf = timeval_to_asc (tv);
/*

  lcd_pos (l, 0, 0);
  lcd_wr (l, LCD_HOME, 0);
  l->mpos = 0;
  l->spos = 0;

  lcd_wr_str (l, buf);
*/

printf("foo: %s\n",buf);
}

void
dispatch (When_list ws)
{
  When w = ws->head;
  Daytime dt;


/*
  printf ("Got %s at ", timeval_to_asc (w->tv));
  printf ("%s\n", timeval_to_asc (tv));
*/

  if (w->callback)
    w->callback (w->clientdata);

  Fill_when (w);


  Resort_whens (ws);
}

#ifdef USE_ITIMER
static void
fish (int i)
{
}
#endif


int
main (int argc, char *argv[])
{
#ifdef USE_ITIMER
  struct itimerval itime;
#endif
  struct timeval correction;


#if 0
  {
    struct Lcd_struct ls = LCD_H2571;
    l = lcd_open (ls);



    lcd_reset (l);

    lcd_dpy_ctrl (l, 1, 0, 0);


    lcd_cls (l);

  //  while (1) myclock(NULL);

  }
#endif

  whens = CREATE_LIST (When);

  {
    When w = CREATE_OBJ (When);
    int i;

    struct timeval tv;

//  El_add(w->hour,0);
//  El_add(w->min,59);


    El_add (w->usec, 0);
/*
    El_add (w->usec, 100000);
    El_add (w->usec, 200000);
    El_add (w->usec, 300000);
    El_add (w->usec, 400000);
    El_add (w->usec, 500000);
    El_add (w->usec, 600000);
    El_add (w->usec, 700000);
    El_add (w->usec, 800000);
    El_add (w->usec, 900000);
*/

    w->callback = myclock;


    Obj_Insert (whens, w, ObjInsertTail);
  }


  {
    When w = CREATE_OBJ (When);

    struct timeval tv;


    El_add (w->usec, 500000);

    w->callback = donothing;

    Obj_Insert (whens, w, ObjInsertTail);



  }


  Fill_whens (whens);
  Resort_whens (whens);

#ifdef USE_ITIMER
  signal (SIGALRM, fish);
#endif

  timerclear (&correction);

  while (1)
    {
      struct timeval now, towait, then, error, length, shouldwait;


      gettimeofday (&now, NULL);

      timersub (&whens->head->tv, &now, &shouldwait);

      if (shouldwait.tv_sec > 1)
        shouldwait.tv_sec = 1;



      timersub (&shouldwait, &correction, &towait);


      if ((((int) towait.tv_sec) >= 0) && (((int) towait.tv_usec) >= 0))
        {
          double d;

#ifdef USE_ITIMER
          if ((towait.tv_sec) || (towait.tv_usec))
            {
              itime.it_interval.tv_sec = 1;
              itime.it_interval.tv_usec = 0;
              itime.it_value = towait;
              setitimer (ITIMER_REAL, &itime, NULL);
              pause ();
            }
#endif
#ifdef USE_NANOSLEEP
          {
            struct timespec ts = { tv_sec:(long int) towait.tv_sec,
              tv_nsec:((long int) towait.tv_usec) * 1000ul
            };

          }
#endif

          then = now;
          gettimeofday (&now, NULL);


          timersub (&now, &then, &length);
          timersub (&length, &towait, &error);

          d = timevaltod (correction) * 0.9;
          d += timevaltod (error) * 0.1;
          d += TIGHT_BUSY;
          correction = dtotimeval (d);


        }
      if timercmp
        (&now, &(whens->head->tv), >)
        {
          dispatch (whens);
        }

/*
	printf("Now %s Error %d.%06d Correction %d.%06d\n",
	timeval_to_asc(now),
	(int) error.tv_sec,(int)error.tv_usec,
	(int) correction.tv_sec,(int)correction.tv_usec);
*/


    }


  return 0;
}
