package com.thebrokenrail.gestus.emote;

import com.thebrokenrail.gestus.emote.exception.EmoteSyntaxException;
import net.minecraft.util.math.EulerAngle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Emote {
    public final EmoteFrame[] frames;

    public Emote(String[] lines) throws EmoteSyntaxException {
        List<EmoteFrame> list = new ArrayList<>();

        EmotePart[] parts = EmotePart.values();

        for (int lineNum = 0; lineNum < lines.length; lineNum++) {
            String line = lines[lineNum].trim();

            if (line.equals("maintain")) {
                if (list.size() > 0) {
                    list.add(list.get(list.size() - 1));
                } else {
                    throw new EmoteSyntaxException(lineNum, "No Previous Frame");
                }
            } else if (!line.startsWith("#")) {
                Map<EmotePart, EulerAngle> map = new HashMap<>();

                String[] lineParts = line.split(" ");

                for (int i = 0; i < lineParts.length; i++) {
                    String linePart = lineParts[i];

                    boolean found = false;
                    EmotePart selectedPart = null;
                    for (EmotePart part : parts) {
                        if (linePart.equals(part.getName())) {
                            selectedPart = part;
                            found = true;
                            break;
                        }
                    }

                    if (!found) {
                        throw new EmoteSyntaxException(lineNum, "Invalid Emote Part: " + linePart);
                    } else if (map.containsKey(selectedPart)) {
                        throw new EmoteSyntaxException(lineNum, "Duplicate Emote Part: " + linePart);
                    }

                    try {
                        String yawStr = lineParts[++i];
                        String pitchStr = lineParts[++i];
                        String rollStr = lineParts[++i];

                        float yaw = Float.parseFloat(yawStr);
                        float pitch = Float.parseFloat(pitchStr);
                        float roll = Float.parseFloat(rollStr);

                        map.put(selectedPart, new EulerAngle(pitch, yaw, roll));
                    } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
                        throw new EmoteSyntaxException(lineNum, "No Rotation Specified: " + selectedPart.getName());
                    }
                }

                list.add(new EmoteFrame(map));
            }
        }

        frames = list.toArray(new EmoteFrame[0]);
    }
}
