// -*- c++ -*-

/*
 *
 * Copyright (C) 2002 George Staikos <staikos@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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef __QTVISION_H
#define __QTVISION_H

#include <qmap.h>
#include <qcolor.h>
#include <qobject.h>
#include <qpixmap.h>
#include <qstring.h>
#include <qguardedptr.h>

#include "cfgdata.h"
#include "channel.h"

#include "qtvisioniface.h"
#include "qvsrcplugin.h"
#include "view.h"

class KConfig;

class ViewManager;
class AudioManager;
class OSDManager;
class ChannelStore;
class StatusManager;
class MiscManager;
class PluginFactory;

typedef QMap<QString,QString> DeviceMap;
typedef QMap<QString,QStringList> SourceMap;

/**
 * A reusable TV object.
 */
class QtVision : public QObject, virtual public QtVisionIface
{
    Q_OBJECT

public:
    QtVision( QObject *parent = 0, const char* name = 0);
    ~QtVision();

    /**
     * Returns the current screen widget.
     */
    QtVisionView *screen() { return _view; }

    /**
     * Returns a DCOP reference to the ChannelStore.
     */
    DCOPRef channelStoreIface();

    /**
     * Returns a DCOP reference to the current Channel.
     */
    DCOPRef channelIface();

    /**
     * Returns the name of the current Channel.
     */
    QString channelName() const;

    /**
     * Returns the number of the current Channel.
     */
    int channelNumber() const;

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

    /**
     * Returns the current video device (or 0).
     */
    QVSourcePlugin *device() const { return _vsrc; }

    /**
     * Returns the manager controlling the views.
     */
    ViewManager *views() const { return _viewmng; }

    /**
     * Returns the audio manager.
     */
    AudioManager *audioManager() const { return _am; }

    /**
     * Returns the OSD manager.
     */
    OSDManager *osdManager() const { return _osd; }

    /**
     * Returns the miscellaneous plugin manager.
     */
    MiscManager *miscManager() const { return _mm; }

    /**
     * Returns the status plugin manager.
     */
    StatusManager *statusManager() const { return _sm; }

    /**
     * Returns the plugin factory.
     */
    PluginFactory *pluginFactory() const { return _pf; }

    /**
     * Returns current ChannelStore.
     */
    ChannelStore *channels() { return _cs; }

    /**
     * Returns the current configuration.
     */
    ConfigData *config() const { return _cfg; }
    
    /**
     * Returns the KConfig objectg for this instance.
     */
    KConfig *configHandle () const { return _config; }

    /**
     * Factory method for creating the screen the picture will be displayed
     * on. This widget returned will depend on the facilities supported by
     * the TV card and X server (eg. there will be special screen widgets
     * for Xv support). Note that this widget is automatically made the
     * screen for this QtVision object.
     */
    virtual QtVisionView *createScreen( QWidget *parent=0, const char *name=0 );

    /**
     * To get various values.
     */
    int brightness();
    int colour();
    int hue();
    int contrast();
    int whiteness();
    QColor colourKey();
    Channel *channel() { return _chan; }

public slots:
    /**
     * Try to start using the previous device. Returns true iff it succeeds.
     */
    bool tryAutoStart();

    /**
     * Ask the user to select a device.
     */
    virtual void selectDevice();

    /**
     * Set the current video device.
     */
    void setDevice( QVSourcePlugin *dev );

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

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

    /**
     * Sets the current current channel.
     */
    void setChannel( Channel *channel );

    /**
    * Overloaded version of the above method
    */
    void setChannel(int channel);
    
    
    /**
     * Changes the channel to the one preceding the current, wrapping
     * round if we are currently showing the first channel.
     */
    virtual void channelDown();

    /**
     * Changes the channel to the one following the current, wrapping
     * round if we are currently showing the last channel.
     */
    virtual void channelUp();
    
    /**
     * Recalls the previous channel.
     */
    virtual void previousChannel();

    /**
     * Mutes and unmutes the sound.
     */
    virtual void volumeMute();

    /**
     * Increases the volume.
     */
    virtual void volumeUp();

    /**
     * Decreases the volume.
     */
    virtual void volumeDown();

    /**
     * Sets the volume
     */
    virtual void setVolume(int left, int right);
    virtual void setVolume(int vol);

    virtual void start();
    virtual void stop();
    virtual void startCapture();
    virtual void snapshot();

    virtual void startVideo();
    virtual void stopVideo();

    /**
     * Launches the settings dialog.
     */
    virtual void settings();

    /**
     * Launches the channel wizard and returns the dialog return value.
     */
    virtual int launchWizard();

    /**
     * Sets the tuner mode (PAL, NTSC etc.).
     */
    void setTunerMode( int mode );

    /**
     * Set various attributes on the current device.
     */
    virtual void setBrightness(int val);
    virtual void setColour(int val);
    virtual void setHue(int val);
    virtual void setContrast(int val);
    virtual void setWhiteness(int val);

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

    /**
     *  Do migration from kwintv to qtvision
     */
    virtual bool doMigration();

    /**
     *  Shows the dialog to allow the user to import default channel lists.
     */
    virtual void importDefaultChannels();

    /**
     *  Imports the old KWinTV channels if they exist.
     */
    virtual bool importLegacyChannels();

    /**
     *  Open a file dialog to allow the user to choose a new channel file.
     */
    virtual void openChannelFile();

    /**
     *  Open a file dialog to allow the user to add the channels from a file
     *  to the channel list.
     */
    virtual void importChannelFile();

    /**
     *  Open the provided filename and read in the channels.
     */
    virtual void openChannelFile(const QString &filename);

    /**
     * Process the press of a number key (0-9) from keyboard, or lirc.
     */
    virtual void processNumberKeyEvent(int);

signals:
    /**
     * Emitted when the volume changes
     */
    void volumeChanged( int left, int right );
    
    /**
     * Emitted whenever the volume is mutted.
     */
    void volumeMuted(bool);

    /**
     * Emitted when the current channel changes.
     */
    void channelChanged( int num );

    /**
     * Emitted when the current channel changes.
     */
    void channelChanged( const QString &name );

    /**
     * Emitted when the current channel changes.
     */
    void channelChanged( Channel *channel );

    /**
     * Emitted when the video device changes.
     */
    void deviceChanged( QVSourcePlugin *dev );

    /**
     * Emitted when the channel text changes during setting channel with numeric keys.
     */
    void channelText(const QString &);

protected:
    void timerEvent (QTimerEvent *ev);
    
private slots:
    void viewResized(int w, int h);
    void viewMoved(int x, int y);
    void aboutToQuit();
    
    /** Mute/Unmute volume... */
    void setMuteVolume (bool);

    void slotKeyPressTimeout();
    
private:
    ChannelStore *_cs;
    
    QGuardedPtr<Channel> _chan;
        
    OSDManager *_osd;    
    AudioManager *_am;    
    StatusManager *_sm;
    MiscManager *_mm;
    QtVisionView *_view;
    PluginFactory *_pf;
    QVSourcePlugin *_vsrc;
    ViewManager *_viewmng;
    ConfigData* _cfg;
    KConfig* _config;
    QPixmap grabPix;
    
    QTimer *_keypresstimer;
    QString _number;
    
    int _prevChannel;
    
    bool _muted;    // We have to keep track since some devices are broken    
    bool _quitting;

    struct { 
        int left; // Left volume
        int right; // Right volume
        int changeEventId; // Id 
    } ChannelVolState;

    class QtVisionPrivate;
    QtVisionPrivate *d;
};

#endif

