package de.fanta.challenges;
import de.fanta.challenges.events.TimerChangedEvent;
import de.fanta.challenges.schedular.CancellableTask;
import de.fanta.challenges.utils.ChatUtil;
import de.fanta.challenges.utils.Config;
import de.iani.cubesideutils.StringUtil;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class Timer {
private final Challenges plugin;
private CancellableTask actionBarTaskId;
private CancellableTask idleActionBarTaskId;
private long time; // milliseconds
private TimerMode mode;
private long countingSinceTimestamp;
public Timer(Challenges plugin) {
this.plugin = plugin;
this.mode = TimerMode.UP;
if (!isRunning()) {
sendIdleActionBar();
}
}
public void startTimer() {
countingSinceTimestamp = System.currentTimeMillis();
if (idleActionBarTaskId != null) {
idleActionBarTaskId.cancel();
idleActionBarTaskId = null;
}
actionBarTaskId = plugin.getScheduler().runGlobalAtFixedRate(() -> {
if (mode == TimerMode.DOWN) {
if (time <= 0) {
if (Config.getBoolean("event.enabled")) {
for (Player p : Bukkit.getOnlinePlayers()) {
p.setGameMode(GameMode.SPECTATOR);
}
ChatUtil.sendTitleToAll("Event", "Die Zeit ist abgelaufen!", ChatUtil.GREEN);
} else {
for (Player p : Bukkit.getOnlinePlayers()) {
p.setGameMode(GameMode.SPECTATOR);
p.sendTitle(ChatUtil.RED + "ZEIT ABGELAUFEN!", ChatUtil.RED + "Challenge fehlgeschlagen", 10, 60, 10);
}
ChatUtil.sendBrodcastMessage(ChatUtil.RED + "Die Zeit ist abgelaufen und die Challenge somit fehlgeschlagen!");
ChatUtil.sendBrodcastMessage("Seed: " + ChatUtil.BLUE + Bukkit.getWorlds().get(0).getSeed());
}
stopTimer();
} else {
time -= (System.currentTimeMillis() - countingSinceTimestamp);
countingSinceTimestamp = System.currentTimeMillis();
sendTimerActionBar(ChatUtil.BLUE);
}
} else {
time += (System.currentTimeMillis() - countingSinceTimestamp);
countingSinceTimestamp = System.currentTimeMillis();
sendTimerActionBar(ChatUtil.GREEN);
}
}, 20L, 20L);
if (!Config.getBoolean("firsttimerstart")) {
Config.setValue("firsttimerstart", true, false);
}
Bukkit.getPluginManager().callEvent(new TimerChangedEvent(true));
}
public void stopTimer() {
if (actionBarTaskId != null) {
actionBarTaskId.cancel();
actionBarTaskId = null;
sendIdleActionBar();
}
for (Player pp : Bukkit.getOnlinePlayers()) {
plugin.getScheduler().runDelayedOnEntity(pp, () -> {
for (final Entity entity : pp.getNearbyEntities(100, 100, 100)) {
if ((entity instanceof final Creature creature)) {
if ((creature.getTarget() != null) && creature.getTarget().equals(pp)) {
creature.setTarget(null);
}
}
}
}, 1);
}
Bukkit.getPluginManager().callEvent(new TimerChangedEvent(false));
}
private void sendIdleActionBar() {
idleActionBarTaskId = plugin.getScheduler().runGlobalAtFixedRate(() -> {
for (Player p : Bukkit.getOnlinePlayers()) {
if (!plugin.getVanish().isVanish(p)) {
p.sendActionBar(ChatUtil.RED + "" + ChatColor.BOLD + "Der Timer ist pausiert.");
if (p.getGameMode() != GameMode.SPECTATOR) {
p.getWorld().playEffect(p.getLocation(), Effect.ENDER_SIGNAL, 2);
}
}
}
}, 20L, 20L);
}
private void sendTimerActionBar(ChatColor color) {
for (Player p : Bukkit.getOnlinePlayers()) {
if (!plugin.getVanish().isVanish(p)) {
if (Config.getBoolean("showtimer")) {
if (Config.getBoolean("editsettings")) {
p.sendActionBar(formatTime(color));
} else {
p.sendActionBar(ChatUtil.GREEN + "SpeedRun " + formatTime(color));
}
}
}
}
}
public String formatTime(ChatColor color) {
return color + formatTime();
}
public String formatTime() {
String formattime = StringUtil.formatTimespan((time / 1000) * 1000, " Tage, ", ":", "", "", "", ":", false, true);
if (formattime.startsWith("1 Tage")) {
return StringUtil.formatTimespan((time / 1000) * 1000, " Tag, ", ":", "", "", "", ":", false, true);
}
return formattime;
}
public void reverseTimer() {
if (mode == TimerMode.DOWN) {
mode = TimerMode.UP;
} else {
mode = TimerMode.DOWN;
}
if (isRunning()) {
countingSinceTimestamp = System.currentTimeMillis();
}
}
public boolean isRunning() {
return actionBarTaskId != null;
}
public boolean isReverse() {
return mode == TimerMode.DOWN;
}
public long getTime() {
return time / 1000;
}
public long getTimeInMs() {
return time;
}
public void setTime(int seconds) {
this.time = seconds * 1000L;
this.countingSinceTimestamp = System.currentTimeMillis();
}
public void addTime(int seconds) {
this.time = Math.max(time + (seconds * 1000L), 0);
this.countingSinceTimestamp = System.currentTimeMillis();
Config.setValue("editsettings", true);
}
public void removeTime(int seconds) {
this.time = Math.max(time - (seconds * 1000L), 0);
this.countingSinceTimestamp = System.currentTimeMillis();
Config.setValue("editsettings", true);
}
private enum TimerMode {
UP,
DOWN
}
}