/*
 * cd.c:
 *
 * Copyright (c) 2000 James McKenzie <james@fishsoup.dhs.org>.
 * All rights reserved.
 *
 * $Log: cd.c,v $
 * Revision 1.13  2000/11/23 23:45:28  root
 * #
 *
 * Revision 1.12  2000/09/29 07:53:48  root
 * #
 *
 * Revision 1.11  2000/09/29 07:53:02  root
 * #
 *
 * Revision 1.10  2000/09/24 01:12:53  root
 * #
 *
 * Revision 1.9  2000/09/19 09:36:01  root
 * #
 *
 * Revision 1.8  2000/02/20 18:23:01  root
 * #
 *
 * Revision 1.7  2000/02/20 03:17:22  root
 * #
 *
 * Revision 1.6  2000/02/20 03:16:39  root
 * #
 *
 * Revision 1.5  2000/02/20 02:51:44  root
 * #
 *
 * Revision 1.4  2000/02/16 11:34:56  root
 * #
 *
 * Revision 1.3  2000/02/16 11:34:21  root
 * #
 *
 * Revision 1.2  2000/02/15 22:16:16  root
 * #
 *
 * Revision 1.1  2000/02/15 22:13:40  root
 * #
 *
 *
 *
 */

static char rcsid[] = "$Id: cd.c,v 1.13 2000/11/23 23:45:28 root Exp $";

#include "project.h"



static Byte current_track = 0;
static Word current_length = 0;
static Word current_numtrack = 0;
static Byte current_state = 255;

static void
do_hide_tracks (void)
{
  Word i, index;
  FormPtr ptr;

  ptr = FrmGetFormPtr (CdForm);
  if (!ptr)
    return;

  for (i = 1; i <= CdPbNum; ++i)
    {
      index = FrmGetObjectIndex (ptr, i + CdPbBase);
      if (i <= current_numtrack)
        {
          FrmShowObject (ptr, index);
        }
      else
        {
          FrmHideObject (ptr, index);
        }
    }

}
void
flash_track (Word track)
{
  RectangleType rt;

  if (track < 1)
    return;
  if (track > current_numtrack)
    return;

  if (GetBounds (CdForm, track + CdPbBase, &rt))
    {
      WinInvertRectangle (&rt, 0);
    }
}

void
cd_cmdst_message (Byte unit, Word cmd, Byte * data, Word len)
{
  Word id = FrmGetActiveFormID ();
  if (id != CdForm)
    return;

  if (unit != cdunit)
    return;

  switch (cmd)
    {
    case HIFI_ST_VOL:
      {
        Word v;
        v = data[0] + data[1];
        v = v / 2;
        SliderSet (CdForm, CdVolume, v);
      }
      break;
    case HIFI_ST_CD_STATE:
      {
        Byte st;
        DWord d;
        char buf[80], *ptr;
        int fl = 0;
        RectangleType rt = {
          {CdStLeft, CdStTop},
          {CdStWidth, CdStHeight}
        };

        WinEraseRectangle (&rt, 0);

        ptr = buf;
        if (current_state != data[4])
          {
            if (current_state == HIFI_CD_State_Playing)
              redraw_screen ();
            current_state = data[4];
          }

        switch (current_state)
          {
          case HIFI_CD_State_Stopped:
            ptr += sprintf (ptr, "Stop: ");
            break;
          case HIFI_CD_State_Playing:
            ptr += sprintf (ptr, "Play: ");
            fl++;
            break;
          case HIFI_CD_State_Paused:
            ptr += sprintf (ptr, "Paused: ");
            fl++;
            break;
          case HIFI_CD_State_NoDisc:
            ptr += sprintf (ptr, "NoDisc: ");
            break;
          case HIFI_CD_State_Unknown:
            ptr += sprintf (ptr, "???: ");
            break;
          }

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

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

        SliderSet (CdForm, CdProgress, (Word) d);


        if (current_track)
          {
            flash_track (current_track);
            current_track = 0;
          }
        else
          {
            current_track = data[0];
            flash_track (current_track);
          }


        WinDrawChars (buf, StrLen (buf), CdStLeft, CdStTop);
      }

      break;
    case HIFI_ST_CD_TKSTATE:
      {
        RectangleType rt;


        if (current_numtrack != data[1])
          {
            current_numtrack = data[1];

            do_hide_tracks ();

            redraw_screen ();
            current_track = 0;

          }

        hifipkt_dword (data + 2, &current_length);
      }
      break;


    }


}

#if 0

void
cd_packet (Byte * ptr, int len)
{
  LastStatusPacket = TimGetTicks ();

}

void
status_dispatch ()
{
  RectangleType rt = {
    {StLeft, StTop},
    {StWidth, StHeight}
  };

  if ((TimGetTicks () - LastStatusPacket) > TicksToLose)
    {
      WinEraseRectangle (&rt, 0);
      WinDrawChars ("Lost Contact", 12, StLeft, StTop);
    }
}
#endif

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;

  min = (Byte) (o / 60);
  sec = (Byte) (o % 60);


  buf = ptr = hifi_getbuf ();
  ptr =
    hifipkt_new (ptr, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_CD, cdunit);
  ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_CD_PLAY);
  ptr = hifipkt_ebyte (ptr, current_track);
  ptr = hifipkt_ebyte (ptr, 0); //Index (Ignored)

  ptr = hifipkt_ebyte (ptr, min); //Min

  ptr = hifipkt_ebyte (ptr, sec); //Sec

  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_CD, cdunit);
  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
cd_dispatch (EventType * e)
{
  Err err;
  Byte *cptr, *ptr, *buf;

  switch (e->eType)
    {
    case penDownEvent:
      slider_dispatch (e, CdForm, CdVolume, volume_callback);
      slider_dispatch (e, CdForm, CdProgress, progress_callback);
      break;
    case ctlSelectEvent:

      if ((e->data.ctlEnter.controlID > CdPbBase)
          && (e->data.ctlEnter.controlID <= CdPbMax))
        {

          buf = ptr = hifi_getbuf ();
          ptr =
            hifipkt_new_rel (ptr, HIFI_CLASS_DISPLAY, displayunit,
                             HIFI_CLASS_CD, cdunit);
          ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_CD_PLAY);
          ptr = hifipkt_ebyte (ptr, (e->data.ctlEnter.controlID) - CdPbBase); //Track

          ptr = hifipkt_ebyte (ptr, 0); //Index (Ignored)

          ptr = hifipkt_ebyte (ptr, 0); //Min

          ptr = hifipkt_ebyte (ptr, 0); //Sec

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

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



        }

      switch (e->data.ctlEnter.controlID)
        {
        case CdEjectButton:

          hifi_cmd_rel (NULL, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_CD,
                        cdunit, HIFI_CMD_EJECT);
          break;
        case CdStopButton:
          hifi_cmd_rel (NULL, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_CD,
                        cdunit, HIFI_CMD_STOP);
          break;

        }
      break;

    case frmOpenEvent:
      do_hide_tracks ();
      redraw_screen ();
      current_track = 0;
      SliderSet (CdForm, CdVolume, 0);
      SliderSet (CdForm, CdProgress, 0);
      break;
    }

}
