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

static char rcsid[] = "$Id: wave.c,v 1.2 2000/09/29 07:53:48 root Exp $";

/*
 * $Log: wave.c,v $
 * Revision 1.2  2000/09/29 07:53:48  root
 * #
 *
 * Revision 1.1  2000/09/29 07:53:02  root
 * #
 *
 * Revision 1.7  2000/09/24 01:48:14  root
 * #
 *
 */


#include "project.h"

static Word current_length;

typedef unsigned char Eweid[8];

static char **names = NULL;
static Word num = 0;
static Word need_update = 1;

void
wave_do_cleanup ()
{
  Word n = num;
  Word i;

  if (names)
    {
      if (!n)
        n++;

      for (i = 0; i < n; ++i)
        {
          MemPtrFree (names[i]);
        }

      MemPtrFree (names);
    }

  names = NULL;
  num = 0;


}

static void
maintain_list (int j, int n, char *name, int form)
{
  Word i;
  FormPtr formptr;
  ListPtr listptr;
  UInt16 index;


  if (n != num)
    {
      wave_do_cleanup ();

      num = n;

      if (!n)
        n++;

      names = (char **) MemPtrNew (n * sizeof (char *));

      for (i = 0; i < n; ++i)
        {
          names[i] = MemPtrNew (15);
          bcopy ("Please wait...", names[i], 15);
        }


    }



  if ((j <= num) && names)
    {
      int update = 0;

      if (names[j])
        {
          if (strcmp (names[j], name) || need_update)
            {
              update++;
              need_update = 0;
              MemPtrFree (names[j]);
            }
        }
      else
        {
          update++;
        }

      if (update)
        {


          names[j] = MemPtrNew (strlen (name) + 1);
          bcopy (name, names[j], strlen (name) + 1);

          if (form)
            {
              formptr = FrmGetFormPtr (WaveForm);
              if (!formptr)
                return;
              index = FrmGetObjectIndex (formptr, WaveList);
              listptr = FrmGetObjectPtr (formptr, index);
              if (!listptr)
                return;

              LstSetListChoices (listptr, names, num);
              LstDrawList (listptr);
            }
        }

    }





}

static void
list_lookup (int i)
{
  FormPtr formptr;
  ListPtr listptr;
  UInt16 index;
  Int16 j;


  formptr = FrmGetFormPtr (WaveForm);
  if (!formptr)
    return;
  index = FrmGetObjectIndex (formptr, WaveList);
  listptr = FrmGetObjectPtr (formptr, index);
  if (!listptr)
    return;

  j = LstGetSelection (listptr);

  if (j != i)
    {
      LstSetSelection (listptr, i);
    }
}


void
wave_cmdst_message (Byte unit, Word cmd, Byte * data, Word len)
{
  Word id = FrmGetActiveFormID ();

  if (unit != waveunit)
    return;

  if (cmd == HIFI_ST_WAVE_LIST)
    maintain_list (data[0], data[1], &data[2], id == WaveForm);

  if (id != WaveForm)
    return;

  switch (cmd)
    {
    case HIFI_ST_VOL:
      {
        Word v;
        v = data[0] + data[1];
        v = v / 2;
        SliderSet (WaveForm, WaveVolume, v);
      }
      break;
    case HIFI_ST_WAVE_STATE:
      {
        int current_state;
        int fl = 0;

        DWord d;
        Word length;

        char buf[80], *ptr;


        RectangleType rt = {
          {WaveStLeft, WaveStTop},
          {WaveStWidth, WaveStHeight}
        };

        WinEraseRectangle (&rt, 0);

        ptr = buf;


        current_state = data[0];

        switch (current_state)
          {
          case HIFI_WAVE_State_Stopped:
            ptr += sprintf (ptr, "Stop: ");
            break;
          case HIFI_WAVE_State_Playing:
            ptr += sprintf (ptr, "Play: ");
            fl++;
            break;
          case HIFI_WAVE_State_Recording:
            ptr += sprintf (ptr, "Record: ");
            fl++;
            break;
          case HIFI_WAVE_State_Error:
            ptr += sprintf (ptr, "Error: ");
            break;
          case HIFI_WAVE_State_Unknown:
            ptr += sprintf (ptr, "???: ");
            break;
          }

        hifipkt_dword (&data[3], &current_length);


        if (fl)
          {
            sprintf (ptr, "%02d:%02d/%d:%02d", data[1], data[2],
                     current_length / 60, current_length % 60);

          }
        if (current_length > 0)
          {
            d = data[1];
            d *= 60;
            d += data[2];
            d *= 100;
            d = d / current_length;
          }

        SliderSet (WaveForm, WaveProgress, (Word) d);

        list_lookup (data[5]);


        WinDrawChars (buf, StrLen (buf), WaveStLeft, WaveStTop);
      }

      break;

    }


}

