<script>
import Selecto from "vue3-selecto";
import Moveable from "vue3-moveable";
import { diff } from "@egjs/children-differ";
import { ref } from "vue";

export default {
    components: { Moveable, Selecto },
    setup() {
        const targets = ref([]);
        const moveableRef = ref(null);
        const selectoRef = ref(null);
        const cubes = [];
        for (let i = 0; i < 30; ++i) {
            cubes.push(i);
        }
        const onClickGroup = e => {
            selectoRef.value.clickTarget(e.inputEvent, e.inputTarget);
        };
        const onDrag = e => {
            e.target.style.transform = e.transform;
        };
        const onDragGroup = e => {
            e.events.forEach(ev => {
                ev.target.style.transform = ev.transform;
            });
        };
        const onClick = e => {
            if (e.isDouble) {
                const inputTarget = e.inputTarget;
                const selectableElements = selectoRef.value.getSelectableElements();
                if (selectableElements.includes(inputTarget)) {
                    selectoRef.value.setSelectedTargets([inputTarget]);
                    targets.value = [inputTarget];
                }
            }
        };
        const onDragStart = e => {
            const moveable = moveableRef.value;
            const target = e.inputEvent.target;
            if (moveable.isMoveableElement(target)
                || targets.value.some(t => t === target || t.contains(target))
            ) {
                e.stop();
            }
        };
        const onSelectEnd = e => {
            const moveable = moveableRef.value;
            let selected = e.selected;
            selected = selected.filter(target => {
                return selected.every(target2 => {
                    return target === target2 || !target2.contains(target);
                });
            });
            const result = diff(e.startSelected, selected);
            e.currentTarget.setSelectedTargets(selected);
            if (!result.added.length && !result.removed.length) {
                return;
            }
            if (e.isDragStartEnd) {
                e.inputEvent.preventDefault();
                moveable.waitToChangeTarget().then(() => {
                    moveable.dragStart(e.inputEvent);
                });
            }
            targets.value = selected;
        };
        return {
            moveableRef,
            targets,
            onClickGroup,
            onDrag,
            onDragGroup,
            onClick,
            selectoRef,
            window,
            onDragStart,
            onSelectEnd,
            cubes
        };
    }
};
</script>
<template>
    <div class="root">
        <div class="container">
            <Moveable
                ref="moveableRef"
                :draggable="true"
                :target="targets"
                @clickGroup="onClickGroup"
                @drag="onDrag"
                @dragGroup="onDragGroup"
                @click="onClick"
            ></Moveable>
            <Selecto
                ref="selectoRef"
                :dragContainer="window"
                :selectableTargets="['.selecto-area .cube']"
                :hitRate="0"
                :selectByClick="true"
                :selectFromInside="false"
                :toggleContinueSelect="['shift']"
                :ratio="0"
                @dragStart="onDragStart"
                @selectEnd="onSelectEnd"
            ></Selecto>
            <div class="elements selecto-area">{{cubes.map(i => {
                    if (i === 2) {
                        return <div class="cube" key={i} style="width: 100px;height: 50px;">
                                            {i}
                                            <div class="cube" key={i}>{i}</div>
                                        </div>;
                    }
                    return <div class="cube" key={i}>{i}</div>;
                })}}
            </div>
            <div class="empty elements"></div>
        </div>
    </div>
</template>