/**
    05Robot - Computer Vision Module

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

#include "Processor.h"

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

using namespace std;
/** \addtogroup ComputerVisionModule
 *  @{
 */
/**
 @brief Camera calibration image processor
 
 Calculates internal camera and lens parameters based on a series of chessboard images.
 */
class Processor_CameraCalibration: public Processor
{
	Q_OBJECT
    /**
     @brief Path to camera parameters storage directory
     */
    ADD_PROPERTY(path, QString)
    /**
     @brief Name format of camera parameters file. %s is replaced with unique camera ID
     */
    ADD_PROPERTY(filename, QString)
    /**
     @brief Number of chessboard internal columns (crossings)
     */
    ADD_PROPERTY(boardSize_X, int)
    /**
     @brief Number of chessboard internal rows (crossings)
     */
    ADD_PROPERTY(boardSize_Y, int)
    /**
     @brief Chessboard field size, in meters
     */
    ADD_PROPERTY(squareSize, double)

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

		mode = Processor_CameraCalibration_Mode_Normal;

		m_path = QString("calibration/");
		m_filename = QString("%s.yml");
		m_boardSize_X = 9;
		m_boardSize_Y = 6;
		m_squareSize = 0.042;
	}

private:
	vector<vector<cv::Point2f> > imagePoints;
	vector<vector<cv::Point3f> > objectPoints;
	vector<cv::Point2f> imageCorners;
	vector<cv::Point3f> objectCorners;

	int acquiredImageDisplayTimeout;

	enum Processor_CameraCalibration_Mode {Processor_CameraCalibration_Mode_Normal, Processor_CameraCalibration_Mode_Acquire, Processor_CameraCalibration_Mode_Calibrate};
	Processor_CameraCalibration_Mode mode;

	
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>acquire: adds current frame to list of calibration images
     <br>calibrate: calculates camera patameters using stored images
     
     @param s Command string
     @return 0 on success
     */
	int processSpecial(string s);
    /**
     @brief Stops image processing
     
     @return 0 on success
     */
	int stop();
};
/** @}*/
#endif
