package eu.crushedpixel.replaymod.gui.elements;

import eu.crushedpixel.replaymod.gui.GuiEditKeyframe;
import eu.crushedpixel.replaymod.holders.Keyframe;
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import net.minecraft.client.Minecraft;

public class GuiKeyframeTimeline extends GuiTimeline {
    private static final int KEYFRAME_PLACE_X = 74;
    private static final int KEYFRAME_PLACE_Y = 20;
    private static final int KEYFRAME_TIME_X = 74;
    private static final int KEYFRAME_TIME_Y = 25;

    private Keyframe clickedKeyFrame;
    private long clickTime;
    private boolean dragging;

    public GuiKeyframeTimeline(int positionX, int positionY, int width) {
        super(positionX, positionY, width);
        showMarkers = true;
    }

    public void mouseClicked(Minecraft mc, int mouseX, int mouseY) {
        long time = getTimeAt(mouseX, mouseY);
        if (time == -1) {
            return;
        }

        int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));

        Keyframe closest;
        if (mouseY >= positionY + BORDER_TOP + 5) {
            closest = ReplayHandler.getClosestTimeKeyframeForRealTime((int) time, tolerance);
        } else if (mouseY >= positionY + BORDER_TOP) {
            closest = ReplayHandler.getClosestPlaceKeyframeForRealTime((int) time, tolerance);
        } else {
            closest = null;
        }

        ReplayHandler.selectKeyframe(closest); //can be null, deselects keyframe

        // If we clicked on a key frame, then continue monitoring the mouse for movements
        long currentTime = System.currentTimeMillis();
        if (closest != null) {
            if (currentTime - clickTime < 500) { // if double clicked then open GUI instead
                mc.displayGuiScreen(new GuiEditKeyframe(closest));
                this.clickedKeyFrame = null;
            } else {
                this.clickedKeyFrame = closest;
                this.dragging = false;
            }
        } else { // If we didn't then just update the cursor
            ReplayHandler.setRealTimelineCursor((int) time);
            this.dragging = true;
        }
        this.clickTime = currentTime;
    }

    public void mouseDrag(int mouseX, int mouseY) {
        long time = getTimeAt(mouseX, mouseY);
        if (time != -1) {
            if (clickedKeyFrame != null) {
                int tolerance = (int) (2 * Math.round(zoom * timelineLength / width));

                if (dragging || Math.abs(clickedKeyFrame.getRealTimestamp() - time) > tolerance) {
                    clickedKeyFrame.setRealTimestamp((int) time);
                    ReplayHandler.sortKeyframes();
                    dragging = true;
                }
            } else if (dragging) {
                ReplayHandler.setRealTimelineCursor((int) time);
            }
        }
    }

    public void mouseRelease(int mouseX, int mouseY) {
        mouseDrag(mouseX, mouseY);
        clickedKeyFrame = null;
        dragging = false;
    }

    @Override
    public void draw(Minecraft mc, int mouseX, int mouseY) {
        super.draw(mc, mouseX, mouseY);

        int bodyWidth = width - BORDER_LEFT - BORDER_RIGHT;

        long leftTime = Math.round(timeStart * timelineLength);
        long rightTime = Math.round((timeStart + zoom) * timelineLength);

        double segmentLength = timelineLength * zoom;

        //Draw Keyframe logos
        for(Keyframe kf : ReplayHandler.getKeyframes()) {
            if (kf.getRealTimestamp() <= rightTime && kf.getRealTimestamp() >= leftTime) {
                int textureX;
                int textureY;
                int y = positionY;
                if (kf instanceof PositionKeyframe) {
                    textureX = KEYFRAME_PLACE_X;
                    textureY = KEYFRAME_PLACE_Y;
                    y += 0;
                } else if (kf instanceof TimeKeyframe) {
                    textureX = KEYFRAME_TIME_X;
                    textureY = KEYFRAME_TIME_Y;
                    y += 5;
                } else {
                    throw new UnsupportedOperationException("Unknown keyframe type: " + kf.getClass());
                }

                if (ReplayHandler.isSelected(kf)) {
                    textureX += 5;
                }

                long positionInSegment = kf.getRealTimestamp() - leftTime;
                double fractionOfSegment = positionInSegment / segmentLength;
                int x = (int) (positionX + BORDER_LEFT + fractionOfSegment * bodyWidth);

                rect(x - 2, y + BORDER_TOP, textureX, textureY, 5, 5);
            }
        }
    }
}
