package me.km.networking;

import com.mojang.blaze3d.systems.RenderSystem;
import java.util.ArrayList;
import java.util.TreeMap;
import me.km.KajetansMod;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class PlayerDisplayGui extends AbstractGui {
    private static final ResourceLocation CUSTOM_ICONS = new ResourceLocation(KajetansMod.MODID, "textures/gui/icons.png");

    public final static PlayerDisplayGui INSTANCE = new PlayerDisplayGui(Minecraft.getInstance());

    private class IconStorage {
        private final Icon icon;
        private final int count;

        public IconStorage(int id, int count) {
            this.icon = Icon.getIcon(id);
            this.count = count;
        }

        public int getWidth() {
            return count * icon.getWidth() - count + 1;
        }

        public int getHeight() {
            return icon.getHeight();
        }
    }

    private class LineData {
        private ArrayList<String> list;
        private ArrayList<IconStorage> icons;

        public LineData(String s) {
            this.list = new ArrayList<>();
            this.icons = new ArrayList<>();

            int pos;
            int old = 0;
            while(true) {
                // icon format #X-Y- where X and Y are numbers
                pos = s.indexOf("#", old);
                if(pos == -1) {
                    list.add(s.substring(old));
                    break;
                }
                list.add(s.substring(old, pos));
                try {
                    int first = s.indexOf("-", pos);
                    int second = s.indexOf("-", first + 1);
                    icons.add(new IconStorage(Integer.parseInt(s.substring(pos + 1, first)), Integer.parseInt(s.substring(first + 1, second))));
                    old = second + 1;
                } catch(Exception ex) {
                    list.add("ERROR");
                    break;
                }
            }
        }

        public int getWidth() {
            return list.stream().mapToInt(s -> mc.fontRenderer.getStringWidth(s)).sum() + icons.stream().mapToInt(i -> i.getWidth()).sum();
        }

        public int getHeight() {
            return Math.max(mc.fontRenderer.FONT_HEIGHT, icons.stream().mapToInt(i -> i.getHeight()).max().orElse(0) + 1);
        }
    }

    private final TreeMap<Integer, LineData> strings;
    private final Minecraft mc;

    public PlayerDisplayGui(Minecraft mc) {
        this.mc = mc;
        this.strings = new TreeMap<>();
    }

    public void add(int i, String s) {
        strings.put(i, new LineData(s));
    }

    public void remove(int i) {
        strings.remove(i);
    }

    public void clear() {
        strings.clear();
    }

    public void paint() {
        if(strings.isEmpty()) {
            return;
        }
        int x;
        int y = 2;

        int width = 0;
        int height = 4;

        for(LineData data : strings.values()) {
            height += data.getHeight();
            width = Math.max(data.getWidth(), width);
        }

        fill(0, 0, width + 4, height, 1342177280);

        String s;
        for(LineData data : strings.values()) {
            x = 2;
            for(int i = 0; i < data.list.size(); i++) {
                s = data.list.get(i);
                mc.fontRenderer.drawString(s, x, y + 1, 0xFFFFFF);
                if(!s.isEmpty()) {
                    x += mc.fontRenderer.getStringWidth(s);
                } else {
                    x--;
                }
                if(i < data.icons.size()) {
                    x += paintIcons(data.icons.get(i), x, y);
                }
            }
            y += data.getHeight();
        }
    }

    private void bind(ResourceLocation res) {
        mc.getTextureManager().bindTexture(res);
    }

    private int paintIcons(IconStorage is, int x, int y) {
        RenderSystem.enableBlend();
        RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        bind(CUSTOM_ICONS);
        Icon icon = is.icon;
        int width = icon.getWidth();
        int height = icon.getHeight();
        int offX = icon.getOffsetX();
        int offY = icon.getOffsetY();
        for(int i = 0; i < is.count; i++) {
            blit(x + width * i - i, y, offX, offY, width, height);
        }
        RenderSystem.disableBlend();
        return is.getWidth();
    }
}
