
/*
 * tuner.c:
 *
 * Copyright (c) 2000 James McKenzie <james@fishsoup.dhs.org>.
 * All rights reserved.
 *
 * $Log: tuner.c,v $
 * Revision 1.15  2001/10/12 13:51:17  root
 * #
 *
 * Revision 1.14  2001/01/30 06:16:31  root
 * #
 *
 * Revision 1.13  2000/12/01 04:42:19  root
 * #
 *
 * Revision 1.12  2000/12/01 04:13:52  root
 * #
 *
 * Revision 1.11  2000/11/23 23:45:28  root
 * #
 *
 * Revision 1.10  2000/10/07 18:30:10  root
 * #
 *
 * Revision 1.9  2000/10/06 19:52:45  root
 * #
 *
 * Revision 1.8  2000/09/29 11:07:42  root
 * #
 *
 * Revision 1.7  2000/09/29 07:53:48  root
 * #
 *
 * Revision 1.6  2000/09/29 07:53:02  root
 * #
 *
 * Revision 1.5  2000/09/24 01:48:14  root
 * #
 *
 * Revision 1.4  2000/09/24 01:12:53  root
 * #
 *
 * Revision 1.3  2000/09/19 09:36:01  root
 * #
 *
 * Revision 1.2  2000/02/20 03:16:39  root
 * #
 *
 * Revision 1.1  2000/02/20 02:51:44  root
 * #
 *
 * Revision 1.1  2000/02/16 11:34:56  root
 * #
 *
 *
 */

static char rcsid[] =
  "$Id: tuner.c,v 1.15 2001/10/12 13:51:17 root Exp root $";

#include "project.h"


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_TUNER,
                 tunerunit);
  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);

}

DWord off_to_freq (int i)
{
  DWord ret;

  ret = i;
  ret *= (1080000 - 880000);
  ret += 88000000;

  return ret;

}

int
freq_to_off (DWord ret)
{

  ret -= 88000000;
  ret = ret / (1080000 - 880000);

  return (int) ret;
}

void
tuner_empty_message (int msg)
{
  Byte *cptr, *ptr, *buf;

  buf = ptr = hifi_getbuf ();
  ptr =
    hifipkt_new_rel (ptr, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_TUNER,
                     tunerunit);
  ptr = hifipkt_ecmd (cptr = ptr, msg);
  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
tuner_tune (DWord f, int band, int rel)
{
  Hifi_Radio_Frequency rf;
  Byte *cptr, *ptr, *buf;

  buf = ptr = hifi_getbuf ();
  if (rel)
    {
      ptr =
        hifipkt_new_rel (ptr, HIFI_CLASS_DISPLAY, displayunit,
                         HIFI_CLASS_TUNER, tunerunit);
    }
  else
    {
      ptr =
        hifipkt_new (ptr, HIFI_CLASS_DISPLAY, displayunit, HIFI_CLASS_TUNER,
                     tunerunit);

    }
  ptr = hifipkt_ecmd (cptr = ptr, HIFI_CMD_TUNER_TUNE);
  rf.band = band;
  rf.freq = f;
  ptr = hifipkt_eradio_frequency (ptr, rf);
  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
slider_callback (Word formid, Word sliderid, int v)
{

  tuner_tune (off_to_freq (v), HIFI_TUNER_Band_FM, 0);
}

void
tuner_dispatch (EventType * e)
{
  switch (e->eType)
    {
    case penDownEvent:
      slider_dispatch (e, TunerForm, TunerVolume, volume_callback);
      slider_dispatch (e, TunerForm, TunerDial, slider_callback);
      break;

    case ctlSelectEvent:
      switch (e->data.ctlEnter.controlID)
        {
        case TunerOffButton:
          tuner_tune (HIFI_TUNER_Freq_Mute, 0, 1);
          break;
        case TunerR1Button:
          tuner_tune (98500000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerR2Button:
          tuner_tune (88900000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerR3Button:
          tuner_tune (91100000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerR4Button:
          tuner_tune (93300000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerCambButton:
          tuner_tune (96000000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerQ103Button:
          tuner_tune (103000000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerVibeButton:
          tuner_tune (105600000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerCafeButton:
          tuner_tune (107900000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerCFMButton:
          tuner_tune (101900000L, HIFI_TUNER_Band_FM, 1);
          break;
        case TunerDownButton:
          tuner_empty_message (HIFI_CMD_TUNER_SEARCH_DOWN);
          break;
        case TunerUpButton:
          tuner_empty_message (HIFI_CMD_TUNER_SEARCH_UP);
          break;
        case TunerMonoButton:
          tuner_empty_message (HIFI_CMD_TUNER_MONO);
          break;
        case TunerStereoButton:
          tuner_empty_message (HIFI_CMD_TUNER_STEREO);
          break;
        }
      break;

    case frmOpenEvent:
      SliderSet (TunerForm, TunerDial, 0);
      SliderSet (TunerForm, TunerVolume, 0);
      break;
    }


}

void
tuner_cmdst_message (Byte unit, Word cmd, Byte * data, Word len)
{
  Word id = FrmGetActiveFormID ();
  if (id != TunerForm)
    return;
  if (unit != tunerunit)
    return;


  switch (cmd)
    {
    case HIFI_ST_VOL:
      {
        Word v;
        v = data[0] + data[1];
        v = v / 2;
        SliderSet (TunerForm, TunerVolume, v);
      }
      break;
    case HIFI_ST_TUNER_STATE:
      {
        RectangleType rt = { {TunerStLeft, TunerStTop}
        , {TunerStWidth, TunerStHeight}
        };
        char buf[80], *ptr = buf;
        Hifi_Tuner_State s;

        data = hifipkt_dtuner_state (data, &s);

        WinEraseRectangle (&rt, 0);

        if (s.f.freq > 1000000)
          {
            DWord f = s.f.freq / 1000000;
            DWord r = s.f.freq - (f * 1000000);
            r = r / 1000;

            ptr += sprintf (ptr, "Freq %3d.%03dMHz ", (int) f, (int) r);
          }
        else
          {
            DWord f = s.f.freq / 1000;
            DWord r = s.f.freq - (f * 1000);
            r = r / 100;

            ptr += sprintf (ptr, "Freq %3d.%1dkHz ", (int) f, (int) r);
          }

        SliderSet (TunerForm, TunerDial, freq_to_off (s.f.freq));

        if (s.lock)
          {
            ptr += sprintf (ptr, "[ locked  ] ");
          }
        else
          {
            ptr += sprintf (ptr, "[no signal] ");
          }

        if (s.stereo)
          {
            ptr += sprintf (ptr, "[stereo]");
          }
        else
          {
            ptr += sprintf (ptr, "[ mono ]");
          }


        WinDrawChars (buf, StrLen (buf), TunerStLeft, TunerStTop);
      }

      break;
    }


}
