#ifndef _PVR_DEVICE_H_
#define _PVR_DEVICE_H_

#include <vdr/device.h>
#include <linux/types.h>

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

typedef enum {
  eRadio,
  eTelevision,
  eExternalInput
} eEncSwitch;

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


class cPvrReadThread;

class cPvrDevice : public cDevice {
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 video_fd;
  int radio_fd;
  int vbi_fd;
  int radioDevice;
  int inputs[11];
  int frequency;
  int vpid;
  int apid;
  int tpid;
  int VideoNorm;
  int VideoInput;
  eEncState  EncoderState;
  eEncSwitch EncoderSwitch;
  int IVTV_apiversion;

  bool dvrOpen;
  bool delivered;
  bool isTuning;

  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);
  void ReInit(void);
  bool Tune(int frequency);
  bool SetInput(int input);
  bool SetVideoNorm(int norm);
  bool SetVideoSize(int width, int height);
  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
