package reddeathartifacts.vibration;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import reddeathartifacts.entity.Warden;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class VibrationManager {

    private static final List<VibrationManager> worldManagers = new ArrayList<>();

    public static VibrationManager get(World world) {
        for (VibrationManager manager : worldManagers) {
            if (manager.world == world) return manager;
        }
        VibrationManager newManager = new VibrationManager(world);
        worldManagers.add(newManager);
        return newManager;
    }

    public static void tickAll() {
        for (VibrationManager manager : worldManagers) {
            manager.tick();
        }
    }

    private final World world;
    private final List<Vibration> vibrations = new ArrayList<>();

    public static class Vibration {
        public final Entity source;
        public final BlockPos pos;
        public final GameEvent gameEvent;
        public int ticksToLive;

        public Vibration(Entity source, BlockPos pos, GameEvent gameEvent, int duration) {
            this.source = source;
            this.pos = pos;
            this.gameEvent = gameEvent;
            this.ticksToLive = duration;
        }
    }

    public VibrationManager(World world) { this.world = world; }

    public void addVibration(Entity source, BlockPos pos, GameEvent event, int duration) {
        if (source == null || event == null) return;
        vibrations.add(new Vibration(source, pos, event, duration));
    }

    public void tick() {
        Iterator<Vibration> iterator = vibrations.iterator();

        while (iterator.hasNext()) {
            Vibration v = iterator.next();

            AxisAlignedBB box = new AxisAlignedBB(v.pos).grow(32.0D);
            List<Warden> wardens = world.getEntitiesWithinAABB(Warden.class, box);

            for (Warden warden : wardens) {
                VibrationSystem.Listener listener = new VibrationSystem.Listener(warden.getVibrationData(), warden);
                listener.handleGameEvent(this.world, v.gameEvent, v.source, new Vec3d(v.pos.getX() + 0.5, v.pos.getY() + 0.5, v.pos.getZ() + 0.5));
            }

            v.ticksToLive--;
            if (v.ticksToLive <= 0) iterator.remove();
        }
    }

    public void addPlayerStep(EntityPlayer player) { 
        addVibration(player, player.getPosition(), GameEvent.STEP, 5); 
    }
    
    public void addBlockEvent(Entity source, BlockPos pos) { 
        addVibration(source, pos, GameEvent.BLOCK_PLACE, 5); 
    }
    
    public void addProjectileImpact(Entity projectile, BlockPos pos) { 
        addVibration(projectile, pos, GameEvent.PROJECTILE_LAND, 5); 
    }
    
    public void addExplosion(Entity source, BlockPos pos) {
        addVibration(source, pos, GameEvent.EXPLODE, 5);
    }
}