<script setup lang="ts">
import * as d3 from "d3"
import { onMounted } from "vue"

import { IMAGE_URL } from '../../constants'

const props = defineProps(['files'])

onMounted(async () => {
    const files = props.files
    // const width = 1920
    // const height = 1080
    const width = window.innerWidth
    const height = window.innerHeight

    const svg = d3.select('#gallery').append("svg")
        .attr("viewBox", [0, 0, width, height])
        .attr("stroke-width", 2);

    var defs = svg.append('svg:defs');

    files.forEach((element: any, i: number) => {
        // const src = element[1].default
        const src = `${IMAGE_URL}/${element.file}`
        defs.append("svg:pattern")
            .attr("id", `img${i}`)
            .attr("width", width)
            .attr("height", height)
            .attr("patternUnits", "userSpaceOnUse")
            .attr("preserveAspectRatio", "none")
            .append("svg:image")
            .attr("xlink:href", src)
            .attr("width", width)
            .attr("height", height)
            .attr("x", 0)
            .attr("y", 0);
    });
    const range = files.length + 2
    const circles = d3.range(range).map(() => ({
        x: Math.random() * width,
        y: Math.random() * height,
    }));

    let voronoi = d3.Delaunay
        .from(circles, d => d.x, d => d.y)
        .voronoi([0, 0, width, height]);

    const circle = svg.append("g")
        .selectAll("circle")
        .data(circles)
        .join("circle")
        .attr("cx", d => d.x)
        .attr("cy", d => d.y)
        .attr("r", 0)
        .attr("fill", 'none');

    const mesh = svg.append("path")
        .attr("fill", "none")
        .attr("stroke", "#ccc")
        .attr("stroke-width", 0)
        .attr("d", voronoi.render());

    const cell = svg.append("g")
        .attr("fill", "none")
        .attr("pointer-events", "all")
        .selectAll("path")
        .data(circles)
        .join("path")
        .attr("d", (d, i) => voronoi.renderCell(i))
        .attr('fill', (d, i) => i < (range - 2) ? `url(#img${i})` : 'none')
        .call(d3.drag()
            .on("start", (event, d) => circle.filter(p => p === d).raise().attr("stroke", "black"))
            .on("drag", (event, d: any) => (d.x = event.x, d.y = event.y))
            .on("end", (event, d) => circle.filter(p => p === d).attr("stroke", null))
            .on("start.update drag.update end.update", update) as any)

    function update() {
        voronoi = d3.Delaunay.from(circles, d => d.x, d => d.y).voronoi([0, 0, width, height]);
        circle.attr("cx", d => d.x).attr("cy", d => d.y);
        cell.attr("d", (d, i) => voronoi.renderCell(i));
        mesh.attr("d", voronoi.render());
    }

    if (document.querySelector('.pin')) {
        const rect = (document.querySelector('.pin') as HTMLElement).getBoundingClientRect()
        circles[circles.length - 1] = { x: rect.x + rect.width, y: rect.y + rect.height }
        circles[circles.length - 2] = { x: rect.x, y: rect.y }
        update()
    }
})
</script>
<template>
    <div id="gallery"></div>
</template>