local S = minetest.get_translator("hades_columnia")

hades_columnia.registered_materials = {}

-- List of all available shapes
local shapes = {
	"bottom", "mid", "top", "crosslink", "link", "linkangle",
	"linktee", "linkcross", "linkdown", "linkangle_down", "linktee_down",
	"linkcrossdown", "linkvertical", "stairsub", "stairsubpillar"
}

-- Given a recipe item (from which the columnia node is crafted)
-- and a 'fuel item' (a columnia node to register), this checks
-- if the recipeitem has a fuel recipe and if yes, registers
-- a recipe for the fuel item. The burntime is the recipe item's
-- burntime times `factor`.
-- If recipeitem is not a fuel, this function does nothing.
local register_fuel_from_recipeitem = function(recipeitem, fuelitem, factor)
	local input = {
		method = "fuel",
		items = { recipeitem },
	}
	local res = minetest.get_craft_result(input)
	if res and res.time and res.time > 0 then
		local burntime = math.max(1, math.ceil(res.time * factor))
		minetest.register_craft({
			type = "fuel",
			recipe = fuelitem,
			burntime = burntime,
		})
	end
end

function hades_columnia.register_all(craft, desc, image, groups, sounds, mat)

if not mat then
	mat = string.gsub(craft, ":", "_")
end

if not desc then
	desc = minetest.registered_items[craft].description
end

if not image then
	image = minetest.registered_items[craft].tiles[1]
end

if not groups then
	groups = table.copy(minetest.registered_items[craft].groups)
end
groups.not_in_creative_inventory = 1
groups.wood = nil
groups.tree = nil
groups.bark = nil
groups.cloth = nil
groups.stone = nil
groups.claybricks = nil
groups.colwood = nil

if not sounds then
	sounds = minetest.registered_items[craft].sounds
end

local on_place = function(itemstack, placer, pointed_thing)
	if pointed_thing.type ~= "node" then
		return itemstack
	end

	local p0 = pointed_thing.under
	local p1 = pointed_thing.above
	local param2 = 0

	local placer_pos = placer:get_pos()
	if placer_pos then
		local dir = {
			x = p1.x - placer_pos.x,
			y = p1.y - placer_pos.y,
			z = p1.z - placer_pos.z
		}
		param2 = minetest.dir_to_facedir(dir)
	end

	if p0.y-1 == p1.y then
		param2 = param2 + 20
		if param2 == 21 then
			param2 = 23
		elseif param2 == 23 then
			param2 = 21
		end
	end

	return minetest.item_place(itemstack, placer, pointed_thing, param2)
end

hades_columnia.registered_materials[craft] = mat

-- Make it a world-aligned tile if align_style is not set
local tile
if type(image) == "table" then
	tile = table.copy(image)
	if tile.align_style == nil then
		tile.align_style = "world"
	end
else
	tile = { name = image, align_style = "world" }
end
local tiles = {tile}

minetest.register_node("hades_columnia:column_mid_"..mat, {
	description = S("@1 Column", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, 
		}
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_top_"..mat,
})

local mod_screwdriver = minetest.get_modpath("screwdriver")
local on_rotate_column_top, on_rotate_column_bottom
if mod_screwdriver then
	on_rotate_column_top = function(pos, node, user, mode, new_param2)
		if mode == screwdriver.ROTATE_AXIS then
			node.name = "hades_columnia:column_bottom_"..mat
			minetest.swap_node(pos, node)
			return false
		end
	end
	on_rotate_column_bottom = function(pos, node, user, mode, new_param2)
		if mode == screwdriver.ROTATE_AXIS then
			node.name = "hades_columnia:column_top_"..mat
			minetest.swap_node(pos, node)
			return false
		end
	end
end

minetest.register_node("hades_columnia:column_top_"..mat, {
	description = S("@1 Column Top", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			   {-0.25, -0.5, -0.25, 0.25, 0, 0.25},
			   {-0.375, 0, -0.375, 0.375, 0.25, 0.375},
			   {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, 
		},
	},
	on_place = on_place,
	on_rotate = on_rotate_column_top,
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_bottom_"..mat,
})
register_fuel_from_recipeitem("hades_columnia:column_mid_"..mat, craft, 0.75)

minetest.register_node("hades_columnia:column_bottom_"..mat, {
	description = S("@1 Column Bottom", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			    {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
			    {-0.375, -0.25, -0.375, 0.375, 0, 0.375},
			    {-0.25, 0, -0.25, 0.25, 0.5, 0.25},
		},
	},
	on_place = on_place,
	on_rotate = on_rotate_column_bottom,
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_mid_"..mat,
})

