#pragma once

#include <C2/lm/vector3.h>

#include <LibGeo/Mesh/BaryCoord.h>

#include <LibQtGeoViewerCore/NamedValue.h>



namespace geom
{

class GeomObject;
class MeshBuf;

}


enum class SphereClipType
{
	None,
	Hole,
	ShowAround,
};


class CursorStroke
{
public:
	CursorStroke(void) :
		Length(0)
	{}

	bool IsEmpty(void) const
	{
		return Points.empty();
	}

	void AddPoint(const lm::vec3f& pos)
	{
		if (!Points.empty())
			Length += (Points.back() - pos).length();

		Points.push_back(pos);
	}

	float GetLength(void) const
	{
		return Length;
	}

	const std::vector<lm::vec3f>& GetPoints(void) const
	{
		return Points;
	}

private:
	std::vector<lm::vec3f> Points;
	float Length;
};


class Cursor3D
{
public:
	Cursor3D(void);

	void ResetCursorPos(void);
	void ResetMeasure(void);
	void ResetCloseFace(void);

	lm::vec3f GetMidMeasurePos(void) const;
	float GetMeasureLength(void) const;

	bool IsHoleActive(void) const;
	bool IsHoleRevActive(void) const;
	bool IsCircleClipActive(void) const;

	void PushStroke(void);
	void CutStroke(void);
	void ClearStroke(void);

	float GetSphereClipLen(const lm::range3f& bbox) const;
	void GetFreeCutParam(lm::vec3f& p, lm::vec3f& n);

public:
	NamedValue<bool> ShowCursor;
	NamedValue<bool> CursorDepth;
	NamedValue<bool> ShowMeasure;
	NamedValue<bool> ShowMeasureLen;
	NamedValue<bool> ShowMeasureXYZ;
	NamedValue<bool> ShowAxis;
	NamedValue<bool> ShowCoord;
	NamedValue<bool> CheckBaryCoord;
	NamedValue<bool> SelCloseMat;
	NamedValue<bool> RecordStroke;
	NamedValue<bool> ShowStrokeLen;
	NamedValue<bool> TranspStorke;

	SphereClipType SphereClip;
	float HoleRangeRatio;

	lm::vec3f CursorPos;
	lm::vec3f MeasurePos;

	lm::quat4f CutplaneRot;

	geom::MeshBuf* CloseFaceMBuf;
	lib_geo::BaryCoord CloseFace;

	std::vector<CursorStroke> Strokes;
};
