/*
 * KMix -- KDE's full featured mini mixer
 *
 *
 * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
 * 1996-2000 Christian Esken <esken@kde.org>
 * Sven Fischer <herpes@kawo2.rwth-aachen.de>
 * 2002 - Helio Chissini de Castro <helio@conectiva.com.br>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef MIXER_H
#define MIXER_H

#include <tqstring.h>
#include <tqtimer.h>
#include <tqobject.h>
#include <tqintdict.h>
#include <tqptrlist.h>

#include "volume.h"
class Mixer_Backend;
#include "mixerIface.h"
#include "mixset.h"
#include "mixdevice.h"

class Volume;
class TDEConfig;

class Mixer : public TQObject, virtual public MixerIface
{
      Q_OBJECT
  

   public:
      enum MixerError { ERR_PERM=1, ERR_WRITE, ERR_READ, ERR_NODEV, ERR_NOTSUPP,
			ERR_OPEN, ERR_LASTERR, ERR_NOMEM, ERR_INCOMPATIBLESET, ERR_MIXEROPEN };

      Mixer( int driver, int device );
      virtual ~Mixer();

      static int numDrivers();

      MixDevice* find(TQString& devPK);

      void volumeSave( TDEConfig *config );
      void volumeLoad( TDEConfig *config );

       /// Tells the number of the mixing devices
      unsigned int size() const;
      
      bool isValid();
      bool isOpen() const;
      
      /// Returns a pointer to the mix device with the given number
      MixDevice* operator[](int val_i_num);

      /// Returns a pointer to the mix device whose type matches the value
      /// given by the parameter and the array MixerDevNames given in
      /// mixer_oss.cpp (0 is Volume, 4 is PCM, etc.)
      MixDevice *mixDeviceByType( int deviceidx );

      /// Open/grab the mixer for further intraction
      virtual int open();
      /// Close/release the mixer
      virtual int close();

      /// Returns a detailed state message after errors. Only for diagnostic purposes, no i18n.
      TQString& stateMessage() const;

      virtual TQString mixerName();
      virtual int devnum();

      // Returns the name of the driver, e.g. "OSS" or "ALSA0.9"
      static TQString driverName(int num);

      /// Returns an unique ID of the Mixer. It currently looks like "<soundcard_descr>:<hw_number>@<driver>"
      TQString& id();
      /// The owner/creator of the Mixer can set an unique name here. This key should never displayed to
      /// the user, but can be used for referencing configuration items and such.
      void setID(TQString& ref_id);

      /// The KMix global master card. Please note that KMix and KMixPanelApplet can have a
      /// different MasterCard's at the moment (but actually KMixPanelApplet does not read/save this yet).
      /// At the moment it is only used for selecting the Mixer to use in KMix's DockIcon.
      static void setMasterCard(const TQString& ref_id);
      static Mixer* masterCard();
      /// The global Master Device inside the current MasterCard (as returned by masterCard()).
      static void setMasterCardDevice(const TQString &ref_id);
      static MixDevice* masterCardDevice();


      /// get the actual MixSet
      MixSet getMixSet();

      /// Returns the master volume device (doesn't work out :-(. See masterCard() and masterCardDevice() instead)
      MixDevice* masterDevice();
      /// Sets the master volume device (doesn't work out :-(. See setMasterCard() and setMasterCardDevice() instead)
      void setMasterDevice(TQString&);

      /// DCOP oriented methods (look at mixerIface.h for the descriptions)
      void setVolume( int deviceidx, int percentage );
      void setAbsoluteVolume( int deviceidx, long absoluteVolume );
      void setMasterVolume( int percentage );

      void increaseVolume( int deviceidx, int percentage );
      void decreaseVolume( int deviceidx, int percentage );

      long absoluteVolume( int deviceidx );
      long absoluteVolumeMin( int deviceidx );
      long absoluteVolumeMax( int deviceidx );
      int volume( int deviceidx );
      int masterVolume();
      int masterDeviceIndex();

      void setMute( int deviceidx, bool on );
      void setMasterMute( bool on );
      bool mute( int deviceidx );
      bool masterMute();
      void toggleMute( int deviceidx );
      void toggleMasterMute();
      bool isRecordSource( int deviceidx );

      bool isAvailableDevice( int deviceidx );

      void commitVolumeChange( MixDevice* md );

   public slots:
      virtual void readSetFromHW();
      void readSetFromHWforceUpdate() const;
      virtual void setRecordSource( int deviceidx, bool on );

      virtual void setBalance(int balance); // sets the m_balance (see there)

   signals:
      void newBalance( Volume& );
      void newRecsrc( void );
      void newVolumeLevels(void);

   protected:
      TQTimer* _pollingTimer;

      int m_balance; // from -100 (just left) to 100 (just right)

      TQPtrList<MixSet> m_profiles;
      static TQPtrList<Mixer> s_mixers;

   public:
      int setupMixer( MixSet set );
      static TQPtrList<Mixer>& mixers();

   private:
     Mixer_Backend *_mixerBackend;
      mutable bool _readSetFromHWforceUpdate;
      static int _dcopID;
      TQString _id;
      TQString _masterDevicePK;
      static TQString _masterCard;
      static TQString _masterCardDevice;
};

#endif
