//##########################################################################
//#                                                                        #
//#                              CLOUDCOMPARE                              #
//#                                                                        #
//#  This program is free software; you can redistribute it and/or modify  #
//#  it under the terms of the GNU General Public License as published by  #
//#  the Free Software Foundation; version 2 or later of the License.      #
//#                                                                        #
//#  This program is distributed in the hope that it will be useful,       #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          #
//#  GNU General Public License for more details.                          #
//#                                                                        #
//#          COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI)             #
//#                                                                        #
//##########################################################################

#ifndef CC_COMPARISON_DIALOG_HEADER
#define CC_COMPARISON_DIALOG_HEADER

//qCC_db
#include <ccOctree.h>

//Qt
#include <QDialog>
#include <QString>

#include <ui_comparisonDlg.h>

class ccHObject;
class ccPointCloud;
class ccGenericPointCloud;
class ccGenericMesh;

//! Dialog for cloud/cloud or cloud/mesh comparison setting
class ccComparisonDlg: public QDialog, public Ui::ComparisonDialog
{
	Q_OBJECT

public:

	//! Comparison type
	enum CC_COMPARISON_TYPE
	{
		CLOUDCLOUD_DIST = 0,
		CLOUDMESH_DIST  = 1,
	};

	//! Default constructor
	ccComparisonDlg(ccHObject* compEntity,
					ccHObject* refEntity,
					CC_COMPARISON_TYPE cpType,
					QWidget* parent = nullptr,
					bool noDisplay = false);

	//! Default destructor
	~ccComparisonDlg();

	//! Should be called once after the dialog is created
	inline bool initDialog() { return computeApproxDistances(); }

	//! Returns compared entity
	ccHObject* getComparedEntity() const { return m_compEnt; }
	//! Returns compared entity
	ccHObject* getReferenceEntity() { return m_refEnt; }

public:
	bool computeDistances();
	void applyAndExit();
	void cancelAndExit();

protected:
	void showHisto();
	void locaModelChanged(int);
	void maxDistUpdated();
    void enableCompute2D(bool);

protected:

	bool isValid();
	bool prepareEntitiesForComparison();
	bool computeApproxDistances();
	int getBestOctreeLevel();
	int determineBestOctreeLevel(double);
	void updateDisplay(bool showSF, bool hideRef);
	void releaseOctrees();

	//! Compared entity
	ccHObject* m_compEnt;
	//! Compared entity equivalent cloud
	ccPointCloud* m_compCloud;
	//! Compared entity's octree
	ccOctree::Shared m_compOctree;
	//! Whether the compared entity octree is partial or not
	bool m_compOctreeIsPartial;
	//! Initial compared entity visibility
	bool m_compSFVisibility;

	//! Reference entity
	ccHObject* m_refEnt;
	//! Reference entity equivalent cloud (if any)
	ccGenericPointCloud* m_refCloud;
	//! Reference entity equivalent mesh (if any)
	ccGenericMesh* m_refMesh;
	//! Reference entity's octree
	ccOctree::Shared m_refOctree;
	//! Whether the reference entity octree is partial or not
	bool m_refOctreeIsPartial;
	//! Initial reference entity visibility
	bool m_refVisibility;

	//! Comparison type
	CC_COMPARISON_TYPE m_compType;

	//! last computed scalar field name
	QString m_sfName;

	//! Initial SF name enabled on the compared entity
	QString m_oldSfName;

	//! Whether a display is active (and should be refreshed) or not
	bool m_noDisplay;

	//! Best octree level (or 0 if none has been guessed already)
	int m_bestOctreeLevel;
};

#endif
