local icosa_defines = {}

local cpml = require "cpml"
local vec3 = cpml.vec3

--- vertex 1..12
-- icosa_defines.vertices = {
--     vec3(        1.0,  1.61803399,         0.0):normalize(), ---  1
--     vec3(       -1.0,  1.61803399,         0.0):normalize(), ---  2
--     vec3(        1.0, -1.61803399,         0.0):normalize(), ---  3
--     vec3(       -1.0, -1.61803399,         0.0):normalize(), ---  4
--     vec3(        0.0,         1.0,  1.61803399):normalize(), ---  5
--     vec3(        0.0,        -1.0,  1.61803399):normalize(), ---  6
--     vec3(        0.0,         1.0, -1.61803399):normalize(), ---  7
--     vec3(        0.0,        -1.0, -1.61803399):normalize(), ---  8
--     vec3( 1.61803399,         0.0,         1.0):normalize(), ---  9
--     vec3(-1.61803399,         0.0,         1.0):normalize(), --- 10
--     vec3( 1.61803399,         0.0,        -1.0):normalize(), --- 11
--     vec3(-1.61803399,         0.0,        -1.0):normalize()  --- 12
-- }

--- normalized and transformed
icosa_defines.vertices = {
	vec3(-0.60702621936798100,  0.79468178749084500,  0.00008639693260193), ---  1
	vec3( 0.30369532108306900,  0.79468178749084500,  0.52559489011764500), ---  2
	vec3(-0.30369532108306900, -0.79468178749084500, -0.52559489011764500), ---  3
	vec3( 0.60702621936798100, -0.79468178749084500, -0.00008639693260193), ---  4
	vec3( 0.30343821644783000,  0.79459977149963400, -0.52586734294891400), ---  5
	vec3( 0.49090704321861300, -0.18768092989921600, -0.85075616836547900), ---  6
	vec3(-0.49090704321861300,  0.18768092989921600,  0.85075616836547900), ---  7
	vec3(-0.30343821644783000, -0.79459977149963400,  0.52586734294891400), ---  8
	vec3(-0.49132287502288800,  0.18754824995994600, -0.85054534673690800), ---  9
	vec3( 0.98225533962249800,  0.18754824995994600, -0.00025475025177002), --- 10
	vec3(-0.98225533962249800, -0.18754824995994600,  0.00025475025177002), --- 11
	vec3( 0.49132287502288800, -0.18754824995994600,  0.85054534673690800), --- 12
}

--- face 1..20
---    vertex 1..12
icosa_defines.face_vertices = {
	{ 1,  2,  5}, ---  1
	{ 2, 10,  5}, ---  2
	{ 5, 10,  6}, ---  3
	{ 6, 10,  4}, ---  4
	{ 3,  4,  8}, ---  5
	{ 4,  3,  6}, ---  6
	{ 8, 11,  3}, ---  7
	{ 1,  9, 11}, ---  8
	{ 1,  5,  9}, ---  9
	{ 9,  3, 11}, --- 10
	{ 9,  5,  6}, --- 11
	{ 9,  6,  3}, --- 12
	{ 2,  1,  7}, --- 13
	{12,  2,  7}, --- 14
	{ 4, 10, 12}, --- 15
	{ 7, 11,  8}, --- 16
	{ 4, 12,  8}, --- 17
	{12,  7,  8}, --- 18
	{ 7,  1, 11}, --- 19
	{10,  2, 12}  --- 20
}

local function cc(fi)
	local vi1, vi2, vi3 = icosa_defines.face_vertices[fi][1], icosa_defines.face_vertices[fi][2], icosa_defines.face_vertices[fi][3]
	local c = icosa_defines.vertices[vi1] + icosa_defines.vertices[vi2] + icosa_defines.vertices[vi3]
	return c:normalize()
end

icosa_defines.centers = {
	cc(1), cc(2), cc(3), cc(4), cc(5), cc(6), cc(7), cc(8), cc(9), cc(10),
	cc(11), cc(12), cc(13), cc(14), cc(15), cc(16), cc(17), cc(18), cc(19), cc(20)
}

