package in.twizmwaz.cardinal.module.modules.kit.kitTypes;

import in.twizmwaz.cardinal.Cardinal;
import in.twizmwaz.cardinal.event.MatchEndEvent;
import in.twizmwaz.cardinal.module.modules.kit.KitRemovable;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerOnGroundEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.util.Vector;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Parts of code borrowed from
 * https://github.com/rmsy/DoubleJump
 *
 * Modified for use with CardinalPGM
 */

public class DoubleJumpKit implements KitRemovable {

    private boolean enabled;
    private int power;
    private float rechargePerTick;
    private boolean rechargeBeforeLanding;

    List<UUID> players = new ArrayList<>();
    List<UUID> landed = new ArrayList<>();

    public DoubleJumpKit(boolean enabled, int power, double rechargeTime, final boolean rechargeBeforeLanding) {
        this.enabled = enabled;
        this.power = power;
        this.rechargePerTick = (float)(0.1D / rechargeTime);
        this.rechargeBeforeLanding = rechargeBeforeLanding;

        Bukkit.getScheduler().runTaskTimer(Cardinal.getInstance(), new Runnable() {
            public void run() {
                for(UUID uuid : players) {
                    Player player = Bukkit.getPlayer(uuid);
                    if(player.getExp() < 1.0f && (rechargeBeforeLanding || landed.contains(uuid))) {
                        player.setExp(player.getExp() + rechargePerTick);
                    } else if(player.getExp() > 1.0f) {
                        player.setExp(1.0f);
                    }
                    if(player.getExp() >= 1.0f) {
                        player.setAllowFlight(true);
                    }
                }
            }
        }, 0, 2);
    }

    @Override
    public void unload() {
        HandlerList.unregisterAll(this);
    }

    @Override
    public void apply(Player player, Boolean force) {
        if (!enabled) return;
        players.add(player.getUniqueId());
        player.setExp(1.0f);
        player.setAllowFlight(true);
    }

    @Override
    public void remove(Player player) {
        if (!players.contains(player.getUniqueId())) return;
        players.remove(player.getUniqueId());
        player.setExp(0.0f);
        player.setAllowFlight(false);
    }

    @EventHandler(priority = EventPriority.LOWEST)
    public void onMatchEnd(MatchEndEvent event) {
        enabled = false;
        for(UUID uuid : players) {
            Player player = Bukkit.getPlayer(uuid);
            player.setExp(0.0f);
            player.setAllowFlight(false);
        }
        landed.clear();
        players.clear();
    }

    @EventHandler
    public void onPlayerGround(PlayerOnGroundEvent event) {
        if (!enabled || rechargeBeforeLanding) return;
        UUID id = event.getPlayer().getUniqueId();
        if (!players.contains(id) || landed.contains(id)) return;
        if (event.getOnGround()) landed.add(id);
    }

    @EventHandler
    public void onPlayerToggleFly(PlayerToggleFlightEvent event) {
        if (!enabled) return;
        Player player = event.getPlayer();
        if (!players.contains(player.getUniqueId()) || player.getExp() > 1.0f || !event.isFlying()) return;
        player.setAllowFlight(false);
        player.setExp(0.0f);
        event.setCancelled(true);

        Vector normal = player.getEyeLocation().getDirection();
        normal.setY(0.75 + Math.max(normal.getY() * 0.5, 0));
        normal.multiply(power / 2);
        event.getPlayer().setVelocity(normal);

        player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ZOMBIE_INFECT, 0.5f, 1.8f);
    }

}

@@ -849,21 +849,22 @@
 private 
-float
+double
  recharg
@@ -864,23 +864,20 @@
 recharge
-PerTick
+Time
 ;%0A    pr
@@ -908,24 +908,58 @@
 foreLanding;
+%0A    private long lastUpdate = 0L;
 %0A%0A    List%3CU
@@ -1234,32 +1234,14 @@
 arge
-PerTick = (float)(0.1D /
+Time =
  rec
@@ -1249,17 +1249,16 @@
 argeTime
-)
 ;%0A      
@@ -1428,32 +1428,344 @@
 run() %7B%0A        
+        DoubleJumpKit.this.update();%0A            %7D%0A        %7D, 0, 2);%0A    %7D%0A%0A    private void update() %7B%0A        int diff = (int) (System.currentTimeMillis() - lastUpdate);%0A        lastUpdate = System.currentTimeMillis();%0A        float toAddExp = rechargeTime %3E 0 ? (float) (diff / (rechargeTime * 1000)) : 1.0f;%0A
         for(UUID
@@ -1779,32 +1779,24 @@
  players) %7B%0A
-        
             
@@ -1831,32 +1831,24 @@
 ayer(uuid);%0A
-        
             
@@ -1940,32 +1940,24 @@
             
-  
-      
 player.setEx
@@ -1980,34 +1980,62 @@
 ) + 
-rechargePerTick);%0A        
+toAddExp %3E 1.0f ? 1.0f : player.getExp() + toAddExp);%0A
     
@@ -2090,32 +2090,24 @@
             
-        
 player.setEx
@@ -2123,38 +2123,26 @@
             
-        %7D%0A    
+%7D%0A
             
@@ -2133,36 +2133,32 @@
   %7D%0A            
-    
 if(player.getExp
@@ -2183,32 +2183,24 @@
             
-        
 player.setAl
@@ -2232,67 +2232,19 @@
     
-   
+%7D%0A   
      %7D
-%0A                %7D%0A            %7D%0A        %7D, 0, 2);
 %0A   
@@ -4121,16 +4121,35 @@
 , 1.8f);
+%0A%0A        update();
 %0A    %7D%0A%0A

Fix double jumps with 0 recharge not being instant