#ifndef __RUINSRECONSTRUCTORPROCESSOR_H__
#define __RUINSRECONSTRUCTORPROCESSOR_H__

#include "Processor.h"
#include "ModelDrawer.h"
#include "TrackedCorners.h"
#include "CanvasPointGrabber.h"
#include "CornerTracker.h"
#include "CornerDetector.h"
#include "FASTCornerDetector.h"
#include "KLTCornerDetector.h"
#include <QImage>
#include <QPoint>
#include <QObject>
#include <QMenu>

class QAction;

class RuinsReconstructorPropertiesWidget;

class RuinsReconstructorProcessor : public QObject, public Processor
{
	Q_OBJECT

public:
	RuinsReconstructorProcessor( Canvas* canvas );
	~RuinsReconstructorProcessor();

	virtual void resize( int width, int height );
	virtual void process( const unsigned char* original, unsigned char* processed );
	virtual QWidget* getPropertiesWidget( QWidget* parent );
	virtual void setupToolBar( QToolBar* toolBar );

	virtual void decorateGL( Canvas* canvas );
	virtual bool onMousePress( Canvas* canvas, int x, int y );
	virtual bool onMouseRelease( Canvas* canvas, int x, int y );

	void setModel( const double *modelPoints, int numPoints );

	CornerDetector* getCornerDetector() { return _cornerDetector; }

	void setCornerDetector( CornerDetector *cd ) { _cornerDetector = cd; }

	inline void transferGrabberPoints( CanvasPointGrabber *cpg, TrackedCorners *tc )
	{
		int numPoints = cpg->getNumPoints();

		tc->setNumPoints( numPoints );

		int* points = tc->getPoints();
		for( int i = 0; i < numPoints; ++i )
		{
			const QPoint& p = cpg->getPoint( i );
			points[2*i] = p.x();
			points[2*i + 1] = _height - p.y();
		}
	}

	inline bool usingKalmanFilter()
	{
		return _useKalmanFilter;
	}

	inline void setUseCalmanFilter( bool s )
	{
		_useKalmanFilter = s;
	}


private:
	void calibrateCamera();
	void loadCameraMatrices();

private slots:
	void on_actionStartInitialPointsSelection_toggled( bool on );

private:
	int _width;
	int _height;
	int _maxPointsModel;

	double _modelViewMatrix[16];
	double _projectionMatrix[16];

	QAction* _actionStartInitialPointsSelection;
	QMenu _menuInitialPointsGetMode;
	RuinsReconstructorPropertiesWidget* _widget;
	CanvasPointGrabber* _canvasPointGrabber;
	CornerDetector *_cornerDetector;
	CornerTracker *_cornerTracker;

	QImage _referenceImage;
	TrackedCorners _trackedPoints;
	ModelDrawer drawer;
	double* _modelPoints;

	// Marks if camera could be calibrated currently (for the current frame)
	bool _isCameraCurrentlyCalibrated;

	// Marks if camera has been ever calibrated (in this case there will be some last valid camera parameters to build camera matrices )
	bool _hasLastCameraCalibration;

	bool _automaticInitialPointsMode;

	bool _useKalmanFilter;

	bool _kalmanInitialized;
};

#endif