
#pragma once

#include <TopoDS.hxx>
#include "nlohmann/json.hpp"
#include "ShapeTypes.hpp"
using json = nlohmann::json;

/// <summary>
/// Class - container for TopoDS_Shape
/// intended to hold name, id, shape
/// </summary>
class TopoEntity
{
public:
	TopoEntity(TopoDS_Shape shape, std::string name, int id = 0);

	/// <summary>
	/// Constructor with json as argument
	/// </summary>
	/// <param name="inp"> json which will be parsed</param>
	/// <param name="wdir">working directory as json contains relative paths</param>
	TopoEntity(json inp, std::string wdir);


	TopoEntity(const TopoEntity& that);

	TopoEntity(const std::shared_ptr<TopoEntity> that);


	ShapeType getType();
	std::string getName();

	TopoDS_Shape getShape();
	int getId();

	void setId(int);

	void setShape(TopoDS_Shape);

	//methods for checking relations
	bool isSubShapeOf(TopoDS_Shape sh);
	bool isSubShapeOf(std::shared_ptr<TopoEntity> ent);
	bool hasSharedEdges(std::shared_ptr<TopoEntity> ent);
	bool hasSharedFaces(std::shared_ptr<TopoEntity> ent);

	// checks shape type of passed shape (static method!!)
	static ShapeType getShapeType(const TopoDS_Shape);

	void writeBrep(std::string p);

	int getDimension();

	json getJson();


	// contains matches between entities in different lists
	void addLinkedEntity(std::shared_ptr<TopoEntity>);
	std::vector<std::shared_ptr<TopoEntity>> getLinkedEntities();

	void setEnabled(bool);
	bool isEnabled();
	void setIsindomain();
	bool getIsindomain();
	void unsetIsindomain();
protected:
	ShapeType ent_type;
	TopoDS_Shape shape;
	std::string name;
	std::string brep_path;

	std::vector<std::shared_ptr<TopoEntity>> linked_entities;

	// global id, numbering for all shape types is in one sequence
	int id;

	// flag for entities that are not added to partition. Used by GeometryData
	bool enabled;
	bool isindomain;
};

typedef std::shared_ptr<TopoEntity> TopoEntity_;