<template>
  <div class="elem-composition elem-composition-edit">
    <div
      v-if="data.showTitle"
      ref="ElemTitle"
      class="elem-title"
      :style="nameStyles"
    >
      {{ data.parent.topicName }}
    </div>
    <div class="elem-body" :style="bodyStyle">
      <div
        class="elem-composition-elements"
        @drop.prevent="dropInnerElement($event)"
        @dragover.prevent
        @dragleave.prevent
      >
        <elem-composition-element-edit
          v-for="element in data.elements"
          :key="element.id"
          :data="element"
          :transform-fit="rebuildGuides"
          @resize-over="elementResizeOver"
        ></elem-composition-element-edit>
        <!-- guide-lines -->
        <div class="element-guide-lines">
          <div
            class="guide-line guide-line-x"
            v-for="line in xLines"
            :key="`x-${line.top}`"
            :style="line"
          ></div>
          <div
            class="guide-line guide-line-y"
            v-for="line in yLines"
            :key="`y-${line.left}`"
            :style="line"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import ElemCompositionElementEdit from "./ElemCompositionElementEdit";
import guideLinesMixins from "../../mixins/guideLines";

export default {
  name: "elem-composition-edit",
  components: { ElemCompositionElementEdit },
  mixins: [guideLinesMixins],
  props: {
    data: {
      type: Object,
    },
  },
  data() {
    return {
      bodyStyle: {},
    };
  },
  computed: {
    ...mapState("card", ["curDragElement"]),
    nameStyles() {
      return {
        fontWeight: this.data.parent.nameFontWeight,
        fontSize: this.data.parent.nameFontSize,
      };
    },
  },
  watch: {
    "data.parent": {
      handler() {
        this.modifyBodyStyle();
      },
    },
  },
  mounted() {
    this.modifyBodyStyle();
  },
  methods: {
    ...mapMutations("card", ["setCurDragElement", "setCurElement"]),
    ...mapActions("card", ["rebuildPages", "modifyElementChild"]),
    modifyBodyStyle() {
      this.$nextTick(() => {
        let height = this.data.h;
        if (this.data.showTitle) {
          height = this.data.h - this.$refs.ElemTitle.clientHeight;
        }
        this.bodyStyle = {
          height: height + "px",
        };
      });
    },
    dropInnerElement(e) {
      let { offsetX: x, offsetY: y } = e;
      const { offsetLeft, offsetTop } = this.getOffsetInfo(
        e.target || e.srcElement
      );
      // 作文题的子元素中会新增container字段
      const curElement = {
        ...this.curDragElement,
        x: x + offsetLeft,
        y: y + offsetTop,
        container: {
          id: this.data.id,
          type: this.data.type,
        },
      };
      if (["LINES", "GRIDS"].includes(curElement.type)) {
        curElement.w = this.data.parent.w;
        curElement.x = 0;
      }
      this.elementResizeOver(curElement);
      this.setCurDragElement({});
      this.setCurElement(curElement);
    },
    getOffsetInfo(dom, endParentClass = "elem-composition-elements") {
      let parentNode = dom;
      let offsetTop = 0,
        offsetLeft = 0;
      while (!parentNode.className.includes(endParentClass)) {
        offsetTop += parentNode.offsetTop;
        offsetLeft += parentNode.offsetLeft;
        parentNode = parentNode.offsetParent;
      }
      return {
        offsetLeft,
        offsetTop,
      };
    },
    elementResizeOver(element) {
      this.clear();
      this.modifyElementChild(element);
      this.$nextTick(() => {
        this.rebuildPages();
      });
    },
    rebuildGuides(element, actionType) {
      return this.rebuild(this.data.elements, element, actionType);
    },
  },
};
</script>
