/*
 * rotary.c:
 *
 * Copyright (c) 2000 James McKenzie <james@fishsoup.dhs.org>,
 * All rights reserved.
 *
 */

static char rcsid[] = "$Id: rotary.c,v 1.3 2001/01/30 06:16:34 root Exp $";

/*
 * $Log: rotary.c,v $
 * Revision 1.3  2001/01/30 06:16:34  root
 * #
 *
 * Revision 1.2  2000/12/01 04:42:25  root
 * #
 *
 * Revision 1.1  2000/11/23 23:45:36  root
 * #
 *
 * Revision 1.4  2000/09/24 01:48:13  root
 * #
 *
 * Revision 1.3  2000/09/24 01:37:11  root
 * #
 *
 * Revision 1.2  2000/09/24 01:12:47  root
 * #
 *
 * Revision 1.1  2000/09/19 06:09:00  root
 * #
 *
 */

#include <time.h>
#include <sys/time.h>

#include "project.h"
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>



#define WAVE_DIR "/root/WAVE/"

BEGIN_OBJECT (Wavefile)
     char *filename;
     char *name;
     int min;
     int sec;
END_OBJECT (Wavefile)
     static void wavefile_destructor (Wavefile w)
{
  if (!w)
    return;
  if (!w->filename)
    free (w->filename);
  if (!w->name)
    free (w->name);
  free (w);
}

CREATOR (Wavefile) = (Creator (Wavefile)) Obj_DefaultCreator;
DESTRUCTOR (Wavefile) = wavefile_destructor;

extern void *msglib;

struct timeval rotary_sep;
int rotary_sep_count = 0;

Wavefile_list surf = NULL;

static int surf_height = 0, surf_num = 0;


static void
enumurate (void)
{
  Wavefile e;

  e = surf->head;

  surf_height = 0;
  surf_num = 0;

  while (e)
    {
      surf_height++;
      e = e->next;
    }


  rotary_sep.tv_usec = 100000;
  rotary_sep.tv_sec = 0;

  rotary_sep_count = surf_height << 1;
  rotary_sep_count++;
}

static Wavefile
rotary_resolve (int i)
{
  Wavefile e;

  e = surf->head;

  while (i--)
    {
      if (e)
        e = e->next;
    }

  return e;
}

static void
do_dispatch (Wavefile w, int n)
{
  char *buf, *ptr, *cptr;


  if (!w)
    return;

  if (n < 256)
    {
      buf = hifi_getbuf ();
      ptr = buf;

      ptr = hifipkt_new_brd (ptr, HIFI_CLASS_WAVE, waveunit);

      ptr = hifipkt_ecmd (cptr = ptr, HIFI_ST_WAVE_LIST);
      ptr = hifipkt_ebyte (ptr, n);
      ptr = hifipkt_ebyte (ptr, surf_height > 255 ? 255 : surf_height);

{
      char foo[51];
      foo[sizeof(foo)-1]=0;
      strncpy(foo,w->name,sizeof(foo)-1);
      ptr += sprintf (ptr, "%.50s (%d:%02d)", foo, w->min, w->sec);
}	
      ptr++;
      hifipkt_elen (cptr, HIFI_PTR_DIFF (ptr, cptr));
      ptr = hifipkt_eeof (ptr);

      hifi_send (msglib, buf, HIFI_PTR_DIFF (ptr, buf));
      hifi_freebuf (buf);

    }

  printf ("WW %d/%d %s(%s)\n", n, surf_height, w->name, w->filename);

}

void
rotary_play (void *player, int n)
{
  Wavefile w = rotary_resolve (n);
  if (!w)
    return;

  wavep_play (player, w->filename);
}

int
rotary_derefence (char *filename)
{
  Wavefile w = surf->head;
  int n = 0;

  if (!filename)
    return -1;

  while (w)
    {
      if (!strcmp (w->filename, filename))
        return n;
      n++;
      w = w->next;
    }

  return -1;
}

void
rotary_dispatch ()
{
  Wavefile w = rotary_resolve (surf_num);

  if (w)
    {
      do_dispatch (w, surf_num);
      surf_num++;
    }
  else
    {
      surf_num = 0;
    }


  if (rotary_sep_count)
    {
      rotary_sep_count--;

      if (!rotary_sep_count)
        {
          rotary_sep.tv_usec = 0;
          rotary_sep.tv_sec = 1;
        }
    }

}


static int
mychoose (const struct dirent *e)
{
  return (e->d_name[0] != '.');
}

void
rotary_scan ()
{
  struct dirent **namelist, **ptr;
  struct stat s;
  int i, j;

  if (surf)
    Obj_Delete (surf);
  surf = CREATE_LIST (Wavefile);


  namelist = 0;

  i = scandir (WAVE_DIR, &namelist, mychoose, alphasort);

  if (i <= 0)
    return;

  if (!(ptr = namelist))
    return;

  while (i--)
    {
      Wavefile w = CREATE_OBJ (Wavefile);
      w->name = strdup ((*ptr)->d_name);
      w->filename =
        (char *) malloc (strlen (WAVE_DIR) + (*ptr)->d_reclen + 1);
      strcpy (w->filename, WAVE_DIR);
      strcat (w->filename, (*ptr)->d_name);

      s.st_size = 0;
      stat (w->filename, &s);

      j = s.st_size / RATE;

      w->min = j / 60;
      w->sec = j % 60;

      free (*ptr);
      ptr++;
      Obj_Insert (surf, w, ObjInsertTail);
    }


  free (namelist);

  enumurate ();
}


void
rotary_init (void)
{
  rotary_scan ();
}

unsigned char *
ordinal (int i)
{

  if ((i > 10) && (i < 20))
    return "th";
  switch (i % 10)
    {
    case 1:
      return "st";
    case 2:
      return "nd";
    case 3:
      return "rd";
    case 0:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    default:
      return "th";
    }




}

void
rotary_record (void *player)
{
  char buf[1024];
  char *ptr;
  char *wdname[] = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
  char *mname[] =
    { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
    "Oct", "Nov", "Dec"
  };
  struct tm tm;
  time_t t;

  time (&t);
  localtime_r (&t, &tm);

  sprintf (buf, "%s %d%s %s %04d %d:%02d:%02d",
           wdname[tm.tm_wday],
           tm.tm_mday,
           ordinal (tm.tm_mday),
           mname[tm.tm_mon],
           tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);



  rotary_scan ();
  ptr = (char *) malloc (strlen (buf) + strlen (WAVE_DIR) + 1);
  strcpy (ptr, WAVE_DIR);
  strcat (ptr, buf);

  printf ("WAVE:%s\n", ptr);
  close(creat (ptr, 0666));
  //creat (ptr, O_CREAT | O_TRUNC);

  rotary_scan ();

  wavep_record (player, ptr);

  free (ptr);
}
