#pragma once


#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include "ShapeStats.hpp"


class ShapeAlgorithms
{
public:
	static TopoDS_Shape preProcessCadShape(const TopoDS_Shape shape);
	static bool have_equal_shapes(const TopoDS_Shape& s1, const TopoDS_Shape& s2);
	static bool have_equal_shapes(const TopoDS_Shape& s1, const TopTools_ListOfShape& l2);
	static bool are_equal(const TopoDS_Shape& s1, const TopoDS_Shape& s2);
	static bool are_equal(const TopoDS_Shape& s1, const TopTools_ListOfShape& l2);
	static bool have_common(const TopoDS_Shape& s1, const TopoDS_Shape& s2);
	static bool have_common(const TopoDS_Shape& s1, const TopTools_ListOfShape& s2);
	static void getShapeStatistics(const TopoDS_Shape* shape, ShapeStats& stats);
	static TopAbs_ShapeEnum getHighestShapeType(const TopoDS_Shape& sh);
	static bool sameType(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool have_common_vertices(const TopoDS_Shape& s1, const TopoDS_Shape& s2);
	static bool isDegenerate(const TopoDS_Shape& s1);

	static double getDiagonal(const TopoDS_Shape& shape);
	static double getMinEdgeLength(const TopoDS_Shape& shape);

	static double getVolume(const TopoDS_Shape& shape);
	static double getArea(const TopoDS_Shape& shape);
	static double getLength(const TopoDS_Shape& shape);

	static void writeStepFile(const TopoDS_Shape& shape, const std::string filename);
	static void writeBrepFile(const TopoDS_Shape& shape, const std::string filename);
	static TopoDS_Shape readStepFile(const std::string filename);
	static TopoDS_Shape readIgesFile(const std::string filename);


	static bool have_common_solids(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool have_common_faces(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool have_common_edges(const TopoDS_Shape s1, const TopoDS_Shape s2);

	static double getMinDistance(const TopoDS_Shape s1, const TopoDS_Shape s2, gp_Vec& vector = gp_Vec());
	static gp_Pnt getCenterPoint(const TopoDS_Shape& s1);

	static bool hasInternalFaces(const TopoDS_Shape& s1);
	static TopTools_ListOfShape sortEdges(const TopoDS_Shape& s1);

	static gp_Dir getFaceNormal(TopoDS_Shape shape);
	static TopoDS_Shape scaleShape(const TopoDS_Shape shape, double factor);

private:
	static bool compare_bounding_boxes(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool compare_solids(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool compare_faces(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool compare_edges(const TopoDS_Shape s1, const TopoDS_Shape s2);
	static bool compare_vertices(const TopoDS_Shape s1, const TopoDS_Shape s2);

	static std::string stepToOCCUnits(std::string);
};
