//=========================================================
//  MusE
//  Linux Music Editor
//    $Id: audioconf.cpp,v 1.1.1.1 2003/10/29 10:06:28 wschweer Exp $
//  (C) Copyright 2001 Werner Schweer (ws@seh.de)
//=========================================================

#include <qlabel.h>
#include <qbuttongroup.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qcombobox.h>
#include <qgroupbox.h>

#include "globals.h"
#include "config.h"
#include "audioconf.h"
#include "driver/audiodev.h"
#include "driver/alsaaudio.h"
#include "song.h"
#include "seq.h"
#include "mixer/amixer.h"
#include "audio.h"
#include "app.h"

#if HAVE_JACK_JACK_H
#include "driver/jackaudio.h"
#endif

static int srate[] = { 44100, 48000, 96000 };
static int framesize[] = {
      32, 64, 128, 256, 512, 1024, 2048, 4096
      };

//---------------------------------------------------------
//   AudioConf
//    comboDelay
//    comboSampleRate
//    comboFrameSize
//    buttonRecord   (button group)
//    comboDevice
//---------------------------------------------------------

AudioConf::AudioConf(QWidget* parent, const char* name)
   : AudioConfBase(parent, name, true)
      {
      updateValues();

      connect(buttonApply, SIGNAL(clicked()), SLOT(apply()));
      connect(comboDelay, SIGNAL(activated(int)), SLOT(delayChanged(int)));
      connect(comboFrameSize, SIGNAL(activated(int)), SLOT(frameSizeChanged(int)));
      connect(comboSampleRate, SIGNAL(activated(int)), SLOT(sampleRateChanged(int)));
      connect(useAlsaButton, SIGNAL(toggled(bool)), SLOT(useAlsaButtonToggled(bool)));
      }

//---------------------------------------------------------
//   updateValues
//---------------------------------------------------------

void AudioConf::updateValues()
      {
#if HAVE_JACK
      if (useJackAudio) {
            useJackButton->setChecked(true);
            }
      else if (useAlsaAudio) {
            useAlsaButton->setChecked(true);
            }
      else {
            noAudioButton->setChecked(true);
            }
      useJackButton->setEnabled(!noJack);
#else
      if (useAlsaAudio) {
            useAlsaButton->setChecked(true);
            }
      else {
            noAudioButton->setChecked(true);
            }
      useJackButton->setEnabled(false);
#endif

      useAlsaButton->setEnabled(!noAlsa);

      if (audioDevice)
            labelStatus->setText(audioDevice->state());

      int idx;
      switch(sampleRate) {
            case 44100: idx = 0; break;
            case 48000: idx = 1; break;
            case 96000: idx = 2; break;
            default:
                  printf("illegal sample Rate %d\n", sampleRate);
                  exit(-1);
            }
      comboSampleRate->setCurrentItem(idx);

      switch(segmentSize) {
            case 32:    idx = 0; break;
            case 64:    idx = 1; break;
            case 128:   idx = 2; break;
            case 256:   idx = 3; break;
            case 512:   idx = 4; break;
            case 1024:  idx = 5; break;
            case 2048:  idx = 6; break;
            case 4096:  idx = 7; break;
            default:
                  printf("illegal segment size %d\n", segmentSize);
                  exit(-1);
            }
      comboFrameSize->setCurrentItem(idx);

      for (int i = 0; i < 8; ++i) {
            QString s;
            s.sprintf("%.2f", (double(framesize[i]) / double(sampleRate)) * 1000.0);
            comboDelay->insertItem(s, i);
            }
      comboDelay->setCurrentItem(idx);
      }

//---------------------------------------------------------
//   delayChanged
//---------------------------------------------------------

void AudioConf::delayChanged(int val)
      {
      comboFrameSize->setCurrentItem(val);
      }

//---------------------------------------------------------
//   frameSizeChanged
//---------------------------------------------------------

void AudioConf::frameSizeChanged(int val)
      {
      comboDelay->setCurrentItem(val);
      }

//---------------------------------------------------------
//   sampleRateChanged
//---------------------------------------------------------

void AudioConf::sampleRateChanged(int val)
      {
      double sr = double(srate[val]);
      comboDelay->clear();
      for (int i = 0; i < 8; ++i) {
            QString s;
            s.sprintf("%.2f", (double(framesize[i]) / sr) * 1000.0);
            comboDelay->insertItem(s, i);
            }
      comboDelay->setCurrentItem(comboFrameSize->currentItem());
      }

//---------------------------------------------------------
//   accept
//---------------------------------------------------------

void AudioConf::accept()
      {
      apply();
      AudioConfBase::accept();
      }

//---------------------------------------------------------
//   apply
//---------------------------------------------------------

void AudioConf::apply()
      {
      // switch between ALSA and JACK
      int curMode = 0;
      if (useJackAudio)
            curMode = 1;
      if (useAlsaAudio)
            curMode = 2;

      int mode = 0;
      if (useAlsaButton->isChecked())
            mode = 2;
      if (useJackButton->isChecked())
            mode = 1;

      seq->stop();
      if (curMode != mode) {
            if (curMode == 1) {
                  // switch off JACK
#if HAVE_JACK_JACK_H
                  jackAudioDevice->activate(false);
#endif
                  }
            else if (curMode == 2) {
                  // switch off ALSA
                  alsaAudioDevice->activate(false);
                  }
            audioDevice  = 0;
            useJackAudio = false;
            useAlsaAudio = false;
            if (mode == 0) {
                  noAudio = true;
                  audioTimebase = false;
                  }
#if HAVE_JACK_JACK_H
            else if (mode == 1) {
                  // switch on JACK
                  useJackAudio = true;
                  jackAudioDevice->activate(true);
                  audioDevice = jackAudioDevice;
                  noAudio = false;
                  }
#endif
            else if (mode == 2) {
                  // switch on ALSA
                  useAlsaAudio = true;
                  alsaAudioDevice->activate(true);
                  audioDevice = alsaAudioDevice;
                  noAudio = false;
                  }
            if (audioMixer)
                  audioMixer->updateMixer();

            }
      int frameSizeIndex = comboFrameSize->currentItem();
      int sampleIndex    = comboSampleRate->currentItem();
      int frameSize      = framesize[frameSizeIndex];
      int sR             = srate[sampleIndex];

      if ((segmentSize != frameSize) || (sR != sampleRate)) {
            segmentSize = frameSize;
            sampleRate  = sR;
            }
      muse->enableAudio(!noAudio);
      song->update();  // ??
      updateValues();  // show real values set
      seq->start();
      }

//---------------------------------------------------------
//   useAlsaButtonToggled
//---------------------------------------------------------

void AudioConf::useAlsaButtonToggled(bool val)
      {
      comboFrameSize->setEnabled(val);
      comboDelay->setEnabled(val);
      comboSampleRate->setEnabled(val);
      }

