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

static char rcsid[] =
  "$Id: rotary.c,v 1.11 2001/10/12 13:51:16 root Exp root $";

/*
 * $Log: rotary.c,v $
 * Revision 1.11  2001/10/12 13:51:16  root
 * #
 *
 * Revision 1.10  2001/01/30 06:16:26  root
 * #
 *
 * Revision 1.9  2000/12/01 04:42:13  root
 * #
 *
 * Revision 1.8  2000/11/23 23:45:23  root
 * #
 *
 * Revision 1.7  2000/10/07 18:30:06  root
 * #
 *
 * Revision 1.6  2000/10/07 17:57:01  root
 * #
 *
 * Revision 1.5  2000/10/06 19:52:20  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 <sys/time.h>

#include "project.h"



Files files = NULL;
static Eweid sheep = NULL;
static int flock_size = 0;
static int flock_num = 0;
static Flock flock = NULL;
Eweid flockid=NULL;
static char *flockname = NULL;

static int berandom = 0;

struct timeval rotary_sep;
static int rotary_sep_count = 0;

extern void *player;
extern void *msglib;

static void
enumurate (void)
{
  Eweid e;

  sheep = flock->head;

  flock_size = 0;
  flock_num = 0;


  e = flock->head;

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

  rotary_sep.tv_usec = 100000;
  rotary_sep.tv_sec = 0;
  rotary_sep_count = flock_size << 1;
  rotary_sep_count++;
}

int
rotary_resolve (char *s, int dogroup)
{
  Eweid e = CREATE_OBJ (Eweid);
  char *r;
  char *t;
  CFH h;
  struct mpegp_status st;

  st = mpegp_status (player);

  bcopy (s, e->e, sizeof (e->e));

  r = eweidtoa (e);
  t = eweid_to_text (e);

  printf ("Rotary_resolve %s(%s)\n", t, r);
  free (r);
  free (t);

  if (st.e && (!EWEID_CMP (e, st.e)) && (st.state == MPEGP_PLAYING))
    {
      printf ("Duplicate\n");
      Obj_Delete (e);
      return 1;
    }


  h = files_open (files, e, O_RDONLY);

  if (!h)
    {
      Obj_Delete (e);
      return 0;
    }


  if (files_is_group (h))
    {

      if (flockname)
        free (flockname);
      flockname = eweid_to_text (e);
      if (flockid) Obj_Delete(flockid);
	flockid=CREATE_OBJ(Eweid);
	bcopy(e->e,flockid->e,sizeof(e->e));
      if (flock)
        Obj_Delete (flock);
      flock = files_read_group (h);
      enumurate ();
      Obj_Delete (h);
      Obj_Delete (e);


      e = flock->head;
      if (dogroup)
        {
          if (e)
            return rotary_resolve ((unsigned char *) &e->e, dogroup);
        }
      return 0;
    }

//  Obj_Delete (h);

/*Ok we have to play this sob*/

  mpegp_play (player, files, e, h);

// Obj_Delete (e);

  return 1;

}

static void
do_dispatch (Eweid e, int n)
{
  char *s = eweidtoa (e);
  char *t;
  char *buf, *ptr, *cptr;

  if (e)
    {
      t = eweid_to_text (e);
    }
  else
    {
      t = strdup ("N/A");
    }

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

      ptr = hifipkt_new_brd (ptr, HIFI_CLASS_MPEG, mpegunit);

      ptr = hifipkt_ecmd (cptr = ptr, HIFI_ST_MPEG_LIST);
      ptr = hifipkt_ebyte (ptr, n);
      ptr =
        hifipkt_ebyte (ptr,
                       flock_size ? ((flock_size > 255) ? 255 : flock_size) :
                       1);
      if (e)
        {
          bcopy (e->e, ptr, 8);
        }
      else
        {
          bzero (ptr, 8);
        }
      ptr += 8;
      {
        char foo[51];
	foo[sizeof(foo)-1]=0;
        strncpy (foo, t, sizeof (foo) - 1);
        ptr += sprintf (ptr, "%.50s", foo);
      }
      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);

    }

  if (!flock_num)
    {
      char *a = flockname ? flockname : "Unknown";

      buf = hifi_getbuf ();
      ptr = buf;

      ptr = hifipkt_new_brd (ptr, HIFI_CLASS_MPEG, mpegunit);

      ptr = hifipkt_ecmd (cptr = ptr, HIFI_ST_MPEG_GPNAME);
  
      if (flockid) {
      	bcopy(flockid->e,ptr,sizeof(flockid->e));
      } else {
      	bzero(ptr,8);
      }
      ptr+=8;
 
      {
        char foo[51];
	foo[sizeof(foo)-1]=0;
        strncpy (foo, a, sizeof (foo) - 1);
        ptr += sprintf (ptr, "%.50s", foo);
      }
      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 ("DD %d/%d %s (%s)\n", n, flock_size, s, t);

  free (s);
  free (t);


}

