/*
 * See the README file for copyright information and how to reach the author.
 *
 */

#ifndef __PVRUSB2_DEVICE_H
#define __PVRUSB2_DEVICE_H

#include "common.h"

const int kVideoPid=301;
const int kAudioPid=300;

class cRMScanChannelListener
{
    public:
        virtual void NewChannel(cRMChannelList* _list)=0;
        virtual void ScanFinished()=0;
};

class cRMDevice:
    public cDevice,
    public cListObject
{
    friend class cRMReader;
    friend class cRMScanner;

    private:
        volatile bool dvrOpen;
        volatile bool dvrJustOpened;
        timeval dvrClosedTime;

        int deviceIndex;
        int videoDeviceFD;
        timeval deviceClosedTime;

        cRMReader* reader;
        cRingBufferLinear* tsBuffer;
        cMutex tsBufferMutex;
        int tsPacketCounter;
        int tsPacketLimit;
        int lastAvailable;
        int logCounter;
        bool delivered;

        cRMScanner* scanner;
        cMutex scannerMutex;

    protected:
        // device manipulation and interface functions
        virtual bool SetValue(eSetupItem _item, int _value)=0;
        virtual bool SetValue(eSetupItem _item, const char* _value)=0;

        // helper functions
        virtual bool OpenVideoDevice();
        virtual bool CloseVideoDevice();
        virtual int VideoDeviceFD() { return videoDeviceFD; };
        virtual const char* VideoDeviceName()=0;

        virtual void StopReader();
        virtual bool CheckReader();
        virtual void LogTSBufferState();
        virtual bool Wait4TSBuffer2Fill(int _fillSize);
        virtual void ClearTSBuffer();
        virtual void CleanupTSBuffer();
        virtual bool CheckTSBuffer(uchar* _data, int _count);
        virtual int PutTSData(unsigned char* _data, int _count);
        virtual bool Have2Wait();

        // vdr device plugin interface functions
        virtual bool OpenDvr();
        virtual void CloseDvr();
        virtual bool GetTSPacket(uchar*& _data);
        virtual bool SetPid(cPidHandle* _handle, int _type, bool _on);

    public:
        // initialization
        cRMDevice(int _index);
        virtual ~cRMDevice();

        virtual int Index() { return deviceIndex; };

        virtual bool Setup(cRMSetup* _newSetup);

        virtual bool IsDvrOpen() { return dvrOpen; };
        virtual bool IsReady2Close();

        // vdr device plugin interface functions
        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;
        virtual bool SetChannelDevice(const cChannel* _channel,
                bool _liveView);

        // device interface functions
        virtual int MinValue(eSetupItem _item) const=0;
        virtual int MaxValue(eSetupItem _item) const=0;
        virtual int CurrentValue(eSetupItem _item) const=0;

        virtual int VideoDevice()=0;
        virtual bool SetVideoDevice(int _deviceId)=0;
        virtual bool Tune(int _frequency);
        virtual int Frequency() const; 

        static bool IsPvrUsb2Channel(const cChannel *_channel);
        static cRMChannel* Vdr2PvrChannel(cChannel* _channel);
        static cChannel* Pvr2VdrChannel(cRMChannel* _channel);
        static void Pvr2VdrChannel(cRMChannel* _channel, cChannel* _channel);

        virtual bool StartChannelScan(cRMScanChannelListener* _listener);
        virtual bool StopChannelScan();
};

#endif // __PVRUSB2_DEVICE_H


