local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local S = minetest.get_translator(mod_name)

local basic_items = {
    ["br_core:relocator"] = true,
    -- ["br_core:flashlight"] = true,
    -- ["br_core:flashlight_on"] = true,
}
local start_kit = {
    ["br_core:relocator"]=6,
    ["br_core:flashlight"]=1,
}

function br_core.debug_particle(pos, color, time, vel, size)
    -- do return end -- for debug purposes
    core.add_particle({
        size = size or 2,
        pos = pos,
        texture = "white.png^[colorize:"..(color or "#fff")..":255",
        velocity = vel or vector.new(0, 0, 0),
        expirationtime = time,
        glow = 14,
    })
end

local __cardinal_rotate_filters = {
    function (v) return vector.new( v.x, v.y, v.z) end, -- 0
    function (v) return vector.new( v.z, v.y,-v.x) end, -- 90
    function (v) return vector.new(-v.x, v.y,-v.z) end, -- 180
    function (v) return vector.new(-v.z, v.y, v.x) end, -- 270
}
-- rotates vector around Y axis, snapped to cardinal (90 degree) directions
function br_core.cardinal_rotate(v, r)
	return __cardinal_rotate_filters[math.round(r) % 4 + 1](v)
end

-- prevent pulverize command
if not br_core.dev_mode then
    minetest.unregister_chatcommand("pulverize")
end

local function show_dev_warning(player, text)
    local hid = player:hud_add({
        hud_elem_type = "text",
        text = text,
        scale = {x = 0, y = 0},
        size = {x = 1.4, y = 0},
        alignment = {x = 0, y = 0},
        position = {x = 0.5, y = 1},
        offset = {x = 8, y = -8 - 200},
        number = 0xFF5560,
        z_index = 2000,
    })
    local hid2 = player:hud_add({
        hud_elem_type = "image",
        alignment = {x = 0, y = 0},
        position = {x = 0.5, y = 1},
        name = "devmodewarningbg",
        text = "br_meta_blank.png^[colorize:#66223380:255",
        z_index = 1999,
        scale = {x = 2, y = 1.0},
        offset = {x = 0, y = -200},
    })
    minetest.after(20, function()
        if player then
            player:hud_change(hid, "number", 0xAA3322)
            player:hud_change(hid2, "text", "br_meta_blank.png^[colorize:#66223330:255")
        end
    end)
    minetest.after(24, function()
        if player then
            player:hud_remove(hid)
            player:hud_remove(hid2)
        end
    end)
end

-- init the player on join
minetest.register_on_joinplayer(function(player, last_login)
    if player.set_lighting then -- compat
	    player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("br_shadow_intensity") or 0.33) } })
    end

    player:hud_set_flags({
        minimap_radar = (br_core.dev_mode or false),
        minimap = (br_core.dev_mode or false),
        healthbar = (br_core.dev_mode or false),
        basic_debug = (br_core.dev_mode or false),
    })

    if not last_login then
        local inv = player:get_inventory()
        for itemname, i in pairs(start_kit) do
            if not inv:contains_item("main", ItemStack(itemname)) then
                inv:set_stack("main", i, ItemStack(itemname))
            end
        end
    end
    if player:get_meta():get_string("seen_creative_warning") == "true" then return end
    if minetest.is_creative_enabled() or br_core.mapgen == "flat" then
        show_dev_warning(player, "WARNING: DEV MODE / CREATIVE ACTIVE\n----------------------\n"..
        "THIS IS NOT MEANT TO BE USED\nEXCEPT BY DEVELOPERS!\n\nMOST FEATURES ARE DISABLED\n"..
        "AND DEBUG IS VISIBLE, TURN OFF\nIN WORLD MENU FOR INTENDED EXPERIENCE\nUSE  \"/creative ignore\"  ONCE TO NEVER SHOW THIS AGAIN")
    end
end)

br_core.on_changed_level_calls = {}
br_core.registered_on_level_enter = {}
br_core.registered_on_level_exit = {}
local call = br_core.on_changed_level_calls

