#ifndef CCLIBALGORITHMS_H
#define CCLIBALGORITHMS_H
//##########################################################################
//#                                                                        #
//#                              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: CloudCompare project                               #
//#                                                                        #
//##########################################################################

#include "ccHObject.h"

#include <GeometricalAnalysisTools.h>

class QWidget;

class ccGenericPointCloud;
class ccProgressDialog;

namespace ccLibAlgorithms
{
	//! Returns a default first guess for algorithms kernel size (one cloud)
	double GetDefaultCloudKernelSize(ccGenericPointCloud* cloud, unsigned knn = 12);
	
	//! Returns a default first guess for algorithms kernel size (several clouds)
	double GetDefaultCloudKernelSize(const ccHObject::Container& entities, unsigned knn = 12);
	
	/*** CCCoreLib "standalone" algorithms ***/

	//! Geometric characteristic (with sub option)
	struct GeomCharacteristic
	{
		GeomCharacteristic(CCCoreLib::GeometricalAnalysisTools::GeomCharacteristic c, int option = 0)
			: charac(c)
			, subOption(option)
		{}
		
		CCCoreLib::GeometricalAnalysisTools::GeomCharacteristic charac;
		int subOption = 0;
	};

	//! Set of GeomCharacteristic instances
	typedef std::vector<GeomCharacteristic> GeomCharacteristicSet;

	//! Computes geometrical characteristics (see GeometricalAnalysisTools::GeomCharacteristic) on a set of entities
	bool ComputeGeomCharacteristics(const GeomCharacteristicSet& characteristics,
									PointCoordinateType radius,
									ccHObject::Container& entities,
									const CCVector3* roughnessUpDir = nullptr,
									QWidget* parent = nullptr);
	
	//! Computes a geometrical characteristic (see GeometricalAnalysisTools::GeomCharacteristic) on a set of entities
	bool ComputeGeomCharacteristic(	CCCoreLib::GeometricalAnalysisTools::GeomCharacteristic algo,
									int subOption,
									PointCoordinateType radius,
									ccHObject::Container& entities,
									const CCVector3* roughnessUpDir = nullptr,
									QWidget* parent = nullptr,
									ccProgressDialog* progressDialog = nullptr);

	//CCCoreLib algorithms handled by the 'ApplyCCCoreLibAlgorithm' method
	enum CC_LIB_ALGORITHM { CCLIB_ALGO_SF_GRADIENT,
	};
	
	//! Applies a standard CCCoreLib algorithm (see CC_LIB_ALGORITHM) on a set of entities
	bool ApplyCCLibAlgorithm(	CC_LIB_ALGORITHM algo,
								ccHObject::Container& entities,
								QWidget* parent = nullptr,
								void** additionalParameters = nullptr);
	
	//! Scale matching algorithms
	enum ScaleMatchingAlgorithm { BB_MAX_DIM, BB_VOLUME, PCA_MAX_DIM, ICP_SCALE };
	
	//! Applies a standard CCCoreLib algorithm (see CC_LIB_ALGORITHM) on a set of entities
	bool ApplyScaleMatchingAlgorithm(ScaleMatchingAlgorithm algo,
												ccHObject::Container& entities,
												double icpRmsDiff,
												int icpFinalOverlap,
												unsigned refEntityIndex = 0,
												QWidget* parent = nullptr);
}

#endif
