/**
    05Robot - Computer Vision Module

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

#include "Processor.h"

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>

#include <QDebug>
/** \addtogroup ComputerVisionModule
 *  @{
 */
/**
 @brief Perspective correction image processor
 
 Calculates perspective correction based on a chessboard placed in the workspace, performs perspective correction accordingly.
 */
class Processor_PlaneCalibration: public Processor
{
	Q_OBJECT
    /**
     @brief Number of chessboard internal columns (crossings)
     */
    ADD_PROPERTY(checkerboard_columns, int)
    /**
     @brief Number of chessboard internal rows (crossings)
     */
    ADD_PROPERTY(checkerboard_rows, int)
    /**
     @brief Chessboard field size, in meters
     */
    ADD_PROPERTY(checkerboard_raster, double)
    /**
     @brief Offset between lower-left chessboard corner crossing and workspace origin in x axis, in meters
     */
    ADD_PROPERTY(workspace_x_offset, double)
    /**
     @brief Offset between lower-left chessboard corner crossing and workspace origin in y axis, in meters
     */
    ADD_PROPERTY(workspace_y_offset, double)
    /**
     @brief Workspace size along x axis, in meters
     */
    ADD_PROPERTY(workspace_x_size, double)
    /**
     @brief Workspace size along y axis, in meters
     */
    ADD_PROPERTY(workspace_y_size, double)
    /**
     @brief Output picture width, in pixels
     */
    ADD_PROPERTY(picture_width, int)
    /**
     @brief Output picture height, in pixels
     */
    ADD_PROPERTY(picture_height, int)

public:
    /**
     @brief Initializes default parameters
     */
	Processor_PlaneCalibration() {
		Processor();
		inputType = InputTypeMat;

		mode_ = Processor_PlaneCalibration_Mode_Waiting;
        
		m_checkerboard_columns = 9;
		m_checkerboard_rows = 6;
		m_checkerboard_raster = 0.038;
        
        m_workspace_x_offset = 0.058;
        m_workspace_y_offset = 0.0535;
        
        m_workspace_x_size = 0.420;
        m_workspace_y_size = 0.297;
        
        m_picture_width = 640;
        m_picture_height = 480;
    }

private:
	enum Processor_PlaneCalibration_Mode {Processor_PlaneCalibration_Mode_Waiting, Processor_PlaneCalibration_Mode_Acquire, Processor_PlaneCalibration_Mode_Calibrated};
	Processor_PlaneCalibration_Mode mode_;
    
    cv::Mat perspective_mat_;
	
public:
    /**
     @brief Starts image processing

     @return 0 on success
     */
    int start();
    /**
     @brief Processes frames in input buffer

     @param t1 Cameras trigger time
     @param t2 Cameras acquisition finish time
     @return 0 on success
     */
    int process(int t1, int t2);
	/**
     @brief Processes special command
     
	 Valid commands are:
     <br>calibrate: calculates transformation between camera and workspace based on current frame, switches to perspective correction mode
     <br>reset: switches to chessboard search mode
     
	 @param s Command string
	 @return 0 on success
	 */
	int processSpecial(string s);
	/**
	 @brief Stops image processing

	 @return 0 on success
	 */
	int stop();
    
    /**
     @brief Writes properties and current calibration matrix to XML stream

     @param stream XML stream to write to
     */
    virtual void writeXml(QXmlStreamWriter& stream);
    /**
     @brief Reads properties and calibration matrix from XML stream

     @param stream XML stream to read from
     */
    virtual void readXml(QXmlStreamReader& stream);
};
/** @}*/
#endif