static void
progress_callback (Word formid, Word sliderid, int v)
{
  DWord o = v;
  Byte *buf, *ptr, *cptr;
  Byte min, sec;

  o = o * (DWord) current_length;
  o = o / 100;


  buf = ptr = hifi_getbuf ();
  ptr =
    hifipkt_new (ptr, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_WAVE,
                 waveunit);
  ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_WAVE_SEEK);

  ptr = hifipkt_eword (ptr, o);

  hifipkt_elen (cptr, HIFI_PTR_DIFF (ptr, cptr));
  ptr = hifipkt_eeof (ptr);

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

}

static void
volume_callback (Word formid, Word sliderid, int v)
{
  Byte *cptr, *ptr, *buf;

  buf = ptr = hifi_getbuf ();
  ptr =
    hifipkt_new (ptr, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_WAVE,
                 waveunit);
  ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_VOL);
  ptr = hifipkt_ebyte (ptr, v);
  ptr = hifipkt_ebyte (ptr, v);
  hifipkt_elen (cptr, HIFI_PTR_DIFF (ptr, cptr));
  ptr = hifipkt_eeof (ptr);

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

}



void
wave_dispatch (EventType * e)
{
  Err err;
  Byte *cptr, *ptr, *buf;

  switch (e->eType)
    {
    case penDownEvent:
      slider_dispatch (e, WaveForm, WaveVolume, volume_callback);
      slider_dispatch (e, WaveForm, WaveProgress, progress_callback);
      break;
    case lstSelectEvent:
      {
        Word i = e->data.lstSelect.selection;
        if (e->data.lstSelect.listID != WaveList)
          break;
        if (i >= num)
          break;

        buf = ptr = hifi_getbuf ();
        ptr =
          hifipkt_new_rel (ptr, HIFI_CLASS_DISPLAY, displayunit,
                           HIFI_CLASS_WAVE, waveunit);
        ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_WAVE_PLAY);

        ptr = hifipkt_ebyte (ptr, i);

        hifipkt_elen (cptr, HIFI_PTR_DIFF (ptr, cptr));
        ptr = hifipkt_eeof (ptr);

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

      }
      break;
    case ctlSelectEvent:

      switch (e->data.ctlEnter.controlID)
        {
        case WaveRecordButton:
          hifi_cmd_rel (NULL, HIFI_CLASS_DISPLAY, displayunit,
                        HIFI_CLASS_WAVE, waveunit, HIFI_CMD_RECORD);
          break;

        case WaveStopButton:
          hifi_cmd_rel (NULL, HIFI_CLASS_DISPLAY, displayunit,
                        HIFI_CLASS_WAVE, waveunit, HIFI_CMD_STOP);
          break;

        }
      break;

    case frmOpenEvent:
      redraw_screen ();
      SliderSet (WaveForm, WaveVolume, 0);
      SliderSet (WaveForm, WaveProgress, 0);
      need_update++;


      break;
    }

}
