/*
 *   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.core;

import de.steamwar.entity.CWireframe;
import de.steamwar.entity.REntityServer;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;

import java.util.HashMap;
import java.util.Map;

public class WorldEditRendererWrapper20 implements WorldEditRendererWrapper {

    private static final class BoxPair {
        private CWireframe regionBox;
        private CWireframe clipboardBox;

        public CWireframe get(boolean clipboard) {
            if (clipboard) {
                return clipboardBox;
            } else {
                return regionBox;
            }
        }

        public void set(boolean clipboard, CWireframe box) {
            if (clipboard) {
                this.clipboardBox = box;
            } else {
                this.regionBox = box;
            }
        }

        public void die() {
            if (clipboardBox != null) {
                clipboardBox.die();
            }
            if (regionBox != null) {
                regionBox.die();
            }
        }
    }

    private static final Map<Player, REntityServer> servers = new HashMap<>();
    private static final Map<Player, BoxPair> boxes = new HashMap<>();

    @Override
    public void draw(Player player, boolean scheduled, boolean clipboard, Vector pos1, Vector pos2) {
        REntityServer server = servers.computeIfAbsent(player, __ -> {
            REntityServer entityServer = new REntityServer();
            entityServer.addPlayer(player);
            return entityServer;
        });

        WorldEditRendererCUIEditor.Type type = clipboard ? WorldEditRendererCUIEditor.Type.CLIPBOARD : WorldEditRendererCUIEditor.Type.SELECTION;
        float width = type.getWidth(player).value;
        Material material = type.getMaterial(player);
        if (material == Material.BARRIER) {
            hide(player, clipboard, true);
            return;
        }
        BlockData block = material.createBlockData();

        BoxPair boxPair = boxes.computeIfAbsent(player, __ -> new BoxPair());
        CWireframe box = boxPair.get(clipboard);
        if (box == null) {
            box = new CWireframe(server);
            boxPair.set(clipboard, box);
        }
        box.setPos1And2(pos1.toLocation(player.getWorld()), pos2.toLocation(player.getWorld()));
        box.setWidth(width);
        box.setBlock(block);
    }

    @Override
    public void tick(Player player) {
        REntityServer server = servers.get(player);
        if (server != null) server.tick();
    }

    @Override
    public void hide(Player player, boolean clipboard, boolean hide) {
        BoxPair boxPair = boxes.get(player);
        if (boxPair == null) return;
        CWireframe box = boxPair.get(clipboard);
        if (box == null) return;
        box.hide(hide);
    }

    @Override
    public void remove(Player player) {
        BoxPair boxPair = boxes.remove(player);
        if (boxPair != null) boxPair.die();
        REntityServer server = servers.remove(player);
        if (server != null) server.close();
    }
}
