// -*- c++ -*-
/***************************************************************************
                           sourcemanager.h
                           ---------------
    begin                : Sun Sep 21 2003
    copyright            : (C) 2003, 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library 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 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 Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef _SOURCEMANAGER_H
#define _SOURCEMANAGER_H

#include <qobject.h>
#include <qmap.h>
#include <qstring.h>
#include <qstringlist.h>

#include "controlinterface.h"
#include "libkdetv_export.h"

class KdetvSourcePlugin;
class PluginDesc;
class PluginFactory;
class QWidget;
class QTimer;
class QImage;
class Channel;
class QDialog;

class SourceManager : public QObject
{
    Q_OBJECT


public:
    /// Viewmode hints
    typedef enum {
        Windowed,
        Fullscreen
    } ViewModeHint;

    /**
     * List of all available devices
     */
    const QStringList& deviceList() const                  { return _devices;                    };

    /**
     * List of all sources of a device
     */
    const QStringList& sourcesFor(const QString& device)   { return _deviceSourcesMap[device];   };

    /**
     * List of all encodings for a devices
     */
    const QStringList& encodingsFor(const QString& device) { return _deviceEncodingsMap[device]; };

    /**
     * Is the device a tuner?
     */
    bool         isTuner(const QString& device)      { return _deviceTunerMap[device];     };

    /**
     * Returns true iff we have a video device.
     */
    bool hasDevice() const { return _vsrc ? true : false; }

    /**
     * Returns the current video device name (or empty string).
     */
    const QString& device() const { return _dev; };

    /**
     * Returns the current video source (or empty string).
     */
    const QString& source() const { return _src; };

    /**
     * Returns the current video encoding (or empty string).
     */
    const QString& encoding() const { return _enc; };

    /**
     * Audiomodes for currently selected device and source.
     */
    LIBKDETV_EXPORT const QStringList& audioModes() const;

    /**
     * Returns current frequency.
     */
    qulonglong frequency();

    /**
     * Returns signal strength.
     */
    int signal();

    /**
     * Currently active audio mode (does not have to be the last one that was set)
     */
    LIBKDETV_EXPORT const QString audioMode() const;

    /**
     * Video source's colour key.
     */
    QColor colourKey();

    /**
     * Controls
     */
    const Control::ControlList& controls();

    /**
     *  Set video desktop on or off
     */
    LIBKDETV_EXPORT bool setVideoDesktop(bool on);

    /**
     * Can current device display video on desktop background?
     */
    bool canVideoDesktop() const;

    /**
     * Can current device grab still images?
     */
    bool canGrabStill() const;

    LIBKDETV_EXPORT bool supportsImageFiltering() const;

    /**
     * Creates a channel with default channel properties (analog <-> DVB)
     */
    Channel* createChannel(QObject* parent);

    /**
     * Return appropriate properties dialog for channel (analog <-> DVB)
     */
    QDialog* channelPropertiesDialog(Channel* channel, QWidget* parent);


public slots:
    /**
     * Set the current video device.
     */
    bool setDevice( const QString& dev );

    /*
     * Sets a channel (all properties)
     */
    bool setChannel( const Channel& channel );

    /**
     * Sets the source to use.
     */
    bool setSource( const QString &src );

    /**
     * Sets the tuner mode.
     */
    bool setEncoding( const QString& encoding );

    /**
     * Select audio mode.
     */
    bool setAudioMode( const QString& audioMode );

    /**
     * Stop the current device and dispose it.
     */
    void stopDevice();

    /**
     * Sets desired frequency.
     */
    bool setFrequency(qulonglong freq);

    /**
     * Start video playback.
     */
    bool startVideo();

    /**
     * Stop video playback.
     */
    bool stopVideo();

    /**
     * Hint for current video playback mode
     * (e.g. to change resolution)
     */
    virtual void viewModeHint(ViewModeHint);

    /**
     * Loads all enabled video plugins and scans for devices, sources and encodings.
     */
    void scanPlugins();

    /**
     * Mute/unmute video source.
     */
    bool setMuted(bool);

    /**
     * Set volume (range [0..100]).
     */
    bool setVolume(int left, int right);

    /**
     * Write still picture to buffer
     */
    bool snapshot(QImage&);


signals:
    /**
     * Emitted when plugins were rescanned.
     */
    void devicesChanged();

    /**
     * Emitted before device is changed.
     */
    void aboutToChangeDevice();

    /**
     * Emitted when the video device changes.
     */
    void deviceChanged( const QString& dev );
    void colourKeyChanged( QColor );

    /**
     * Emitted before source is changed.
     */
    void aboutToChangeSource();

    /**
     * Emitted when the video device changes.
     */
    void sourceChanged( const QString& src );

    /**
     * Emitted before encoding is changed.
     */
    void aboutToChangeEncoding();

    /**
     * Emitted when the video device changes.
     */
    void encodingChanged( const QString& enc );

    /**
     * Emitted when audio mode changes.
     */
    void audioModeChanged(const QString& mode);

    /**
     * Emitted when the frequency device changes.
     */
    void frequencyChanged(qulonglong freq );

    /**
     * Emitted when video playback state changes.
     */
    void playbackChanged(bool);


protected slots:
    void checkAudioMode();
    void errorMessage(const QString& msg);


private:
    friend class Kdetv;
    SourceManager(PluginFactory*, QWidget*);
    ~SourceManager();

    void setScreen(QWidget*);

    QStringList                _devices;
    QMap<QString, PluginDesc*> _devicePluginMap;
    QMap<QString, QStringList> _deviceSourcesMap;
    QMap<QString, QStringList> _deviceEncodingsMap;
    QMap<QString, bool>        _deviceTunerMap;

    QString            _dev;
    QString            _src;
    QString            _enc;
    QString            _audioMode;
    KdetvSourcePlugin* _vsrc;

    ViewModeHint    _lastViewModeHint;

    QTimer*         _audioModeTimer;

    QWidget*       _screen;
    PluginFactory* _pf;
};

#endif

