#ifndef CALIB_CALIBRATION_H
#define CALIB_CALIBRATION_H

#include <string>
#include <iostream>
#include <fstream>
#include "Helper\Cvh.h"
#include "Calibration\Projector.h"

namespace CALIB
{
	class Calibration{
		
		public: 
			static float saveStatistics(ofstream& fout,float origX,float origY, float shiftX,float shiftY,float L2sum,int projectorWidth,int projectorHeight);
			static vector<double> & split(const string &s,char delim, vector<double> &elems);
			static void NormalizeTexturePoints(std::vector<geometry::Vector2Df> * texturePoints);
			static void LoadMeshPoints(Projector * p,string filename);
			static void LoadMeshPoints(std::vector<geometry::Vector2Df> * vertexPoints,std::vector<geometry::Vector2Df> * texturePoints,string filename,int projectorWidth,int projectorHeight,int * rows,int * cols);
			static void CalculatePointsShift(vector<geometry::Vector2Df> * originalPoints,vector<geometry::Vector2Df> * shiftedPoints,int pointsRows,int pointsCols,string filenameSave,int width,int height,vector<geometry::Vector2Df> * pointsMesh);
			static CvMat* CalculatePointsShift(std::vector<geometry::Vector2Df> * cameraImagePoints,CvMat * projectorImagePointsCv,int pointsRows,int pointsCols,string filenameSave,Projector * p,int currntChessRows,int currntChessCols,CvMat * homography);

			static void SelectChessInnerPoints(CvMat * projectorImagePointsCv,int pointsRows,int pointsCols,int currntChessRows,int currntChessCols,Projector * p);
			static void SelectChessInnerPoints(CvMat * projectorImagePointsCv,int pointsRows,int pointsCols,int currntChessRows,int currntChessCols,std::vector<geometry::Vector2Df> * resultInnerCorners);

			/**
			 * Function draws motion vectors into provided image
			 * @param rightPositions Desired points positions in projector coordinate frame.
			 * @param currentPositions Current points position in camera coordinate frame.
			 * @param cameraImagePoint Desired projector boundry in camera image.
			 * @param homography Camera to projector homography matrix.
			 * @param invertHomographyMatrix Indicatges if the homography matrix should be inverted or not.
			 */
			static void AddMotionVectorsIntoImage(std::vector<geometry::Vector2Df> * rightPositions,std::vector<geometry::Vector2Df> * currentPositions,std::vector<geometry::Vector2Df> * cameraImagePoints,CvMat * homography,IplImage * img,bool invertHomographyMatrix = false);
			static void AddMotionVectorsIntoImage(std::vector<geometry::Vector2Df> * rightPositions,std::vector<geometry::Vector2Df> * currentPositions,IplImage * img,int lineWidth = 2);
			static void AddMotionVectorsIntoImage(CvMat * rightPositionsCv,CvMat * currentPositionsCv,IplImage * img,int lineWidth = 2);
		protected:
			/**
			 * Modify input points to orthogonal structure with coordinate frame.
			 */
			static void initCameraImagePointsOrthogonal(std::vector<geometry::Vector2Df> * cameraImagePoints);
		private: 						
			Calibration();
			~Calibration();
	}; 	
}; 

#endif
