
artifact.registered_nodes = {}

function artifact.register_node(name, def)
    artifact.registered_nodes[name] = def
    def._name = name
    if not name:find ":" then
        name = "artifact:"..name
    end
    -- We might need to add groups below.
    if not def.groups then def.groups = {} end
    if artifact.debug then
        def.groups.dig_immediate = 3
    else
        def.groups.everything = 1
    end
    if def._variants then
        for _, x in ipairs(def._variants) do
            if x == "slab" then
                artifact.register_slab(def)
            elseif x == "stair" then
                artifact.register_stair(def)
            end
        end
    end
    minetest.register_node(":"..name, def)
    if name ~= def._name then
        minetest.register_alias(def._name, name)
    end
end

function artifact.register_craftitem(name, def)
    def._name = name
    if not name:find ":" then
        name = "artifact:"..name
    end 
    minetest.register_craftitem(":"..name, def)
    if name ~= def._name then
        minetest.register_alias(def._name, name)
    end
end

function artifact.register_slab(def)
    def = table.copy(def)
    def._variants = nil
    
    artifact.register_node(def._name.."_slab", extend(def, {
        drawtype = "nodebox",
        node_box = {
            type = "fixed",
            fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}
        },
        paramtype = "light",
        paramtype2 = "facedir"
    }))
end

function artifact.register_stair(def)
    def = table.copy(def)
    def._variants = nil
    
    def.groups[def._name.."_stair"] = 1
    
    artifact.register_node(def._name.."_stair", extend(table.copy(def), {
        drawtype = "nodebox",
        node_box = {
            type = "fixed",
            fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, 0, 0.5, 0.5, 0.5}}
        },
        paramtype = "light",
        paramtype2 = "facedir"
    }))

    artifact.register_node(def._name.."_stair_inner", extend(table.copy(def), {
        drawtype = "nodebox",
        node_box = {
            type = "fixed",
            fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5, 0, 0.5, 0.5}}
        },
        paramtype = "light",
        paramtype2 = "facedir"
    }))

    artifact.register_node(def._name.."_stair_outer", extend(def, {
        drawtype = "nodebox",
        node_box = {
            type = "fixed",
            fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, 0, 0.5, 0, 0.5, 0}}
        },
        paramtype = "light",
        paramtype2 = "facedir"
    }))
end

local function rep(tx, size)
    local out = "[combine:"..(size *16).."x"..(size *16)
    for x = 0, size -1 do
        for y = 0, size -1 do
            out = out..":"..(x *16)..","..(y *16).."="..tx
        end
    end
    return out
end


-- Sound tables for material types.
artifact.sounds = {
    stone = {
        footstep = "artifact_step_stone"
    },
    mossy_stone = {
        footstep = "artifact_step_stone_mossy"
    },
    metal = {
        footstep = "artifact_step_stone" -- We don't have a separate sound for this, so just use stone for now.
    },
    wood = {
        footstep = "artifact_step_stone"
    },
    leaves = {
        footstep = "artifact_step_leaves"
    },
    dry_leaves = {
        footstep = "artifact_step_leaves_dry"
    },
    glass = {
        footstep = "artifact_step_glass"
    },
    water = {
        footstep = "artifact_water"
    }
}


-- These nodes are only used for the intro cutscene.

artifact.register_node("stone_brown", {
    tiles = {{name = "artifact_stone_brown.png", align_style = "world"}},
    _variants = {"stair", "slab"}
})

artifact.register_node("stone_tile_brown", {
    tiles = {{name = "artifact_stone_tile_brown.png", align_style = "world"}},
    _variants = {"stair", "slab"}
})

artifact.register_node("stone_bricks_brown", {
    tiles = {{name = "artifact_stone_bricks_brown.png", align_style = "world"}},
    _variants = {"stair", "slab"}
})

artifact.register_node("torch", {
    drawtype = "mesh",
    paramtype2 = "facedir",
    mesh = "artifact_torch.obj",
    tiles = {"artifact_torch.png"},
    use_texture_alpha = "clip",
    light_source = 10,
    paramtype = "light",
    sunlight_propagates = true
})

artifact.register_node("torch_standing", {
    drawtype = "mesh",
    paramtype2 = "facedir",
    mesh = "artifact_torch_standing.obj",
    tiles = {"artifact_torch.png"},
    use_texture_alpha = "clip",
    light_source = 10,
    paramtype = "light",
    sunlight_propagates = true
})

-- End ad-hoc nodes.

