#ifndef CAMERA_H
#define CAMERA_H

#ifdef __CINT__
typedef unsigned long int pthread_t;
struct pthread_mutex_t;
struct pthread_cond_t;
struct timeval;
#else
#include <TROOT.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#endif


typedef unsigned char byte;

class Camera
{
private:
    //
    // Geometry
    //
    static const int cols  = 768;
    static const int rows  = 576;
    static const int depth = 3;

    //
    // Hardware Descriptors
    //
    int fd;
    int iBufferSize;
    int iOffsets[2];

    char *pMapBuffer;

    //
    // Thread interface
    //
    unsigned long fNum;

    int fStop;
    int fRunning;

    char fImg[cols*rows];
    struct timeval fTime;

    pthread_t       fThread;
    pthread_mutex_t fMux;
    pthread_cond_t  fCond;

    //
    // Hardware dependant functions
    //
    static void SigAlarm(int signal);

    int  Ioctl(int req, void *opt, const char *str=NULL);

    void SigInit();
    void Error(const char *str, int fatal=true);

    int  StartGrab(unsigned int frame);

    char *GetImg(unsigned int frame);

    //
    // Execution thread which processes the pictures
    //
    void Thread();
    static void *MapThread(void *arg);

    void LoopStep(const unsigned long n);

public:
    Camera();
    virtual ~Camera();

    //
    // Starts, stops the execution
    //
    void Loop(const unsigned long nof=0);
    void ExitLoop()
    {
        fStop = 1;
        while (IsRunning())
            usleep(1);
    }

    //
    // flag if the execution is running or not
    //
    int IsRunning() const { return fRunning; }

    //
    // Execution of one frame - this function may be overloaded!
    //
    virtual void ProcessFrame(const unsigned long n,
                              byte *img, struct timeval *tm);

    //
    // hardware features
    //
    void SetPicPar(int  bright, int  hue, int  contrast);
    void GetPicPar(int *bright, int *hue, int *contrast);

    ClassDef(Camera, 0)
};

#endif
