<template>
  <div id="ui-prop">
    <div class="normal-data" style="display: flex;flex-direction: row;align-items: center;min-height: 30px;margin: 0;">
      <div @mousedown="onPropNameMouseDown" class="key"
           @click="onClickFold"
           :style="{'cursor':isArrayOrObject()?'pointer':''}"
      >
        <i class="data-arrow"
           v-if="arrow"
           :class="fold?'el-icon-caret-right':'el-icon-caret-bottom'"
           :style="{'visibility':isArrayOrObject()?'visible':'hidden','margin-left':indent*10+'px'}">
        </i>
        <div class="text" ref="propText">
          <el-popover placement="top" trigger="hover" :disabled="!isShowTooltip()">
            <div>{{ name }}</div>
            <span slot="reference">{{ name }}</span>
          </el-popover>
        </div>

      </div>
      <div class="value">
        <div v-if="isInvalid()" class="invalid">
          {{ value.data }}
        </div>
        <el-input v-if="isString()" v-model="value.data"
                  :disabled="value.readonly"
                  @change="onChangeValue">
        </el-input>
        <el-input v-if="isText()"
                  type="textarea"
                  :autosize="{minRows:3,maxRows:5}"
                  placeholder="请输入内容"
                  :disabled="value.readonly"
                  @change="onChangeValue"
                  v-model="value.data">
        </el-input>
        <el-input-number v-if="isNumber()"
                         style="width: 100%;text-align: left"
                         v-model="value.data"
                         :step="step"
                         :disabled="value.readonly"
                         @change="onChangeValue"
                         controls-position="right"
        ></el-input-number>

        <div v-if="isVec2()||isVec3()" class="vec">
          <ui-prop v-for="(vec, index) in value.data"
                   :key="index"
                   :arrow="false"
                   :value="vec.value"
                   :name="vec.name">

          </ui-prop>
        </div>
        <el-select v-model="value.data"
                   :disabled="value.readonly"
                   v-if="isEnum()" style="width: 100%;"
                   @change="onChangeValue">
          <el-option v-for="(opt, index) in value.values"
                     :key="index"
                     :label="opt.name"
                     :value="opt.value">
          </el-option>
        </el-select>
        <el-checkbox v-model="value.data"
                     v-if="isBool()"
                     :disabled="value.readonly"
                     @change="onChangeValue">
        </el-checkbox>
        <div class="color" v-if="isColor()">
          <el-color-picker style="position: absolute;"
                           :disabled="value.readonly"
                           v-model="value.data" @change="onChangeValue">
          </el-color-picker>
          <div class="hex" :style="{color:colorReverse(value.data)}">{{ value.data }}</div>
        </div>
        <!--      <div v-if="isArrayOrObject()" class="array-object">-->
        <!--        <div class="text">-->
        <!--        </div>-->
        <!--        <el-button @click="onShowValueInConsole">log</el-button>-->
        <!--      </div>-->
        <div v-if="isImage()" class="image-property">
          <el-popover v-if="isImage()" placement="top" trigger="hover">
            <div
                style="width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;justify-content: center;">
              <img :src="value.data" alt="图片" style="max-width: 100px;max-height: 100px;object-fit: contain;">
            </div>
            <img :src="value.data" slot="reference" style="height: 36px;" alt="图片">
          </el-popover>
          <div style="flex:1;display: flex; flex-direction: row-reverse;">
            <el-button @click="onShowValueInConsole">log</el-button>
          </div>
        </div>
        <div v-if="isEngine()" class="engine">
          <div class="head">
            <i class="icon" :class="getEngineTypeIcon()"></i>
            <div class="type">{{ value.engineType }}</div>
          </div>
          <div class="name">{{ value.engineName }}</div>
          <el-button @click="onPlaceInTree" type="primary" icon="el-icon-place"></el-button>
        </div>
        <div v-if="isObject()&&fold" class="objectDesc">
          {{ value.data }}
        </div>
        <div v-if="isArray()" class="array">
          Array({{ value.data.length }})
        </div>
        <div class="slot" v-if="false">
          <slot></slot>
        </div>
      </div>
    </div>
    <div v-if="isArrayOrObject()">
      <div v-show="!fold&&subData" style="display: flex;flex-direction: column;">
        <ui-prop v-for="(arr,index) in subData"
                 :key="index"
                 :indent="indent+1"
                 :value="arr.value"
                 :name="getName(isArray(),arr)"
        >
        </ui-prop>
      </div>
    </div>
  </div>