artifact.register_node("stone", {
    tiles = {{name = "artifact_stone.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.stone,
})
artifact.register_node("stone_mossy", {
    tiles = {{name = rep("artifact_stone.png", 4).."^artifact_moss.png", align_style = "world", scale = 4}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.mossy_stone,
})

artifact.register_node("stone_bricks", {
    tiles = {{name = "artifact_stone_bricks.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.stone,
})
artifact.register_node("stone_bricks_mossy", {
    tiles = {{name = rep("artifact_stone_bricks.png", 4).."^artifact_moss_bricks.png", align_style = "world", scale = 4}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.mossy_stone,
})

artifact.register_node("stone_bricks_small", {
    tiles = {{name = "artifact_stone_bricks_small.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.stone,
})
artifact.register_node("stone_bricks_small_mossy", {
    tiles = {{name = rep("artifact_stone_bricks_small.png", 4).."^artifact_moss_bricks_small.png", align_style = "world", scale = 4}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.mossy_stone,
})

artifact.register_node("stone_tile", {
    tiles = {{name = "artifact_stone_tile.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.stone,
})

artifact.register_node("stone_tile_small", {
    tiles = {{name = "artifact_stone_tile_small.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.stone,
})

-- Why does making this texture a tile animation darken it!?
artifact.register_node("water", {
    tiles = {{name = "artifact_water_source.png^[opacity:150", animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 6}}},
    drawtype = "liquid",
    use_texture_alpha = "blend",
    paramtype = "light",
    walkable = false,
    pointable = artifact.debug,
    liquid_move_physics = true,
    post_effect_color = "#2d5a7c55",
    sounds = artifact.sounds.water,
    
    liquidtype = "source",
    -- Minetest pro tip: Do not try to use aliases for these.
    liquid_alternative_source = "artifact:water",
    liquid_alternative_flowing = "artifact:water_flowing",
    liquid_viscosity = 1,
    liquid_range = 5,
})

artifact.register_node("water_flowing", {
    tiles = {{name = "artifact_water_flowing.png^[opacity:150", animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 0.5}}},
    special_tiles = {
        {name = "artifact_water_flowing.png^[opacity:150", animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 0.5}},
        {name = "artifact_water_flowing.png^[opacity:150", animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 0.5}}
    },
    drawtype = "flowingliquid",
    use_texture_alpha = "blend",
    paramtype = "light",
    paramtype2 = "flowingliquid",
    walkable = false,
    pointable = artifact.debug,
    buildable_to = true,
    liquid_move_physics = true,
    post_effect_color = "#2d5a7c55",
    drop = "",
    sounds = artifact.sounds.water,
    
    liquidtype = "flowing",
    liquid_alternative_source = "artifact:water",
    liquid_alternative_flowing = "artifact:water_flowing",
    liquid_viscosity = 1,
    liquid_range = 5,
})

-- Minetest doesn't properly handle having a custom nodebox on a liquid source, so we do this the hacky way.
artifact.register_node("water_static", {
    tiles = {{name = "artifact_water_source.png^[opacity:150", animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 6}}},
    drawtype = "nodebox",
    node_box = {
        type = "leveled",
        fixed = {
            -0.5, -0.5, -0.5,
             0.5, 6/16,  0.5
        }
    },
    use_texture_alpha = "blend",
    paramtype = "light",
    paramtype2 = "leveled",
    place_param2 = 60,
    walkable = false,
    pointable = artifact.debug,
    liquid_move_physics = true,
    post_effect_color = "#2d5a7c55",
    sounds = artifact.sounds.water,
})


artifact.register_node("vines", {
    drawtype = "nodebox",
    node_box = {
        type = "fixed",
        fixed = {
            -0.5, -0.5, 0.48,
             0.5,  0.5, 0.48
        }
    },
    walkable = false,
    selection_box = {
        type = "fixed",
        fixed = {
            -0.5, -0.5, 0.5,
             0.5,  0.5, 0.35
        }
    },
    paramtype = "light",
    paramtype2 = "facedir",
    tiles = {"artifact_vines.png"},
    use_texture_alpha = "clip",
    sounds = artifact.sounds.leaves,
})
artifact.register_node("vines_dry", {
    drawtype = "nodebox",
    node_box = {
        type = "fixed",
        fixed = {
            -0.5, -0.5, 0.48,
             0.5,  0.5, 0.48
        }
    },
    walkable = false,
    selection_box = {
        type = "fixed",
        fixed = {
            -0.5, -0.5, 0.5,
             0.5,  0.5, 0.35
        }
    },
    paramtype = "light",
    paramtype2 = "facedir",
    tiles = {"artifact_vines_dry.png"},
    use_texture_alpha = "clip",
    groups = {whackable = 1},
    sounds = artifact.sounds.dry_leaves,
    on_destruct = function(pos)
        artifact.play_sound {
            name = "artifact_step_leaves",
            pos = pos,
            gain = 1.5
        }
    end
})

artifact.register_node("leaves", {
    drawtype = "allfaces",
--    paramtype = "light",
    tiles = {"artifact_leaves.png"},
    use_texture_alpha = "clip",
    sounds = artifact.sounds.leaves,
})
artifact.register_node("leaves_dry", {
    drawtype = "allfaces",
--    paramtype = "light",
    tiles = {"artifact_leaves_dry.png"},
    use_texture_alpha = "clip",
    groups = {whackable = 1},
    sounds = artifact.sounds.dry_leaves,
    on_destruct = function(pos)
        artifact.play_sound {
            name = "artifact_step_leaves",
            pos = pos,
            gain = 1.5
        }
    end
})


artifact.register_node("wood_planks", {
    tiles = {{name = "artifact_wood_planks.png", align_style = "world"}},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.wood,
})

artifact.register_node("crate", {
    tiles = {{name = "artifact_crate.png", align_style = "world"}},
    sounds = artifact.sounds.wood,
})

artifact.register_node("ladder_wood", {
    drawtype = "mesh",
    mesh = "artifact_ladder.obj",
    paramtype = "light",
    paramtype2 = "facedir",
    tiles = {"artifact_ladder_wood.png"},
    walkable = false,
    climbable = true,
    sounds = artifact.sounds.wood,
})

artifact.register_node("ladder_iron", {
    drawtype = "mesh",
    mesh = "artifact_ladder.obj",
    paramtype = "light",
    paramtype2 = "facedir",
    tiles = {"artifact_ladder_iron.png"},
    walkable = false,
    climbable = true,
    sounds = artifact.sounds.metal,
})


artifact.register_node("glass", {
    drawtype = "glasslike",
    use_texture_alpha = "clip",
    tiles = {"artifact_glass.png"},
    _variants = {"stair", "slab"},
    sounds = artifact.sounds.glass,
})


local function register_lamp(color, brightness)
    artifact.register_node("lamp_"..color, {
        drawtype = "mesh",
        mesh = "artifact_lamp.obj",
        tiles = {"artifact_lamp_"..color..".png"},
        light_source = brightness,
        paramtype = "light",
        sunlight_propagates = true,
        collision_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,0,-2/16,
                    2/16, 4/16, 2/16
                }
            }
        },
        selection_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,0,-2/16,
                    2/16, 4/16, 2/16
                }
            }
        },
        sounds = artifact.sounds.glass,
    })
    artifact.register_node("lamp_"..color.."_wall", {
        drawtype = "mesh",
        mesh = "artifact_lamp_wall.obj",
        tiles = {"artifact_lamp_"..color..".png"},
        light_source = brightness,
        paramtype = "light",
        sunlight_propagates = true,
        paramtype2 = "facedir",
        collision_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,-1/16,-1/16,
                    2/16, 3/16, 3/16
                },
                {
                    -1/16,4/16,-1/16,
                    1/16, 6/16, 8/16
                },
            }
        },
        selection_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,-1/16,-1/16,
                    2/16, 3/16, 3/16
                },
                {
                    -1/16,4/16,-1/16,
                    1/16, 6/16, 8/16
                },
            }
        },
        sounds = artifact.sounds.glass,
    })
    artifact.register_node("lamp_"..color.."_hanging", {
        drawtype = "mesh",
        mesh = "artifact_lamp_hanging.obj",
        tiles = {"artifact_lamp_"..color..".png"},
        light_source = brightness,
        paramtype = "light",
        sunlight_propagates = true,
        collision_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,0,-2/16,
                    2/16, 4/16, 2/16
                }
            }
        },
        selection_box = {
            type = "fixed",
            fixed = {
                {
                    -2/16,0,-2/16,
                    2/16, 4/16, 2/16
                }
            }
        },
        sounds = artifact.sounds.glass,
    })
end

register_lamp("red", 6)
register_lamp("green", 8)
register_lamp("blue", 10)
register_lamp("gold", 12)


artifact.register_node("light", {
    tiles = {"artifact_light.png"},
    paramtype = "light",
    light_source = 14
})

-- Make darkness the default.
minetest.override_item("air", {
    sunlight_propagates = false,
    light_source = 2 -- But not _too_ much darkness...
})

if artifact.debug then

    minetest.register_mapgen_script(minetest.get_modpath(minetest.get_current_modname()).."/mapgen_debug.lua")
    
    minetest.register_decoration {
        deco_type = "simple",
        decoration = "lamp_gold",
        place_on = "stone",
        fill_ratio = 0.02,
    }
else
    minetest.register_mapgen_script(minetest.get_modpath(minetest.get_current_modname()).."/mapgen.lua")
end
