/*  This file is part of the KDE project
    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library 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 library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#ifndef PHONON_MIXER_P_H
#define PHONON_MIXER_P_H

#include "mixer.h"
#include <QtCore/QByteArray>
#include <QtCore/QExplicitlySharedDataPointer>
#include <QtCore/QSharedData>
#include "defs_p.h"

#include <alsa/asoundlib.h>

namespace Phonon
{
namespace Mixer
{

class AlsaNotifier;
class AlsaControl;
class MixerControl;
class MixerSharedData : public QObject, public QSharedData
{
    friend class Mixer;
    friend class MixerPrivate;
    friend class MixerControlSharedData;
    friend class MixerControlSet;
    Q_OBJECT
    public:
        typedef QExplicitlySharedDataPointer<MixerSharedData> Ptr;
        ~MixerSharedData();
        bool operator==(const QVariant &) const;
        bool operator==(Mixer::Type) const;
        bool isValid() const;
        QList<MixerControl> controls() const;
        AlsaControl *ctl() const;

    Q_SIGNALS:
        void mixerControlAdded(const MixerControl &);
        void mixerControlRemoved(const MixerControl &);

    private Q_SLOTS:
        void eventReady();

    private:
        MixerSharedData(const QVariant &mixerDeviceId);
        MixerSharedData(Mixer::Type type);
        QString name() const;
        MixerControlSet controlSetFor(const QString &name);

        void init();
        void cleanup();
        void updateControls();

        mutable AlsaControl *m_ctl;
        mutable AlsaNotifier *m_notifier;
        int m_cardNumber;
        mutable QString m_name;
        mutable QList<MixerControl> m_controls;
        mutable QHash<QString, MixerControlSet> m_controlSets;
};

class MixerPrivate
{
    friend class MixerControlSet;
    friend uint ::qHash(const Phonon::Mixer::Mixer &);
    Q_DECLARE_PUBLIC(Mixer)
    K_DECLARE_SHARED(Mixer)
    protected:
        static bool isValidDeviceId(const QVariant &mixerDeviceId);
        static MixerSharedData::Ptr getSharedData(const QVariant &mixerDeviceId);
        static MixerSharedData::Ptr getSharedData(Mixer::Type type);

        Mixer *q_ptr;

        MixerSharedData::Ptr s_ptr;
};

} // namespace Mixer
} // namespace Phonon
#endif // PHONON_MIXER_P_H
