
<style lang="less" >
@import "./index.less";
</style>
<template>
  <div class="comps-view" :style="wrapperStyle" ref="compsView" @mousedown="onMouseDown">
    <template v-if="showPlaceholde">
      <!-- 组件操作面板 -->
      <popover :value="showComponentPanel" trigger="click" placement="top-start" style="display: block;">
        <grid
          square
          clickable
          :border="false"
          column-num="3"
          style="width: 240px;"
        >
          <grid-item
            text="图片"
            icon="photo-o"
            @click="addComponent('IMAGE')"
          />
          <grid-item
            text="文本"
            icon="font-o"
            @click="addComponent('TEXT')"
          />
          <grid-item
            text="热区"
            icon="hot-o"
            @click="addComponent('HOT_AREA')"
          />
        </grid>
      </popover>
      <template v-if="data.compsDetail.compList.length > 0">
        <vue-drag-resize v-for="(comp, index) in data.compsDetail.compList"
                         :key="index" :is-active="comp.active"
                         :h="getCompsHeight(comp.height)"
                         :w="getCompsWidth(comp.width)"
                         :minh="10"
                         :minw="10"
                         :x="comp.x"
                         :y="comp.y"
                         :z="comp.zIndex"
                         @resizing="onResizing"
                         @dragging="onDragging"
                         @clicked="onClicked(index)"
                         @activated="onActivated(index)"
                         @deactivated="onDeactivated(index)"
                         class="comp-operation"
        >
          <div class="operation">
            <i class="item">
              <icon name="clear" color="#b7b7b7" :size="20" @click="onDelete(index)" class="delete" />
            </i>
          </div>
          <!-- IMAGE 图片组件-->
          <w-page-image
            v-if="comp.compsType === 'IMAGE'"
            :show-placeholde="showPlaceholde"
            :data="comp"
          />
          <!-- TEXT 文本组件 -->
          <w-page-text
            v-else-if="comp.compsType === 'TEXT'"
            :show-placeholde="showPlaceholde"
            :data="comp"
          />
          <!-- TEXT 文本组件 -->
          <hot-area
            v-else-if="comp.compsType === 'HOT_AREA'"
            :show-placeholde="showPlaceholde"
            :data="comp"
          />
        </vue-drag-resize>
      </template>
      <template v-else-if="data.bgPicKey === ''">
        <div class="placeholde">
          点击增加组件
        </div>
      </template>
    </template>
    <template v-else>
      <template v-for="(comp, index) in data.compsDetail.compList">
        <!-- IMAGE 图片组件-->
        <w-page-image
          :key="index"
          v-if="comp.compsType === 'IMAGE'"
          :show-placeholde="showPlaceholde"
          :data="comp"
        />
        <!-- TEXT 文本组件 -->
        <w-page-text
          :key="index"
          v-else-if="comp.compsType === 'TEXT'"
          :show-placeholde="showPlaceholde"
          :data="comp"
        />
        <!-- TEXT 文本组件 -->
        <hot-area
          :key="index"
          v-else-if="comp.compsType === 'HOT_AREA'"
          :show-placeholde="showPlaceholde"
          :data="comp"
        />
      </template>
    </template>
  </div>
</template>

<script>
import VueDragResize from 'vue-drag-resize';
import CompsMixins from '../comps-mixins';
import WPageImage from '../wpage-image';
import Popover from '../../../popover';
import Grid from '../../../grid';
import GridItem from '../../../grid-item';
import pageCompsFactory from '../../ts/wpage-comps-factory';
import WPageText from '../wpage-text';
import Icon from '../../../icon';
import { isNumber } from '../../../utils/validate/number';
import HotArea from '../hot-area';

