
-- do return end -- debug

local function randf(m, n)
    return (math.random() * (n-m)) + m
end

local function randf_sign(m, n)
    return ((math.random() * (n-m)) + m) * (math.random(0,1)*2-1)
end

local _alpha_tween = {
    0.0, 0.9,
    style = "rev",
    reps = 1,
}
local _animation = {
    type = "vertical_frames",
    aspect_w = 64, aspect_h = 64,
    length = 1.5,
}

local part_static = {
    {
        name = "aom_climate_particle_wind_flat.png",
        alpha_tween = _alpha_tween,
        animation = _animation,
    },
}
local part_normal = {
    {
        name = "aom_climate_particle_wind.png",
        alpha_tween = _alpha_tween,
        animation = _animation,
    },
    {
        name = "aom_climate_particle_wind_2.png",
        alpha_tween = _alpha_tween,
        animation = _animation,
    },
}
local part_mirror = {
    {
        name = "aom_climate_particle_wind.png^[transformFX",
        alpha_tween = _alpha_tween,
        animation = _animation,
    },
    {
        name = "aom_climate_particle_wind_2.png^[transformFX",
        alpha_tween = _alpha_tween,
        animation = _animation,
    },
}

local function add_particles(player, amount)
    local pos = aom_climate.get_eyepos(player)
    local w = 120
    local offset = vector.normalize(vector.new(
        randf(-1, 1),
        randf(-1, 1),
        randf(-1, 1)
    ))
    if math.random() < 0.6 then offset.y = 0.001 end
    local p = (offset * (randf(0.1, 1) * w)) + pos
    local dir = aom_climate.wind.get_wind_or_nil(p)
    if not dir then return end
    local strength = vector.length(dir)
    if strength < 0.2 then return end

    p = p - dir * 10

    local wind_yaw = minetest.dir_to_yaw(dir)
    local pos_to_player_yaw = minetest.dir_to_yaw(vector.direction(p, pos))
    local angledist = aom_climate.shortangledist(wind_yaw, pos_to_player_yaw)
    local is_mirror = angledist < 0
    local is_static = math.abs(angledist) < 0.2
    is_static = is_static or (math.abs(angledist) > math.pi-0.2)

    local tex
    if is_static then tex = part_static
    elseif is_mirror then tex = part_mirror
    else tex = part_normal end

    local d = 4
    local r = vector.new(d,d,d)
    minetest.add_particlespawner({
        amount = math.ceil(7 * strength) + 1 + (amount or 0),
        time = 4,
        vertical = true,
        playername = player:get_player_name(),
        texpool = tex,
        minpos = p - r,
        maxpos = p + r,
        vel = dir * 15,
        exptime = 4,
        minsize = 12 * (is_static and (8/64) or 1),
        maxsize = 48 * (is_static and (8/64) or 1),
    })
end

local function add_particles_debug(player)
    local pos = aom_climate.get_eyepos(player)
    local w = 32
    local s = 4
    for z = -s, s do for y = -s, s do for x = -s, s do repeat
        local p = pos + (vector.new(x,y,z) * w)
        if p:equals(pos) then break end
        local wind = aom_climate.wind.get_wind_dir(p)
        wind = wind * 50
        aom_climate.debug_particle(p, "#ffffff", 1, wind, 6)
    until true end end end
end

local _t = 0
minetest.register_globalstep(function(dtime)
    if not aom_climate.get_setting(nil, "climate_wind_particles_server", false) then return end
    if _t > 0 then _t = _t - dtime; return else _t = _t + 0.1 end
    for i, player in ipairs(minetest.get_connected_players()) do
        if aom_climate.get_setting(player, "climate_wind_particles", false) then
            add_particles(player)
            -- add_particles_debug(player)
        end
    end
end)
