/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.lobby.particle;

import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;

import java.util.Random;
import java.util.function.Consumer;

public interface ParticleElement {
    Random RANDOM = new Random();

    default Color randomColor() {
        return Color.fromRGB(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255));
    }

    default float randomSize() {
        return RANDOM.nextFloat() / 2 + 1;
    }

    default Particle.DustOptions randomParticleDust() {
        return new Particle.DustOptions(randomColor(), randomSize());
    }

    default Particle.DustOptions withColor(int r, int g, int b) {
        return new Particle.DustOptions(Color.fromRGB(r, g, b), (float) (RANDOM.nextFloat() / 2 + 0.5));
    }

    default void display(Location location, Player root, boolean onlySelf, boolean onlyOther, Consumer<Player> consumer) {
        if (onlySelf) {
            consumer.accept(root);
            return;
        }
        Bukkit.getOnlinePlayers().forEach(player -> {
            if (onlyOther && player == root) {
                return;
            }
            int viewDistance = player.getClientViewDistance() * 16;
            if (location.distanceSquared(player.getLocation()) <= viewDistance * viewDistance) {
                consumer.accept(player);
            }
        });
    }

    default void aggregateAttributes(ParticleData particleData) {
    }

    default ParticleTickType tickType() {
        return ParticleTickType.MOVE;
    }

    void tick(ParticleTickData particleTickData);
}