export default {
  name: 'compsview',
  components: {
    VueDragResize,
    WPageImage,
    Popover,
    Grid,
    GridItem,
    WPageText,
    Icon,
    HotArea
  },
  mixins: [CompsMixins],
  props: {
    /**
     * 显示组件面板
     */
    showComponentPanel: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 当前选中的索引
      selectedIndex: -1,
      // 最大的高度
      maxHeight: this.data.height,
      showPopover: true,
      viewWidth: 0,
      viewHeight: 0
    };
  },
  computed: {
    wrapperStyle() {
      if (!this.data) {
        return '';
      }
      const style = [];
      if (this.data.compsDetail.layout) {
        const layout = this.data.compsDetail.layout.toLowerCase();
        /**
          * 布局  @absolute:1:绝对布局  @relative:2:相对布局  @liner:3:线性 @grid:4:网格布局
        */
        if (layout === 'absolute') {
          style.push('position:absolute');
        } else if (layout === 'relative') {
          style.push('position:relative');
        }
      } else {
        style.push('position:relative');
      }
      style.push(this.style);
      return style.join(';');
    }
  },
  watch: {
    data() {
      if (this.data && this.compList && this.compList.length > 0) {
        this.data.compList.forEach(item => {
          item.active = false;
        });
      }
    }
  },
  mounted() {
    if (this.showPlaceholde) {
      // this.viewWidth = this.$refs.compsView.clientWidth;
      // this.viewHeight = this.$refs.compsView.clientHeight;

      // window.addEventListener('resize', () => {
      //   this.viewWidth = this.$refs.compsView.clientWidth;
      //   this.viewHeight = this.$refs.compsView.clientHeight;
      // });
    }
  },
  methods: {

    /**
     * 获得组件的高度 (如果是百分比会计算出实际值)
     */
    getCompsHeight(height) {
      // 如果是
      if (height instanceof Number) {
        return height;
      }
      if (isNumber(height)) {
        // eslint-disable-next-line radix
        return parseInt(height);
      }
      const heightRate = parseFloat(height) / 100;
      // 获得当前父div的高度
      const compsViewtHeight = this.$refs.compsView.clientHeight;
      return compsViewtHeight * heightRate;
    },
    /**
     * 组件宽度 (如果是百分比会计算出实际值)
     */
    getCompsWidth(width) {
      // 如果是
      if (width instanceof Number) {
        return width;
      }
      if (isNumber(width)) {
        // eslint-disable-next-line radix
        return parseInt(width);
      } // 当是百分比时，如30%
      const widthRate = parseFloat(width) / 100;
      // 获得当前父div的宽度
      const compsViewtWidth = this.$refs.compsView.clientWidth;
      return compsViewtWidth * widthRate;
    },
    /**
     * 点击组件外部
     */
    onMouseDown() {
      // 取消之前的选中
      if (this.selectedIndex >= 0) {
        this.data.compsDetail.compList[this.selectedIndex].active = false;
      }
      this.selectedIndex = -1;
      // 强制刷新（数组，有时增加页面不重新渲染）
      this.$forceUpdate();
      /**
       * 当前点击的子组件
       */
      this.$emit('on-click', this.index, this.selectedIndex);
    },

    onActivated(index) {
      // console.log('activateEv:', index);
      // if (!this.showPlaceholde) {
      //   return;
      // }
      // // 选中
      // if (index >= 0) {
      //   this.data.compsDetail.compList[index].active = true;
      // }
      // this.selectedIndex = index;
      // /**
      //  * 当前点击的子组件
      //  */
      // this.$emit('on-click', this.index, index);
      //   // 强制刷新（数组，有时增加页面不重新渲染）
      // this.$forceUpdate();
    },
    /**
     *  失效
     */
    onDeactivated(index) {
      // console.log('deactivateEv:', index);
      // if (!this.showPlaceholde) {
      //   return;
      // }
      // // 取消之前的选中
      // if (index >= 0) {
      //   this.data.compsDetail.compList[index].active = false;
      // }
      // // 强制刷新（数组，有时增加页面不重新渲染）
      // this.$forceUpdate();
    },
    /**
     * 点击
     */
    onClicked(index) {
      if (!this.showPlaceholde) {
        return;
      }
      // 取消之前的选中
      if (this.selectedIndex >= 0) {
        this.data.compsDetail.compList[this.selectedIndex].active = false;
      }
      // 当前选中的索引
      this.selectedIndex = index;
      if (this.selectedIndex >= 0) {
        this.data.compsDetail.compList[this.selectedIndex].active = true;
      }
      // 强制刷新（数组，有时增加页面不重新渲染）
      this.$forceUpdate();
      /**
       * 当前点击的子组件
       */
      this.$emit('on-click', this.index, index);
    },
    /**
     * 调整大小
     */
    onResizing(newRect) {
      if (this.selectedIndex >= 0) {
        this.data.compsDetail.compList[this.selectedIndex].width = newRect.width.toString();
        this.data.compsDetail.compList[this.selectedIndex].height = newRect.height.toString();
      }
    },
    /**
     * 调整位置
     */
    onDragging(newRect) {
      if (this.selectedIndex >= 0) {
        this.data.compsDetail.compList[this.selectedIndex].x = newRect.left;
        this.data.compsDetail.compList[this.selectedIndex].y = newRect.top;
        // 自动增加高度
        this.resetViewHeight(newRect);
      }
    },
    /**
     * 重新设置组件视图的高度
     */
    resetViewHeight(newRect) {
      if (!newRect) {
        return;
      }
      const newHeight = newRect.top + newRect.height;

      if (newHeight + 10 > this.maxHeight) {
        this.maxHeight = newHeight;
        this.data.height = this.maxHeight + 10;
        // 强制刷新（数组，有时增加页面不重新渲染）
        // this.$forceUpdate();
      }
    },
    /**
     * 添加組件
     */
    addComponent(compType) {
      let model = {};
      if (compType === 'IMAGE') { // 图片
        model = pageCompsFactory.createCompsImage();
      } else if (compType === 'HOT_AREA') { // 导航
        model = pageCompsFactory.createHotArea();
      } else if (compType === 'TEXT') { // 标题
        model = pageCompsFactory.createText();
      }
      this.addComponentWithModel(model);
      return model;
    },
    /**
     * 根据wpage-comps-factory工厂生成的model添加
     */
    addComponentWithModel(model) {
      if (!this.data || !this.data.compsDetail || !model) {
        return;
      }
      this.data.compsDetail.compList.push(model);
      // 添加后选中
      setTimeout(() => {
        this.onClicked(this.data.compsDetail.compList.length - 1);
      }, 50);
    },
    /**
     * 删除组件
     */
    onDelete(index) {
      this.selectedIndex = -1;
      this.data.compsDetail.compList.splice(index, 1);
      // 删除on-delete(父组件索引，当前删除的索引)
      this.$emit('on-delete', this.index, index);
    }
  }
};
</script>