</template>

<script lang="ts">

import Vue from "vue"
import {Component, Prop, Watch} from "vue-property-decorator"
import {DataType, EngineData, Info, Property} from "../data"
import {connectBackground} from "@/devtools/connectBackground";
import {Msg} from "@/core/types";
import Bus, {BusMsg} from "../bus"

@Component({
  name: "UiProp",
  components: {}
})
export default class UiProp extends Vue {
  @Prop({default: ""})
  name: string | undefined;

  @Prop({default: 0})
  indent!: number;

  @Prop({default: true})
  arrow!: boolean;

  @Prop()
  value!: Info;

  @Watch("value")
  watchValue() {
    this.fold = true;
    if (this.isArray()) {
      this.subData = this.value.data;
    } else {
      this.subData = null;
    }
  }

  isInvalid() {
    return this.value && (this.value.type === DataType.Invalid);
  }

  isString() {
    return this.value && (this.value.type === DataType.String);
  }

  isText() {
    return this.value && (this.value.type === DataType.Text);
  }

  isNumber() {
    return this.value && (this.value.type === DataType.Number);
  }

  isVec2() {
    return this.value && (this.value.type === DataType.Vec2);
  }

  isVec3() {
    return this.value && (this.value.type === DataType.Vec3);
  }

  isEnum() {
    return this.value && (this.value.type === DataType.Enum);
  }

  isBool() {
    return this.value && (this.value.type === DataType.Bool);
  }

  isColor() {
    return this.value && (this.value.type === DataType.Color);
  }

  isArrayOrObject() {
    return this.value && (this.value.type === DataType.Array || this.value.type === DataType.Object)
  }

  isObject() {
    return this.value && (this.value.type === DataType.Object)
  }

  isArray() {
    return this.value && (this.value.type === DataType.Array)
  }

  isImage() {
    return this.value && (this.value.type === DataType.Image)
  }

  isImageValid() {
    return !!this.value.data;
  }

  isEngine() {
    return this.value && (this.value.type === DataType.Engine)
  }

  onPlaceInTree() {
    Bus.$emit(BusMsg.ShowPlace, this.value);
  }

  created() {

  }

  mounted() {
    this.watchValue();
  }

  isShowTooltip() {
    const el: HTMLDivElement = this.$refs.propText as HTMLDivElement;
    if (el) {
      if (el.scrollWidth > el.offsetWidth) {
        // 出现了省略号
        return true;
      }
    }
    return false;
  }

  getEngineTypeIcon() {
    const value = this.value as EngineData;
    switch (value.engineType) {
      case "cc_Sprite": {
        return "el-icon-picture-outline";
      }
      case "cc_Label": {
        return "el-icon-third-text";
      }
      case "cc_Node": {
        return "el-icon-third-node"
      }
    }
    return "el-icon-third-unknow";
  }

  getName(isArray: boolean, arr: UiProp) {
    const type = arr.value.type;
    if (isArray) {
      return `[${arr.name}]`
    } else {
      return arr.name;
    }
  }

  private fold = true;

  private subData: Property[] | null = null;

  onClickFold() {
    if (this.isObject() && this.fold && !this.subData) {
      // 请求object的item数据
      Bus.$emit(BusMsg.RequestObjectData, this.value, (info: Property[]) => {

        this.fold = false;
        this.subData = info;
      })
    } else {
      this.fold = !this.fold;
    }
  }

  onShowValueInConsole() {
    if (Array.isArray(this.value.path)) {
      let uuid = this.value.path[0];
      let key = this.value.path[1]; // todo 暂时只支持一级key
      if (uuid && key) {
        chrome.devtools.inspectedWindow.eval(`window.CCInspector.logValue('${uuid}','${key}')`)
      }
    }
  }

