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

#ifndef _V4LDEV_H
#define _V4LDEV_H

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

#include <float.h>
#include <kdemacros.h>

struct video_channel;
struct video_mmap;
struct video_mbuf;
struct video_clip;

#include "qvideo.h"

#define MAX_CLIP_RECTS 128

/**
 * Abstract interface to Video4Linux devices.
 *
 * @version $Id: v4ldev.h 466968 2005-10-03 20:14:29Z uga $
 */
class QVIDEO_EXPORT V4LDev : public QVideo
{
public:
    virtual ~V4LDev();

    /**
     * Factory method that creates a V4LDev for the specified device
     * file.
     */
    static V4LDev *getDevice( const QString &dev );

    /**
     * Returns true iff this device is a camera.
     */
    virtual bool isCamera() const { return _isCamera; }

    /**
     * Returns true iff this device is a tuner.
     */
    virtual bool isTuner() const { return _isTuner; }

    /**
     * h = -1 => use aspect ratio
     */
    virtual int startCapture(int x, int y);
    virtual int stopCapture();
    virtual bool overlayOn() const;
    virtual QSize grab(unsigned char* img);
    /**
     * Signal strength (usually for tuners)
     */
    virtual int signal() const { return -1; }
    virtual int setCaptureGeometry(const QRect& geom);

    // this finds the largest video that is within the size specified.
    // -1 on error, and uses aspect ratio if h = -1
    virtual int setImageSize(int w, int h = -1);
    virtual int setImageSize(const QSize& sz) { return setImageSize(sz.width(), sz.height()); };
    virtual QSize getMaxImageSize() { return QSize(_maxWidth, _maxHeight); };
    virtual QSize getMinImageSize() { return QSize(_minWidth, _minHeight); };

    virtual QString name() const { return _name; }

    virtual int setBrightness(int x);
    virtual int brightness() const;

    virtual int setColour(int x);
    virtual int colour() const;

    virtual int setHue(int x);
    virtual int hue() const;

    virtual int setContrast(int x);
    virtual int contrast() const;

    virtual int setWhiteness(int x);
    virtual int whiteness() const;

    virtual int setColourKey(unsigned long x);
    virtual unsigned long colourKey() const;

    /**
     * Set source. String must be taken from sources() QStringList.
     * Empty parameter means don't change source.
     */
    virtual int setSource(const QString &source);
    virtual const QString source() const { return _sources[_source]; }
    virtual const QStringList& sources() const { return _sources; }

    /**
     * Set encoding, usually for tuners. String must be taken from encodings() QStringList.
     * Empty parameter means don't change encoding.
     */
    virtual int setEncoding(const QString&) { return 0; } 
    virtual const QString encoding() const { return _encoding; }
    virtual const QStringList& encodings() const { return _encodings; }

    virtual float aspectRatio() const { return _aspectRatio; }

    virtual bool canOverlay() const;
    virtual bool canGrab() const;

    virtual const QStringList& audioModes() { return _audioModes; };
    virtual int   setAudioMode(const QString& mode);
    virtual const QStringList& broadcastedAudioModes();

    virtual int  enableAudio();
    virtual int  disableAudio();
    virtual bool audioEnabled() const;

    virtual int  setVolume(int val);
    virtual int  volume() const;

    virtual int  setBass(int val);
    virtual int  bass() const;

    virtual int  setTreble(int val);
    virtual int  treble() const;

    // Triggers a re-init of the driver to set the new format.  Returns
    // non-zero on error.
    virtual bool setInputFormat(ImageFormat fmt);
    virtual ImageFormat inputFormat() const;

    virtual void addClip(const QRect& clip);
    virtual void clearClips();
    virtual void reClip();

protected:
    V4LDev(int fd, const QString &name, int channels, int type, int minw, int minh, int maxw, int maxh);

    static int qvideoformat2v4lformat(ImageFormat f);

    int initGrabbing();
    void syncCurrentFrame() const;

    int _fd;
    bool _valid;
    QString _name;
    bool _overlaid;
    struct video_channel *_channels;
    int _minWidth, _minHeight, _maxWidth, _maxHeight; // min and max cap dims
    int _type;
    float _aspectRatio;
    int format;
    QMap<QString, int> _audioMap;
    QStringList _audioModes;
    QStringList _broadcastedAudioModes;
    QStringList _sources;
    QStringList _encodings;
    int _source;
    QString _encoding;
    bool _isTuner, _isCamera;
    struct video_mmap *_mmapData;
    struct video_mbuf *_mbuf;
    int _mmapCurrentFrame;
    uchar *_mmapBuf;
    bool _grabNeedsInit;
    uchar *_readBuf;
    int _grabW, _grabH;        // the actual capture dimensions
    bool _disableOverlay;
    int _v4lfmt;
    int _bpp;
    QValueList<QRect> _clips;
    struct video_clip *_cliprecs;
    ImageFormat _qvideofmt;
};

#endif

