#include "Nedelec3D_Util.h"

namespace Nedelec3D
{
	void buildTetDofMap(Mesh_3D* mesh, int numTet, int elementOrder, int* map, int mapSize)
	{
		if (elementOrder != 2)
		{
			if (mapSize < 6)
				return;
			for (int i = 0; i < 6; i++)
				map[i] = mesh->GetEdgeOfTet(numTet, i);
			return;
		}
		if (mapSize < 20)
			return;

		const int nE = mesh->GetNbrEdge();
		const int nF = mesh->GetNbrFace();
		for (int i = 0; i < 6; i++)
		{
			const int e = mesh->GetEdgeOfTet(numTet, i);
			map[i * 2] = e;
			map[i * 2 + 1] = e + nE;
		}
		for (int i = 0; i < 4; i++)
		{
			const int f = mesh->GetFaceOfTet(numTet, i);
			map[12 + i * 2] = 2 * nE + f;
			map[12 + i * 2 + 1] = 2 * nE + f + nF;
		}
	}

	void sbcFaceSecondOrderBfIndex(int numFace, int bfIndex[8])
	{
		static const int tbl[4][8] = {
			{1, 3, 7, 2, 4, 8, 13, 14},
			{1, 5, 9, 2, 6, 10, 15, 16},
			{3, 5, 11, 4, 6, 12, 17, 18},
			{7, 9, 11, 8, 10, 12, 19, 20}
		};
		const int fi = numFace - 1;
		if (fi < 0 || fi > 3)
			return;
		for (int i = 0; i < 8; i++)
			bfIndex[i] = tbl[fi][i];
	}

	void buildSbcSecondOrderDofMap(Mesh_3D* mesh, int numTet, int numFace, int mapIdx[8])
	{
		static const int edgeSlots[4][3] = { {0, 1, 3}, {0, 2, 4}, {1, 2, 5}, {3, 4, 5} };
		const int nE = mesh->GetNbrEdge();
		const int nF = mesh->GetNbrFace();
		const int fi = numFace - 1;
		if (fi < 0 || fi > 3)
			return;

		const int faceId = mesh->GetFaceOfTet(numTet, fi);
		for (int j = 0; j < 3; j++)
		{
			const int e = mesh->GetEdgeOfTet(numTet, edgeSlots[fi][j]);
			mapIdx[j] = e;
			mapIdx[j + 3] = e + nE;
		}
		mapIdx[6] = 2 * nE + faceId;
		mapIdx[7] = 2 * nE + faceId + nF;
	}
}