  onChangeValue() {
    if (!this.value.readonly) {
      connectBackground.postMessageToBackground(Msg.SetProperty, this.value);
    }
  }

  @Prop({default: 1})
  step: number | undefined;


  clientX: number = 0;

  onPropNameMouseDown(event: MouseEvent) {
    document.addEventListener("mousemove", this._onMouseMove);
    document.addEventListener("mouseup", this._onMouseUp);
    document.addEventListener("onselectstart", this._onSelect);
  }

  colorReverse(OldColorValue: string) {
    OldColorValue = "0x" + OldColorValue.replace(/#/g, "");
    var str = "000000" + (0xFFFFFF - parseInt(OldColorValue)).toString(16);
    return "#" + str.substring(str.length - 6, str.length);
  }

  _onSelect() {
    return false;
  }

  _onMouseMove(event: MouseEvent) {
    let x = event.clientX;
    let calcStep = this.step || 0;
    if (x > this.clientX) {
      calcStep = Math.abs(calcStep);
    } else {
      calcStep = -Math.abs(calcStep);
    }
    this.$emit("movestep", calcStep);
    this.clientX = x;
  }

  _onMouseUp(event: MouseEvent) {
    document.removeEventListener("mousemove", this._onMouseMove);
    document.removeEventListener("mouseup", this._onMouseUp);
    document.removeEventListener("onselectstart", this._onSelect);
  }


};
</script>

<style scoped lang="less">
#ui-prop {
  min-height: 30px;
  margin: 1px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;

  .normal-data {
    margin: 0;
    min-height: 30px;
    overflow: hidden;
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;


    .key {
      flex: 1;
      float: left;
      text-align: left;
      display: flex;
      flex-direction: row;
      align-items: center;
      min-width: 90px;

      .data-arrow {
        width: 20px;
        height: 16px;
        font-size: 16px;
        cursor: pointer;
      }

      .text {
        flex: 1;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        user-select: none;
        font-size: 12px;
        margin: 3px;

        span {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }

    .value {
      flex: 3;
      text-align: left;
      height: 100%;
      overflow: hidden;
      min-width: 400px;

      .color {
        position: relative;
        height: 30px;

        .hex {
          line-height: 30px;
          position: relative;
          text-align: center;
          user-select: none;
          pointer-events: none;
        }
      }

      .invalid {
        color: grey;
      }

      .objectDesc {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        user-select: none;
      }

      .array {
        display: flex;
        flex-direction: column;
        color: red;
      }

      .engine {
        display: flex;
        flex-direction: row;
        border: solid #409EFF 1px;
        border-radius: 5px;
        align-items: center;
        align-content: center;

        .head {
          background-color: cornflowerblue;
          height: 28px;
          align-items: center;
          align-content: center;
          display: flex;
          flex-direction: row;

          .icon {
            font-size: 20px;
            width: 20px;
            margin-left: 5px;
          }

          .type {
            display: flex;
            align-content: center;
            align-items: center;
            margin: 0 5px;
          }
        }


        .name {
          flex: 1;
          height: 28px;
          padding-left: 5px;
          background-color: gold;
          display: flex;
          align-items: center;
          align-content: center;
        }
      }

      .vec {
        width: 100%;
        display: flex;
        flex-direction: row;
        align-items: center;

        #ui-prop {
          margin: 0 10px;
          flex: 1;

          .normal-data {
            .value {
              min-width: 50px;
            }

            .key {
              min-width: unset;
              display: block;
              margin-right: 5px;
              flex: unset;
            }
          }
        }

        #ui-prop:first-child {
          margin-left: 0;
        }

        #ui-prop:last-child {
          margin-right: 0;
        }
      }

      .array-object {
        flex: 1;
        max-width: 100%;
        overflow: hidden;
        display: flex;
        flex-direction: row;
        align-items: center;

        .text {
          flex: 1;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
      }

      .image-property {
        display: flex;
        flex-direction: row;
        align-content: center;
        align-items: center;
        height: 36px;
      }

      .slot {
        display: flex;
        width: 100%;
      }
    }
  }
}
</style>