function br_core.register_on_changed_level(func)
    call[#call+1] = func
end

function br_core.register_on_level_enter(func)
    table.insert(br_core.registered_on_level_enter, func)
end

function br_core.register_on_level_exit(func)
    table.insert(br_core.registered_on_level_exit, func)
end

function br_core.on_changed_level(player, from_level, to_level)
    for i, func in ipairs(br_core.registered_on_level_exit) do
        func(player, from_level, to_level)
    end
    for i, func in ipairs(br_core.registered_on_level_enter) do
        func(player, from_level, to_level)
    end
    for i, func in ipairs(call) do
        func(player, from_level, to_level)
    end
end

minetest.register_globalstep(function(dtime)
    minetest.set_timeofday(0.49)
end)

local default_sun = {
    visible = false,
    sunrise_visible = false,
}
local default_moon = {
    visible = false,
}
local default_sky = {
    clouds = false,
    base_color = "#001",
    type = "plain"
}
local default_clouds = {
    density = 0,
    thickness = 1,
    height = -100
}
local dev_params = {
    sky = {
		base_color = "#ffffff",
		type = "regular",
		clouds = false,
		sky_color = {
			day_sky = "#60b3f3" ,
			day_horizon = "#8fd1f4",
			dawn_sky = "#cec1cc" ,
			dawn_horizon = "#f4a68f",
			night_sky = "#263965" ,
			night_horizon = "#263965",
			indoors = "#263965",
			fog_sun_tint = "#263965",
			fog_moon_tint = "#263965",
			fog_tint_type = "custom",
		}
	}
}

local function set_sky(player, param)
    player:set_sky(param or (default_sky))
end
local function set_sun(player, param)
    player:set_sun(param or (default_sun))
end
local function set_moon(player, param)
    player:set_moon(param or (default_moon))
end
local function set_clouds(player, param)
    player:set_clouds(param or (default_clouds))
end

br_core.register_on_changed_level(function(player, from_level, to_level)
    local to_def = br_core.level[to_level]
    if (not br_core.dev_mode) and to_def then
        if to_def.weather then
            if to_def.weather == true then
            else
                br_core.override_player_weather(player, to_def.weather)
            end
        else
            br_core.override_player_weather(player, "clear")
        end
        set_sky(player, to_def.sky)
        set_sun(player, to_def.sun)
        set_moon(player, to_def.moon)
        set_clouds(player, to_def.clouds)
    elseif not br_core.dev_mode then
        br_core.override_player_weather(player, "clear")
        player:set_sky({
            base_color = "#001",
            type = "plain"
        })
        br_core.override_player_weather(player, "clear")
    else
        br_core.override_player_weather(player, "clear")
        set_sky(player, dev_params.sky)
        set_sun(player, nil)
        set_moon(player, nil)
        set_clouds(player, nil)
    end
end)


minetest.register_chatcommand("level", {
	params = "level [number]",
	description = S("Teleports the player to that level if it exists"),
	privs = {},
	func = function(name, param)
        local num = tonumber(param)
        local player = minetest.get_player_by_name(name)
        if type(num) == "number" and num >= 0 and num <= 180 then
            if br_core.level[num] then
                br_spawn.relocate_player(player, num)
                return true, S("Going to level "..num)
            end
        end
        local levels = ""
        for i=1, #br_core.level_for_index do
            levels = levels..(br_core.index_to_level(i))..(i < #br_core.level_for_index and ", " or "")
        end
        local curlevel = "???"
        if br_spawn.player[name] then curlevel = br_spawn.player[name].level end
        return false, (minetest.colorize("#ffff99", ("List of levels: \n"))..minetest.colorize("#99ff99", levels)..
            "\nThis level: "..minetest.colorize("#ffff99", curlevel))
	end
})

br_core.hand_def = {}
br_core.hand_def.groupcaps_creative = {
    oddly_breakable_by_hand = {
        times = { 0.1, 0.3, 2 },
        uses = 0,
    },
    cracky = {
        times = { 0.5, 0.8, 2 },
        uses = 0,
    },
    dig_immediate = {
        times = { 0.5, 0.5, 0 },
        uses = 0,
    },
}
br_core.hand_def.groupcaps = {
    oddly_breakable_by_hand = {},
    cracky = {},
    dig_immediate = {},
}
--  add hand tool
minetest.override_item("", {
	wield_image = "blank.png",
	wield_scale = { x = 3, y = 3, z = 5 },
    range = (br_core.dev_mode and 10) or nil,
	tool_capabilities = {
		full_punch_interval = 0.5,
		max_drop_level = 0,
		groupcaps = br_core.hand_def.groupcaps,
		damage_groups = { fleshy = 1 },
	}
})

minetest.register_tool("br_core:creative_hand", {
	wield_image = "blank.png",
	wield_scale = { x = 3, y = 3, z = 5 },
    range = 10,
	tool_capabilities = {
		full_punch_interval = 0.5,
		max_drop_level = 0,
		groupcaps = br_core.hand_def.groupcaps_creative,
		damage_groups = { fleshy = 1 },
	}
})

function br_core.rand_range(s,m)
    return math.random() * (m-s) + s
end

function br_core.get_natural_light(pos, time)
    if minetest.get_natural_light ~= nil then
        return minetest.get_natural_light(pos, time) or 0
    else
        return minetest.get_node_light(pos, time) or 0
    end
end

br_core.has_br_weather = core.get_modpath("br_weather") ~= nil
function br_core.override_player_weather(player, weather_name)
    if not br_core.has_br_weather then return end
    br_weather.override_player_weather(player, weather_name)
end

function br_core.unoverride_player_weather(player)
    if not br_core.has_br_weather then return end
    br_weather.unoverride_player_weather(player)
end
