#include "MeshingData.h"
#include "topology/ShapeAlgorithms.h"
#include "cenos_exception.h"

MeshingData::MeshingData()
{
	mesh = nullptr;
}

MeshingData::~MeshingData()
{
}

void MeshingData::addMeshEntity(std::shared_ptr<MeshEntity > te)
{
	entity_vec.push_back(te);
}

bool MeshingData::isMeshed(std::shared_ptr<TopoEntity > te)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			return ent->hasNetgenMesh();

	}
	return false;
}

std::shared_ptr<MeshParameters> MeshingData::getParameters(std::shared_ptr<TopoEntity > te)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			return ent->getMeshParameters();
	}
	throw cenos_exception("Could not find MeshParameters for entity " + te->getName());
}

NetgenMesh_ MeshingData::getMesh(std::shared_ptr<TopoEntity > te)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			return ent->getNetgenMesh();
	}
	throw cenos_exception("Could not find mesh for entity " + te->getName());
}

NetgenLocalH* MeshingData::getLocalH(std::shared_ptr<TopoEntity> te)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			return ent->getNetgenLocalH();
	}
	return nullptr;
}

std::shared_ptr<TopoEntity> MeshingData::getTopoEntity(TopoDS_Shape sh)
{
	// Attempt to find Topo Entity by checking shape type and equal_shapes
	// Return nullptr if no entity was found.
	for (auto ent : entity_vec)
	{
		if (ShapeAlgorithms::have_equal_shapes(sh, ent->getShape()) &&
			ShapeAlgorithms::sameType(sh, ent->getShape()))
			return ent;
	}
	return nullptr;
}

std::shared_ptr<TopoEntity> MeshingData::getTopoEntity(std::string n)
{
	// Attempt to find Topo Entity by checking entity name
	for (auto ent : entity_vec)
	{
		if (ent->getName() == n)
			return ent;
	}

	throw cenos_exception("Could not identify entity named " + n);
}


void MeshingData::setMesh(std::shared_ptr<Mesh> m)
{
	mesh = m;
}


void MeshingData::setMesh(std::shared_ptr<TopoEntity> te, NetgenMesh_ m)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			ent->setNetgenMesh(m);
	}
}

void MeshingData::setLocalH(std::shared_ptr<TopoEntity> te, NetgenLocalH* l)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			ent->setNetgenLocalH(l);
	}
}

void MeshingData::setParameters(std::shared_ptr<TopoEntity> te, std::shared_ptr<MeshParameters> mp)
{
	for (auto ent : entity_vec)
	{
		if (ent->getName() == te->getName())
			ent->setMeshParameters(mp);
	}
}
