#ifndef _PVR_DEVICE_H_
#define _PVR_DEVICE_H_

#include "common.h"

typedef enum {
  videoNormNTSC,
  videoNormSECAM,
  videoNormPAL
  } eVideoNorm;

typedef enum { /* enumeration with encoder states */
  eStop,
  eStart,
} eEncState;

typedef enum {
  eTelevision,
  eRadio,
  eSVideo0,
  eSVideo1,
  eSVideo2,
  eSVideo3,
  eComposite0,
  eComposite1,
  eComposite2,
  eComposite3,
  eComposite4,
  eExternalInput
} eVideoInputs;

typedef enum {
  undef,
  ivtv,
  pvrusb2,
  cx88_blackbird,
} eV4l2Driver;

class cPvrReadThread;

class cPvrDevice :
public cDevice
{
friend class cPvrReadThread;
private:
  static bool Probe(int DeviceNumber);
public:
  static bool Initialize(void);
  static void Stop(void);
  static void ReInitAll(void);
  static int Count();
  static cPvrDevice * Get(int index);

private:
  int number;
  int v4l2_fd;
  int mpeg_fd;
  int radio_fd;
  int v4l2_dev;
  int mpeg_dev;
  int radio_dev;
  int inputs[11];
  int numInputs;
  int frequency;
  int vpid;
  int apid;
  int tpid;
  int VideoNorm;
  int VideoInput;
  cString BusID;
  eEncState    EncoderState;
  eVideoInputs EncoderInput;
  int driver_apiversion;
  bool delivered;
  bool isTuning;
  eV4l2Driver driver;
  cRingBufferLinear * tsBuffer;
  cPvrReadThread    * readThread;

  cMutex mutex;

protected:
  virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
  virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
  virtual bool OpenDvr(void);
  virtual void CloseDvr(void);
  virtual bool GetTSPacket(uchar *&Data);
public:
  cPvrDevice(int DeviceNumber);
  virtual ~cPvrDevice(void);
  virtual int ProvidesCa(const cChannel *Channel) const;
  virtual bool ProvidesSource(int Source) const;
  virtual bool ProvidesTransponder(const cChannel *Channel) const;
  virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, \
                               bool *NeedsDetachReceivers = NULL) const;
  bool ParseChannel(const cChannel *Channel, int *input, int *norm, int *card,
                   eVideoInputs *EncoderInput, int *apid, int *vpid, int *tpid) const;
  void ReInit(void);
  void StopReadThread(void);
  void TurnOffSlicedVBI(void);
  bool Tune(int frequency);
  bool SetInput(int input);
  bool SetVideoNorm(int norm);
  bool SetVideoSize(int width, int height);
  void SetTunerAudioMode(int tuneraudiomode);
  void SetEncoderState(eEncState state);
  bool SetVBImode(int std, int vbistatus);
  // overloaded function SetControlValue
  int  SetControlValue(__u32 control, __s32 Val);
  int  SetControlValue(struct valSet * vs, __s32 Val);
  int  SetControlValue(__u32 control_class, __u32 control, \
                       __s32 Val, struct v4l2_queryctrl queryctrl);
  int  QueryControl(struct valSet * vs);
  bool QueryAllControls(void);
};

int IOCTL(int fd, int cmd, void *data);

#endif
