/** <b>Levmar Methods -- Interface with the levamr lib </b>

The class is static, so a simple call to <code>calibrate()</code> is
sufficient to get a calibrated shot.<br>

*/

#include <vcg/math/matrix44.h>
#include <vcg/space/point3.h>
#include <vcg/space/point2.h>
#include <vcg/math/shot.h>

#include <list>

#include "lm.h"


struct LevmarCorrelation {
	vcg::Point3f point3d;
	vcg::Point2d point2d;
};

struct LevmarData{
	vcg::Point3f** points3d; 
	vcg::Shot<MESHLAB_SCALAR>* levmarCam;
};


class LevmarMethods
{
public:
	//Calibration of the shot according to the 2D and 3D points
	static bool calibrate(vcg::Shot<MESHLAB_SCALAR>* shot, std::list<LevmarCorrelation>* corr, bool p_focal); 

	///Transformation of the camera data between tsai structure and vcg structure
	///True if you want calibrate the focal, false if you want calibrate the extrinsics
	static void Shot2Levmar(vcg::Shot<MESHLAB_SCALAR>*, double* p, bool p_foc);
	///Transformation of the camera data between tsai structure and vcg structure
	///True if you have calibrated the focal, false if you had calibrated the extrinsics
	static void Levmar2Shot(vcg::Shot<MESHLAB_SCALAR>*, double *p, bool p_foc);
	
private:
	static void Cam2Levmar(vcg::Shot<float>*);
    static bool createDataSet(std::list<LevmarCorrelation>* corr, vcg::Shot<MESHLAB_SCALAR>* s, LevmarData* data, double* x, double opts[LM_OPTS_SZ], double info[LM_INFO_SZ]);
	static void estimateExtr(double *p, double *x, int m, int n, void *data);
	static void estimateFocal(double *p, double *x, int m, int n, void *data);

};