--- face 1..20
---    edge 1..3
---        neighbor_face, neighbor_edge
icosa_defines.face_neighbors = {
	{{ 2,  3}, {13,  2}, { 9,  2}}, ---  1
	{{ 3,  2}, {20,  2}, { 1,  1}}, ---  2
	{{ 4,  2}, { 2,  1}, {11,  1}}, ---  3
	{{15,  2}, { 3,  1}, { 6,  3}}, ---  4
	{{17,  3}, { 6,  2}, { 7,  3}}, ---  5
	{{12,  1}, { 5,  2}, { 4,  3}}, ---  6
	{{10,  1}, {16,  1}, { 5,  3}}, ---  7
	{{10,  3}, { 9,  3}, {19,  1}}, ---  8
	{{11,  2}, { 1,  3}, { 8,  2}}, ---  9
	{{ 7,  1}, {12,  3}, { 8,  1}}, --- 10
	{{ 3,  3}, { 9,  1}, {12,  2}}, --- 11
	{{ 6,  1}, {11,  3}, {10,  2}}, --- 12
	{{19,  2}, { 1,  2}, {14,  1}}, --- 13
	{{13,  3}, {20,  1}, {18,  2}}, --- 14
	{{20,  3}, { 4,  1}, {17,  2}}, --- 15
	{{ 7,  2}, {19,  3}, {18,  1}}, --- 16
	{{18,  3}, {15,  3}, { 5,  1}}, --- 17
	{{16,  3}, {14,  3}, {17,  1}}, --- 18
	{{ 8,  3}, {13,  1}, {16,  2}}, --- 19
	{{14,  2}, { 2,  2}, {15,  1}}  --- 20
}

---@param face number
---@param edge number
---@return number, number
function icosa_defines.neighbor_face_edge_at(face, edge)
	return icosa_defines.face_neighbors[face][edge][1], icosa_defines.face_neighbors[face][edge][2]
end

--- vertex 1..12
---    face 1..5
---        face_index 1..20, vertex_index 1..3
icosa_defines.vertex_faces = {
	{{  1,  1 }, { 13,  2 }, { 19,  2 }, {  8,  1 }, {  9,  1 }}, ---  1
	{{  1,  2 }, {  2,  1 }, { 20,  2 }, { 14,  2 }, { 13,  1 }}, ---  2
	{{  5,  1 }, {  7,  3 }, { 10,  2 }, { 12,  3 }, {  6,  2 }}, ---  3
	{{  4,  3 }, { 15,  1 }, { 17,  1 }, {  5,  2 }, {  6,  1 }}, ---  4
	{{  1,  3 }, {  2,  3 }, {  3,  1 }, { 11,  2 }, {  9,  2 }}, ---  5
	{{  3,  3 }, { 11,  3 }, { 12,  2 }, {  6,  3 }, {  4,  1 }}, ---  6
	{{ 13,  3 }, { 14,  3 }, { 18,  2 }, { 16,  1 }, { 19,  1 }}, ---  7
	{{ 16,  3 }, { 18,  3 }, { 17,  3 }, {  5,  3 }, {  7,  1 }}, ---  8
	{{  8,  2 }, { 10,  1 }, { 12,  1 }, { 11,  1 }, {  9,  3 }}, ---  9
	{{  4,  2 }, {  3,  2 }, {  2,  2 }, { 20,  1 }, { 15,  2 }}, --- 10
	{{ 19,  3 }, { 16,  2 }, {  7,  2 }, { 10,  3 }, {  8,  3 }}, --- 11
	{{ 15,  3 }, { 20,  3 }, { 14,  1 }, { 18,  1 }, { 17,  2 }}, --- 12
}

---@param vertex number 1..12
---@param face number 1..5
---@return number, number
function icosa_defines.face_vertex_at(vertex, face)
	return icosa_defines.vertex_faces[vertex][face][1], icosa_defines.vertex_faces[vertex][face][2]
end

return icosa_defines