<template>
  <g @mousedown="handleMousedown" :id="id">
    <rect v-bind="outlineRectAttr" />
    <rect v-bind="attr" />
    <circle
      v-for="i in pointsAttr"
      v-bind="i"
      :key="i.id"
      @mousedown="($event) => startLine($event, i)"
    ></circle>
  </g>
</template>

<script setup>
import {
  defineProps,
  ref,
  watch,
  defineExpose,
  defineEmits,
  computed,
} from "vue";
import { sticky } from "../utils/index";
const props = defineProps(["pos", "size", "mousePos", "id", "draggingId"]);
const boxPos = ref(props.pos);
const boxSize = ref(props.size);
const innerPos = ref({ x: 0, y: 0 });
const isDraging = computed(() => props.id === props.draggingId);
const emits = defineEmits(["startDrag", "startLine", "updatePos"]);

const attr = computed(() => {
  return {
    x: boxPos.value.x,
    y: boxPos.value.y,
    width: boxSize.value.width,
    height: boxSize.value.height,
    fill: "rgba(255,255,255,1)",
    stroke: "#666",
    rx: "15",
  };
});

const outlineRectAttr = computed(() => {
  const space = 8;
  return {
    x: boxPos.value.x - space,
    y: boxPos.value.y - space,
    width: boxSize.value.width + space * 2,
    height: boxSize.value.height + space * 2,
    fill: "rgba(255,255,255,0)",
    "stroke-dasharray": "3 4",
    stroke: "#000",
    rx: "18",
  };
});

const pointsAttr = computed(() => [
  {
    id: `${props.id}-top`,
    cx: boxPos.value.x + boxSize.value.width / 2,
    cy: boxPos.value.y,
    r: 4,
    stroke: "#000",
    fill: "rgba(255,255,255,1)",
  },
  {
    id: `${props.id}-right`,
    cx: boxPos.value.x + boxSize.value.width,
    cy: boxPos.value.y + boxSize.value.height / 2,
    r: 4,
    stroke: "#000",
    fill: "rgba(255,255,255,1)",
  },
  {
    id: `${props.id}-bottom`,
    cx: boxPos.value.x + boxSize.value.width / 2,
    cy: boxPos.value.y + boxSize.value.height,
    r: 4,
    stroke: "#000",
    fill: "rgba(255,255,255,1)",
  },
  {
    id: `${props.id}-left`,
    cx: boxPos.value.x,
    cy: boxPos.value.y + boxSize.value.height / 2,
    r: 4,
    stroke: "#000",
    fill: "rgba(255,255,255,1)",
  },
]);

function handleMousedown(e) {
  emits("startDrag", {
    id: props.id,
    event: e,
  });
  innerPos.value = {
    x: e.offsetX - boxPos.value.x,
    y: e.offsetY - boxPos.value.y,
  };
}

function startLine(e, point) {
  e.stopPropagation();
  emits("startLine", {
    id: props.id,
    point: point,
  });
}

function setPos(pos) {
  boxPos.value = {
    x: sticky(pos.x - innerPos.value.x),
    y: sticky(pos.y - innerPos.value.y),
  };
  emits("updatePos", {
    id: props.id,
    pos: boxPos.value,
  });
}

watch(
  () => props.mousePos,
  (pos) => {
    if (isDraging.value) {
      setPos(pos);
    }
  }
);
</script>

<style lang="less" scoped>
circle {
  cursor: pointer;
}
</style>