void
rotary_dispatch ()
{
  do_dispatch (sheep, flock_num);

  if (sheep)
    {
      sheep = sheep->next;
      flock_num++;
    }

  if (!sheep)
    {
      sheep = flock->head;
      flock_num = 0;
    }

  if (rotary_sep_count)
    {
      rotary_sep_count--;

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



}

#if 0
static void
rotary_dispatch_all (void)
{
  Eweid e = flock->head;
  int i = 0;

  if (e)
    {
      while (e)
        {
          do_dispatch (e, i);
          usleep (100000);
          e = e->next;
          i++;
        }

      e = flock->head;
      i = 0;

      while (e)
        {
          do_dispatch (e, i);
          usleep (100000);
          e = e->next;
          i++;
        }
    }
  else
    {
      rotary_dispatch ();
      rotary_dispatch ();
    }

}
#endif

void
rotary_init ()
{

  files = files_user_init ();
}

void
rotary_rescan (void)
{
  Obj_Delete (files);
  rotary_init ();
}


void
rotary_search (char *c)
{
  Eweid e;

  if (flock)
    Obj_Delete (flock);


  if (flockname)
    free (flockname);
  flockname = (char *) malloc (strlen (c) + 20);
  sprintf (flockname, "search: %s", c);

  if(flockid) 
	Obj_Delete(flockid);
  flockid=NULL;

  e = atoeweid (c);
  if (e)
    {
      flock = CREATE_LIST (Eweid);

      Obj_Insert (flock, e, ObjInsertTail);

      if (flockname)
        free (flockname);
      flockname = eweid_to_text (e);
  //flockid=CREATE_OBJ(Eweid);
//	bcopy(e->e,flockid->e,sizeof(e->e));


      enumurate ();

      rotary_resolve ((unsigned char *) &e->e, 0);
      return;
    }


  flock = files_find (c);

  enumurate ();

}


void
rotary_next (void)
{
  Eweid e;
  struct mpegp_status s;
  int i;
  s = mpegp_status (player);

  if ((!s.e) || (!flock))
    {
      mpegp_stop (player);
      return;
    }


  e = flock->head;

  while (e && EWEID_CMP (e, s.e))
    e = e->next;

  if (e)
    e = e->next;

  while (e)
    {
      if (rotary_resolve ((unsigned char *) &e->e, 1))
        return;
      e = e->next;
    }



  if (berandom)
    for (i = 0; i < 20; ++i)
      {                         //Try a few times
        if (flock)
          Obj_Delete (flock);


	if (flockid)
	  Obj_Delete(flockid);

	flockid=NULL;

        if (flockname)
          free (flockname);
	flockname=NULL;

        flock = CREATE_LIST (Eweid);

        e = files_random_work ();

        if (!e)
          {
            enumurate ();
            return;
          }

        Obj_Insert (flock, e, ObjInsertTail);

        flockname = eweid_to_text (e);
	//flockid=CREATE_OBJ(Eweid);
	//bcopy(e->e,flockid->e,sizeof(e->e));
	
//	Obj_Delete(flock);


        enumurate ();

        if (rotary_resolve ((unsigned char *) &e->e, 1))
          return;
      }

}


void
rotary_random (void)
{
  berandom = 1;
}

void
rotary_notrandom (void)
{
  berandom = 0;
}

void
rotary_choose_random (void)
{
  Eweid e;

  printf ("RANDOM\n");
  if (flock)
    Obj_Delete (flock);

  flock = CREATE_LIST (Eweid);

  e = files_random_work ();

  if (!e)
    {
      enumurate ();
      return;
    }

  Obj_Insert (flock, e, ObjInsertTail);
  if (flockname)
    free (flockname);
  flockname = eweid_to_text (e);
  enumurate ();

  rotary_resolve ((unsigned char *) &e->e, 1);

  return;
}