minetest.register_node("hades_columnia:column_crosslink_"..mat, {
	description = S("@1 Column Crosslink", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			   {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25},
			   {-0.5, 0, -0.25, 0.5, 0.5, 0.25},
			   {-0.25, 0, -0.5, 0.25, 0.5, 0.5},
			   {-0.4375, 0.0625, -0.4375, 0.4375, 0.4375, 0.4375},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
})

minetest.register_node("hades_columnia:column_link_"..mat, {
	description = S("@1 Column Link", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, 0, -0.25, 0.5, 0.5, 0.25},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linktee_"..mat,
})

minetest.register_node("hades_columnia:column_linkdown_"..mat, {
	description = S("@1 Column Link Down", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			   {-0.5, 0, -0.25, 0.5, 0.5, 0.25},
			   {-0.125, -0.5, -0.125, 0.125, 0, 0.125},
			   {-0.1875, -0.5, -0.1875, 0.1875, -0.375, 0.1875},
			   {-0.1875, -0.125, -0.1875, 0.1875, 0, 0.1875},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linktee_down_"..mat,
})

minetest.register_node("hades_columnia:column_linkcross_"..mat, {
	description = S("@1 Column Link Cross", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.25, 0, -0.5, 0.25, 0.5, 0.5}, 
			{-0.5, 0, -0.25, 0.5, 0.5, 0.25},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linkangle_"..mat,
})

minetest.register_node("hades_columnia:column_linkcrossdown_"..mat, {
	description = S("@1 Column Link Cross Down", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.25, 0, -0.5, 0.25, 0.5, 0.5}, 
			{-0.5, 0, -0.25, 0.5, 0.5, 0.25}, 
			{-0.1875, -0.125, -0.1875, 0.1875, 0, 0.1875},
			{-0.1875, -0.5, -0.1875, 0.1875, -0.375, 0.1875}, 
			{-0.125, -0.375, -0.125, 0.125, -0.125, 0.125},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linkangle_down_"..mat,
})

minetest.register_node("hades_columnia:column_linkvertical_"..mat, {
	description = S("@1 Column Link Vertical", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			   {-0.1875, 0.375, -0.1875, 0.1875, 0.5, 0.1875}, 
			{-0.125, -0.375, -0.125, 0.125, -0.125, 0.125}, 
			{-0.1875, -0.125, -0.1875, 0.1875, 0.125, 0.1875},
			{-0.1875, -0.5, -0.1875, 0.1875, -0.375, 0.1875},
			{-0.125, 0.125, -0.125, 0.125, 0.375, 0.125},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
})


minetest.register_node("hades_columnia:column_linkangle_"..mat, {
	description = S("@1 Column Link Corner", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.25, 0, -0.25, 0.5, 0.5, 0.25},
			{-0.25, 0, -0.5, 0.25, 0.5, -0.25},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_link_"..mat,
})

minetest.register_node("hades_columnia:column_linkangle_down_"..mat, {
	description = S("@1 Column Link Corner Down", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.25, 0, -0.25, 0.5, 0.5, 0.25},
			{-0.25, 0, -0.5, 0.25, 0.5, -0.25},
			{-0.1875, -0.125, -0.1875, 0.1875, 0, 0.1875},
			{-0.1875, -0.5, -0.1875, 0.1875, -0.375, 0.1875},
			{-0.125, -0.375, -0.125, 0.125, -0.125, 0.125},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linkdown_"..mat,
})

minetest.register_node("hades_columnia:column_linktee_"..mat, {
	description = S("@1 Column Link T-Form", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, 0, -0.25, 0.5, 0.5, 0.25},
			{-0.25, 0, -0.5, 0.25, 0.5, -0.25},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linkcross_"..mat,
})

minetest.register_node("hades_columnia:column_linktee_down_"..mat, {
	description = S("@1 Column Link T-Form Down", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, 0, -0.25, 0.5, 0.5, 0.25},
			{-0.25, 0, -0.5, 0.25, 0.5, -0.25},
			{-0.1875, -0.125, -0.1875, 0.1875, 0, 0.1875}, 
			{-0.1875, -0.5, -0.1875, 0.1875, -0.375, 0.1875}, 
			{-0.125, -0.375, -0.125, 0.125, -0.125, 0.125},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_linkcrossdown_"..mat,
})

minetest.register_node("hades_columnia:column_stairsub_"..mat, {
	description = S("@1 Stair Substructure", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	--sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, 
			{-0.5, -0.5, 0.4375, 0.5, 0.4375, 0.5},
			{-0.5, -0.4375, 0.375, 0.5, 0.4375, 0.4375},
			{-0.5, -0.375, 0.3125, 0.5, 0.4375, 0.375},
			{-0.5, -0.3125, 0.25, 0.5, 0.4375, 0.3125},
			{-0.5, -0.25, 0.1875, 0.5, 0.4375, 0.25},
			{-0.5, -0.1875, 0.125, 0.5, 0.4375, 0.1875},
			{-0.5, -0.125, 0.0625, 0.5, 0.4375, 0.125},
			{-0.5, -0.0625, 0, 0.5, 0.4375, 0.0625},
			{-0.5, 0, -0.0625, 0.5, 0.4375, 0}, 
			{-0.5, 0.0625, -0.125, 0.5, 0.4375, -0.0625}, 
			{-0.5, 0.125, -0.1875, 0.5, 0.4375, -0.125}, 
			{-0.5, 0.1875, -0.25, 0.5, 0.4375, -0.1875}, 
			{-0.5, 0.25, -0.3125, 0.5, 0.4375, -0.25}, 
			{-0.5, 0.3125, -0.375, 0.5, 0.4375, -0.3125}, 
			{-0.5, 0.375, -0.4375, 0.5, 0.4375, -0.375},
		},
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_stairsubpillar_"..mat,
})

minetest.register_node("hades_columnia:column_stairsubpillar_"..mat, {
	description = S("@1 Stair Substructure Pillar", desc),
	drawtype = "nodebox",
	tiles = tiles,
	paramtype = "light",
	paramtype2 = "facedir",
	--sunlight_propagates = true,
	is_ground_content = false,
	groups = groups,
	node_box = {
		type = "fixed",
		fixed = {
			    {-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, 
				{-0.5, -0.5, 0.4375, 0.5, 0.4375, 0.5}, 
				{-0.5, -0.4375, 0.375, 0.5, 0.4375, 0.4375},
				{-0.5, -0.375, 0.3125, 0.5, 0.4375, 0.375},
				{-0.5, -0.3125, 0.25, 0.5, 0.4375, 0.3125},
				{-0.5, -0.25, 0.1875, 0.5, 0.4375, 0.25},
				{-0.5, -0.1875, 0.125, 0.5, 0.4375, 0.1875},
				{-0.5, -0.125, 0.0625, 0.5, 0.4375, 0.125},
				{-0.5, -0.0625, 0, 0.5, 0.4375, 0.0625},
				{-0.5, 0, -0.0625, 0.5, 0.4375, 0},
				{-0.5, 0.0625, -0.125, 0.5, 0.4375, -0.0625},
				{-0.5, 0.125, -0.1875, 0.5, 0.4375, -0.125}, 
				{-0.5, 0.1875, -0.25, 0.5, 0.4375, -0.1875}, 
				{-0.5, 0.25, -0.3125, 0.5, 0.4375, -0.25},
				{-0.5, 0.3125, -0.375, 0.5, 0.4375, -0.3125},
				{-0.5, 0.375, -0.4375, 0.5, 0.4375, -0.375},
				{-0.25, -0.5, -0.25, 0.25, 0.4375, 0.25},
		    },
	},
	on_place = on_place,
	on_rotate = "simple",
	sounds = sounds,
	_hades_shaper_next = "hades_columnia:column_stairsub_"..mat,
})

-- Add fuel recipes for columnia nodes based on nodes
-- that are fuels themselves.
register_fuel_from_recipeitem(craft, "hades_columnia:column_mid_"..mat, 0.25)
register_fuel_from_recipeitem(craft, "hades_columnia:column_bottom_"..mat, 0.75)
register_fuel_from_recipeitem(craft, "hades_columnia:column_top_"..mat, 0.75)
register_fuel_from_recipeitem(craft, "hades_columnia:column_crosslink_"..mat, 0.65)

register_fuel_from_recipeitem(craft, "hades_columnia:column_link_"..mat, 0.25)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linkangle_"..mat, 0.3)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linktee_"..mat, 0.325)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linkcross_"..mat, 0.35)

register_fuel_from_recipeitem(craft, "hades_columnia:column_linkdown_"..mat, 0.35)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linkangle_down_"..mat, 0.4)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linktee_down_"..mat, 0.425)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linkcrossdown_"..mat, 0.45)
register_fuel_from_recipeitem(craft, "hades_columnia:column_linkvertical_"..mat, 0.2)

register_fuel_from_recipeitem(craft, "hades_columnia:column_stairsub_"..mat, 0.75)
register_fuel_from_recipeitem(craft, "hades_columnia:column_stairsubpillar_"..mat, 0.82)

end

function hades_columnia.add_moss_extensions(craft_nonmossy, craft_mossy)
	local mat_nonmossy = hades_columnia.registered_materials[craft_nonmossy]
	local mat_mossy = hades_columnia.registered_materials[craft_mossy]
	for s=1, #shapes do
		local shape = shapes[s]
		minetest.override_item("hades_columnia:column_"..shape.."_"..mat_nonmossy, {
			_hades_mossy = "hades_columnia:column_"..shape.."_"..mat_mossy,
		})
		minetest.override_item("hades_columnia:column_"..shape.."_"..mat_mossy, {
			_hades_nonmossy = "hades_columnia:column_"..shape.."_"..mat_nonmossy,
		})
	end
end

-- Register aliases for nodes from old columnia version,
-- when this mod was still called 'columnia'
function hades_columnia.register_aliases(nodename)
	local mat = string.gsub(nodename, ":", "_")
	local mat2 = mat
	if string.sub(nodename, 1, 9) == "columnia:" then
		mat2 = "hades_columnia_" .. string.sub(nodename, 10, -1)
	end

	for s=1, #shapes do
		local shape = shapes[s]
		minetest.register_alias("columnia:column_"..shape.."_"..mat, "hades_columnia:column_"..shape.."_"..mat2)
	end
end
