#pragma once

#include "../mesh/Mesh_Base.h"
#include "../common/define.h"

namespace Nedelec3D
{
	inline int bfOrderParam(int elementOrder)
	{
		return (elementOrder == 2) ? BF_QUADFUNC : BF_LINEFUNC;
	}

	inline int gaussOrderVol(int elementOrder)
	{
		return (elementOrder == 2) ? 4 : (BF_LINEFUNC * 2);
	}

	inline int gaussOrderTri(int elementOrder)
	{
		return (elementOrder == 2) ? 6 : (BF_LINEFUNC * 2);
	}

	inline int localDofPerTet(int elementOrder)
	{
		return (elementOrder == 2) ? 20 : 6;
	}

	inline int globalDofCount(Mesh_3D* mesh, int elementOrder)
	{
		if (elementOrder == 2)
			return 2 * mesh->GetNbrEdge() + 2 * mesh->GetNbrFace();
		return mesh->GetNbrEdge();
	}

	void buildTetDofMap(Mesh_3D* mesh, int numTet, int elementOrder, int* map, int mapSize);

	void sbcFaceSecondOrderBfIndex(int numFace, int bfIndex[8]);

	void buildSbcSecondOrderDofMap(Mesh_3D* mesh, int numTet, int numFace, int mapIdx[8]);

	inline int edgeGlobalDof(int edgeId, int slot, int nbrEdge)
	{
		return edgeId + slot * nbrEdge;
	}

	inline int faceGlobalDof(int faceId, int slot, int nbrEdge, int nbrFace)
	{
		return 2 * nbrEdge + faceId + slot * nbrFace;
	}
}
