/**
    05Robot - Computer Vision Module

    @author P.Kaczmarek,J.Tomczynski,T.Mankowski
    @version 1.0 2017
*/
#ifndef CAMERA_H
#define CAMERA_H

#include <string>
#include <vector>
#include <QObject>
#include <QString>

#include <opencv2/opencv.hpp>
#include <cxmlio.h>
/**
 * \defgroup ComputerVisionModule Computer Vision Module
 * \brief The module groups routines used to build image processing toolchain
 *
 * Contains elements used to build image processing toolchain
 * Main elements are:
 * <ul>
 * <li> Image acquisition subsystem is managed by \ref CameraObject class. The interface of a physical device is created by \ref Camera derived class. The UML model is presented in figure below
 * \image html cameraModel.png "Image acquisition subsystem model."
 * \image latex cameraModel.png "Image acquisition subsystem model."
 * <li> Image processing subsystem managed by \ref ProcessoObject class. The system lets to connect multiple ProcessorObject into the pipeline. The image processing routines are implemented in the class derived from \ref Processor Object, being aggregated by \ProcessorObject. The UML model of this subsystem is presented in figure below
 * \image html processorModel.png "Image processing subsystem model."
 * \image latex processorModel.png "Image processing subsystem model."
 * <li> Synchronization subsystem (SyncObject) enables to synchronize image processing pipelines and synchronous acquisition from multiple sources (i.e. cameras). The UML model is presented in figure below
 * \image html syncObjectModel.png "Synchronization subsystem model."
 * \image latex syncObjectModel.png "Synchronization subsystem model."
 *
 * The synchronization process is controlled by a set of semaphores. The synchronization action diagram and model of interactions is presented in figure below
 * \image html syncModel.png "Synchronization action model"
 * \image latex syncModel.png "Synchronization action model"
 * </ul>
 *
 *
 *
 */
using namespace std;
/** \addtogroup ComputerVisionModule
 *  @{
 */
/**
 @brief Base camera interface class
 */
class Camera : public cXmlIO
{
	Q_OBJECT
    /**
     * @brief Image color type
     */
	Q_PROPERTY(CameraColor CameraColor READ cameraColor WRITE setCameraColor DESIGNABLE true USER true)
	Q_ENUMS(CameraColor)

public:
    /**
     * @brief Image color type enum
     */
    enum CameraColor {
        CameraColor_Mono, /**< Grayscale */
        CameraColor_BGR, /**< Color BGR */
    };
    /**
     * @brief Sets image color type
     */
    void setCameraColor(const CameraColor cameraColor);
    /**
     * @brief Gets image color type
     */
    CameraColor cameraColor() const;

public:
    /**
     @brief Output picture width
     */
	int resultX;
    /**
     @brief Output picture height
     */
	int resultY;
    /**
     @brief Output image buffer
     */
	unsigned char* resultBuffer;
    /**
     @brief Output 2D point buffer
     */
	vector<cv::Point2f> points;
    /**
     @brief Data readout enable flag
     */
	bool readData;

    /**
     @brief Camera name
     */
	QString cameraName;


private:
	CameraColor m_cameraColor;
public:
    /**
     @brief Pixel size in bytes
     */
	int pixelSize;


public:

    Camera();
    /**
     @brief Connects to camera with given ID
     
     @param camera_id ID of camera to connect to
     
     @return Returns 0 on success
     */
    virtual int connect(int camera_id);;
    /**
     @brief Starts acquisition
     */
	virtual int start(){return 1;};
    /**
     @brief Sends software trigger to camera
     
     @return Returns 0 on success
     */
	virtual int sync(){return 1;};
    /**
     @brief Copies current internal buffer to resultBuffer or given output Mat
     
     @param output optional Mat to copy image to
     
     @return Returns 0 on success
     */
    virtual int grab(cv::Mat* output = NULL);;
    /**
     @brief Stops acquisition
     
     @return Returns 0 on success
     */
	virtual int stop(){return 1;};
    /**
     @brief Disconnects from camera
     
     @return Returns 0 on success
     */
	virtual int disconnect(){return 1;};

signals:
	void writeInfo(QString);
};
/** @}*/
#endif
