<template>
<div class="edit-page-root">
    <div class="control-panel">
        <edit-action :description="translations.get('EditPage_Discard')" @action="$emit('closeAndDiscard')" icon="cancel" />
        <edit-action :description="translations.get('EditPage_InvertColour')" @action="invert = !invert" icon="invert_colors" />
        <edit-action :description="translations.get('EditPage_Rotate')" v-model="rotateMode" icon="crop_rotate" toggleMode />
        <edit-action :description="translations.get('EditPage_Save')" @action="closeAndSave" icon="save" />
    </div>

    <div class="image-panel">
        <div class="image-container" :style="{ transform: transformString }">
            <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-tl" @mousedown="allowRotation = true" draggable="false" />
            <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-tr" @mousedown="allowRotation = true" draggable="false" />
            <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-bl" @mousedown="allowRotation = true" draggable="false" />
            <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-br" @mousedown="allowRotation = true" draggable="false" />

            <table v-if="rotateMode" class="rotate-guide" :style="{ transform: transformStringInverted }">
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
                <tr><td><hr /></td></tr>
            </table>

            <img ref="image" :src="src" class="image" :style="{ filter: filterString }" />
        </div>
    </div>
</div>
</template>

<style lang="scss" scoped>
.edit-page-root {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    justify-items: center;
    background: rgba(0, 0, 0, 0.8);
}

.image-panel {
    position: relative;
    height: 100%;
    width: 100%;

    display: grid;
    align-items: center;
    justify-items: center;
}

.image {
    max-width: 70vw;
    max-height: 70vh;
}

.image-container {
    position: relative;
    margin: auto;
    padding: 1.5em;
    user-select: none;

    .rotate-handle {
        height: 2em;
        position: absolute;
        z-index: 5;

        // Generated with https://codepen.io/sosuke/pen/Pjoqqp using var(--primary-bg-color)
        // filter: invert(16%) sepia(100%) saturate(3091%) hue-rotate(347deg) brightness(75%) contrast(90%);
    }

    .rotate-tl {
        top: 0;
        left: 0;
    }

    .rotate-tr {
        top: 0;
        right: 0;
        transform: rotate(90deg);
    }

    .rotate-bl {
        bottom: 0;
        left: 0;
        transform: rotate(270deg);
    }

    .rotate-br {
        bottom: 0;
        right: 0;
        transform: rotate(180deg);
    }
}

.rotate-guide {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    z-index: 3;

    tr {
        td {
            vertical-align: center;
        }

        hr {
            background-color: rgba(var(--bg-color-raw), 0.5);
            height: 2px;
        }
    }
}

.control-panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;

    padding: 0.5em;
    gap: 1em;
    height: 100%;

    // background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.2) 10%);
}

.edit-action {
    display: flex;
    position: relative;

    .infotab {
        position: absolute;
        height: 70%;
        top: 15%;
        left: 120%;

        display: flex;
        align-items: center;
        justify-content: center;
        visibility: hidden;

        width: 0;
        min-width: 0;
        padding: 0 0.2em;

        white-space: nowrap;
        transition-duration: var(--transition-duration);
    }

    .btn-fab:hover + .infotab {
        visibility: visible;
        min-width: 10em;
    }
}
</style>

<script>
import { mapState } from "vuex";
import EditAction from "./EditAction.vue"

export default {
    name: "EditPage",
    components: {
        EditAction
    },
    props: {
        imageBuffer: ArrayBuffer,
        src: String
    },
    emits: [ "closeAndDiscard", "closeAndSave" ],
    data() {
        return {
            invert: false,
            rotation: 0,
            rotateMode: false,
            allowRotation: false
        }
    },
    computed: {
        ...mapState({
            translations: state => state.translations,
            filterString() {
                let filters = "";

                if (this.invert) {
                    filters += "invert(1) ";
                }

                return filters;
            },
            transformString() {
                return `rotate(${this.rotation}deg)`;
            },
            transformStringInverted() {
                return `rotate(-${this.rotation}deg)`;
            }
        })
    },
    methods: {
        async closeAndSave() {
            const Jimp = await import("jimp/es");

            const buffer = Buffer.from(this.imageBuffer);
            const that = this;

            const modifiedBuffer = await Jimp.read(buffer)
                .then(async image => {
                    if (that.invert) {
                        image.invert();
                    }

                    if (that.rotation !== 0) {
                        image.rotate(-that.rotation);
                    }

                    return await image.getBufferAsync(Jimp.MIME_PNG);
                });

            this.$emit("closeAndSave", modifiedBuffer, Jimp.MIME_PNG);
        },

        onRotateHandleMouseDown(point) {
            console.log(point);
            this.rotatePoint = point;
        },
        /**
         * @param {MouseEvent} e The mouse movement event.
         */
        onDocumentMouseMove(e) {
            if (!this.allowRotation) {
                return;
            }

            const imageRectangle = this.$refs.image.getBoundingClientRect();
            const imageCenterX = (imageRectangle.width / 2) + imageRectangle.left;
            const imageCenterY = (imageRectangle.height / 2) + imageRectangle.top;

            if (e.clientX > imageCenterX) {
                this.rotation += e.movementY / 8;
            }
            else {
                this.rotation -= e.movementY / 8;
            }

            if (e.clientY > imageCenterY) {
                this.rotation -= e.movementX / 8;
            }
            else {
                this.rotation += e.movementX / 8;
            }

            if (this.rotation < 0) {
                this.rotation = 360 + this.rotation;
            }
            else if (this.rotation > 360) {
                this.rotation -= 360;
            }
        },
        onDocumentMouseUp() {
            this.allowRotation = false;
        }
    },
    beforeMount() {
        document.addEventListener("mousemove", this.onDocumentMouseMove);
        document.addEventListener("mouseup", this.onDocumentMouseUp);
    },
    beforeUnmount() {
        document.removeEventListener("mousemove", this.onDocumentMouseMove);
        document.removeEventListener("mouseup", this.onDocumentMouseUp);
    }
}
</script>
