<template>
  <div class="elem-composition elem-composition-edit">
    <div class="elem-title" v-if="data.showTitle" ref="ElemTitle">
      {{ 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"])
  },
  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 { layerX: x, layerY: y } = e;
      const { offsetLeft, offsetTop } = this.getOffsetInfo(e.target);
      // 作文题的子元素中会新增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, endParent = "elem-composition-elements") {
      let parentNode = dom;
      let offsetTop = 0,
        offsetLeft = 0;
      while (!parentNode.className.includes(endParent)) {
        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>
