
local function light_gain(player)
    local light = minetest.get_natural_light(vector.offset(player:get_pos(), 0, 0.5, 0), 0.5)
    if not light then return 0 end
    light = math.min(light, 14)
    light = math.max(light / 14, 0.0001)
    return light
end

local rain_spawn_size = 30

local function start_weather(player, meta, from_weather)
    if meta.active then return end
    meta.active = true

    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner({
        amount = 100,
        time = 0,
        collisiondetection = true,
        collision_removal = true,
        object_collision = false,
        attached = player, -- to object ref
        vertical = true, -- If true face player using y axis only:-- If true face player using y axis only:
        texture = "br_weather_snow_1.png",
        playername = player:get_player_name(), -- only to this player
        glow = 0,
        minpos = vector.new(-rain_spawn_size, 20, -rain_spawn_size),
        maxpos = vector.new(rain_spawn_size, 20, rain_spawn_size),
        minvel = vector.new(-1, -8, -1),
        maxvel = vector.new(1, -6, 1),
        minacc = {x=0, y=0, z=0},
        maxacc = {x=0, y=0, z=0},
        minexptime = 7,
        maxexptime = 9,
        minsize = 1,
        maxsize = 1,
    })
    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner({
        amount = 100,
        time = 0,
        collisiondetection = true,
        collision_removal = true,
        object_collision = false,
        attached = player, -- to object ref
        vertical = true, -- If true face player using y axis only:-- If true face player using y axis only:
        texture = "br_weather_snow_2.png",
        playername = player:get_player_name(), -- only to this player
        glow = 0,
        minpos = vector.new(-rain_spawn_size, 20, -rain_spawn_size),
        maxpos = vector.new(rain_spawn_size, 20, rain_spawn_size),
        minvel = vector.new(-1, -8, -1),
        maxvel = vector.new(1, -6, 1),
        minacc = {x=0, y=0, z=0},
        maxacc = {x=0, y=0, z=0},
        minexptime = 7,
        maxexptime = 9,
        minsize = 1,
        maxsize = 1,
    })
    br_weather.request_sky(player, {
        base_color = "#e3e3e3",
        type = "regular",
        clouds = true,
        sky_color = {
            day_sky = br_weather.color(105, 110, 115),
            day_horizon = br_weather.color(105, 110, 115),
            dawn_sky = br_weather.color(93, 93, 95),
            dawn_horizon = br_weather.color(100, 87, 102),
            night_sky = br_weather.color(50, 41, 72),
            night_horizon = br_weather.color(50, 41, 71),
            indoors = br_weather.color(59, 59, 59),
            fog_sun_tint = br_weather.color(38, 57, 101),
            fog_moon_tint = br_weather.color(38, 57, 101),
            fog_tint_type = "custom",
        },
        fog = {
            fog_start = 0.4,
        },
    })
    player:set_clouds({
        density = 1.0,
        thickness = 20,
        ambient = "#111111",
        color = "#888888ee",
        height = 100,
        speed = {x=4, z=2}
    })
    player:set_sun({
        visible = true,
        texture = "blank.png",
        sunrise_visible = true,
    })
    player:set_moon({
        visible = true,
        texture = "blank.png",
    })
    br_weather.request_lighting(player, 0.43)
end

local function stop_weather(player, meta, to_weather)
    if not meta.active then return end
    meta.active = false
    for i, id in ipairs(meta.particlespawners) do
        minetest.delete_particlespawner(id)
    end
    meta.particlespawners = {}
end

br_weather.register_weather("snow", {
    biomes = {"default"},
    chance = 100,
    min_duration = 120, -- sec1
    max_duration = 300,
    light_factor = 0.8,
    on_enter_weather = function(player, meta, from_weather)
        start_weather(player, meta, from_weather)
    end,
    on_leave_weather = function(player, meta, to_weather)
        stop_weather(player, meta, to_weather)
        player:set_clouds()
        player:set_moon()
        player:set_sun()
    end,
    on_step = function(player, meta, dtime)
        meta.update_tick = (meta.update_tick or 1) - dtime
        if meta.update_tick <= 0 then
            meta.update_tick = 1
            local light = light_gain(player)
            if light < 0.1 then stop_weather(player, meta, "nil") return
            else start_weather(player, meta, "nil") end
        end
    end,
    next_weather = {
        ["heavy_rain"] = 0.3
    },
    fallbacks = {
        "light_rain",
        "clear",
    },
})

