<template>
  <tree
    :data="data"
    :options="treeOptions"
    :treeView="treeView"
    :isAnyNodeChecked="isAnyNodeChecked"
    :showSensorGateway="showSensorGateway"
    :selectedGateways="selectedGateways"
    :treeMapping="treeMapping"
    :isViewMappingLabel="isViewMappingLabel"
    @on-expand-collapse-click="onNodeExpandCollapse"
    @on-add-sibling-node="onAddSiblingNode"
    @on-add-child-node="onAddChildNode"
    @on-node-click="onNodeClick"
    @on-node-select="onNodeSelect"
    @on-node-mouse-over="onNodeMouseOver"
    @on-node-mouse-leave="onNodeMouseLeave"
    @on-node-drag-start="onNodeDragStart"
  >
  </tree>
</template>

<script>
import tree from './renderTree.js'

export default {
  components: {
    tree
  },
  props: {
    treeData: {
      type: Object,
      default: () => {
        return {}
      }
    },
    treeOptions: {
      type: Object,
      default: () => {
        return {}
      },
      required: true
    },
    treeView: {
      type: String,
      default: 'map'
    },
    isAnyNodeSelected: {
      type: Boolean,
      default: false
    },
    showSensorGateway: {
      type: Boolean,
      default: false
    },
    treeMapping: {
      type: Object,
      default: () => {
        return {}
      }
    },
    isViewMappingLabel: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      data: {},
      selectedNodes: [],
      childrenKey: 'children',
      isAnyNodeChecked: false,
      selectedGateways: {}
    }
  },
  methods: {
    onNodeClick (event, data) {
      this.$emit('on-node-click', event, data)
    },
    onNodeExpandCollapse (event, data) {
      this.$set(data.options, 'expanded', !data.options.expanded)
      this.data = this.$_.assign({}, this.data)
    },
    onAddSiblingNode (event, data) {
      this.$emit('on-add-sibling-node', event, data)
    },
    onAddChildNode (event, data) {
      this.$emit('on-add-child-node', event, data)
    },
    onNodeSelect (event, data) {
      if (data.type === 'Gateway') {
        this.selectedGateways = this.$_.merge({}, this.selectedGateways, {
          [data.id]: !this.selectedGateways[data.id]
        })
      }
      this.$set(data.options, 'selected', event)
      if (this.treeOptions.singleSelect) {
        this.isAnyNodeChecked = event
        this.data = this.$_.assign({}, this.data)
      }
      this.$emit('on-node-select', event, data)
    },
    onNodeMouseOver (event, data) {
      this.$emit('on-node-mouse-over', event, data)
    },
    onNodeMouseLeave (event, data) {
      this.$emit('on-node-mouse-leave', event, data)
    },
    onNodeDragStart (event, data) {
      this.$emit('on-node-drag-start', event, data)
    },
    getNodes (data) {
      if (data.options.selected) {
        let formattedData = data

        this.selectedNodes = this.$_.concat(this.selectedNodes, formattedData)
      }

      this.$_.map(data[this.childrenKey] || [], (node) => {
        this.getNodes(node)
      })
    },
    getCheckedNodes () {
      this.selectedNodes = []
      this.childrenKey = this.treeOptions.childrenKey
      this.getNodes(this.data)

      return this.selectedNodes
    }
  },
  mounted () {
    this.data = this.treeData
    this.isAnyNodeChecked = this.isAnyNodeSelected
  }
}
</script>

<style lang="scss" scoped>
.vue-tree.map {
  margin-top: 10px;
  display: flex;
  .tree-node-children {
    margin: 0 auto;
  }
  .tree-node-container {
    text-align: center;
    position: relative;
    .tree-node {
      margin: 0 7px 20px;
      position: relative;
      display: flex;
      justify-content: center;
      .tree-node-label {
        position: relative;
        cursor: pointer;
        .label {
          padding: 10px;
          display: inline-block;
          min-width: 100px;
          text-align: center;
          display: flex;
          align-items: center;
          white-space: nowrap;
          .icon {
            width: 18px;
            height: 18px;
            margin-right: 5px;
          }
        }
        .add-sibling-node-container {
          display: none;
          position: absolute;
          right: -133px;
          top: 50%;
          transform: translateY(-50%);
          z-index: 999;
          padding-left: 7px;
          .add-sibling-node {
            border: 1px solid #3576AB;
            border-radius: 4px;
            box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
            padding: 5px 10px;
            background-color: #3576AB;
            display: flex;
            justify-content: center;
            align-items: center;
            .icon {
              width: 18px;
              height: 18px;
              fill: #ffffff;
            }
            span {
              padding-left: 5px;
              color: #ffffff;
            }
            .arrow-left {
              position: absolute;
              left: 0px;
              top: 50%;
              transform: translateY(-50%);
              width: 0;
              height: 0;
              border-top: 7px solid transparent;
              border-bottom: 7px solid transparent;
              border-right: 7px solid #3576AB;
            }
          }
        }
        .add-child-node-container {
          display: none;
          position: absolute;
          left: 50%;
          bottom: -37px;
          transform: translateX(-50%);
          z-index: 999;
          padding-top: 7px;
          width: 145px;
          justify-content: center;
          .add-child-node {
            border: 1px solid #3576AB;
            border-radius: 4px;
            box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
            padding: 5px 10px;
            background-color: #3576AB;
            display: flex;
            justify-content: center;
            align-items: center;
            .icon {
              width: 18px;
              height: 18px;
              fill: #ffffff;
            }
            span {
              padding-left: 5px;
              color: #ffffff;
            }
            .arrow-up {
              position: absolute;
              top: 0px;
              left: 50%;
              transform: translateX(-50%);
              width: 0;
              height: 0;
              border-left: 7px solid transparent;
              border-right: 7px solid transparent;
              border-bottom: 7px solid #3576AB;
            }
          }
        }
        &:hover {
          .add-sibling-node-container, .add-child-node-container {
            display: flex;
          }
        }
      }
      .icon-container {
        width: 20px;
        height: 20px;
        position: absolute;
        left: 50%;
        bottom: -30px;
        transform: translateX(-50%);
        background: white;
        z-index: 1;
        cursor: pointer;
        .icon {
          width: 20px;
          height: 20px;
          fill: #939598;
          &.expanded {
            transform:  rotate(-90deg);
          }
          &.collapsed {
            transform: rotate(90deg);
          }
        }
      }
      &.leaf {
        .icon-container {
          display: none;
        }
      }
      &:not(.leaf) {
        &::after {
          content: '';
          position: absolute;
          border-left: 1px solid #939598;
          left: 50%;
          bottom: -20px;
          height: 20px;
        }
      }
    }
    .tree-node-children {
      display: flex;
      padding-top: 20px;
      justify-content: center;
      .tree-node-container:not(.single) {
        .highlight-new-entity {
        .label {
          border: 1px solid black;
        }
      }
        &::before {
          content: '';
          border-top: 1px solid #939598;
          top: -20px;
          position: absolute;
          width: 100%;
          left: 0;
        }
        &:first-child {
          &::before {
            width: 50%;
            left: 50%;
          }
        }
        &:last-child {
          &::before {
            width: 50%;
          }
        }
      }
      .tree-node-container {
        &::after {
          content: '';
          position: absolute;
          border-left: 1px solid #939598;
          left: 50%;
          top: -20px;
          height: 20px;
        }
      }
    }
  }
}

.vue-tree.outline {
  margin-top: 10px;
  margin-left: 60px;
  display: flex;
  justify-content: center;
  .tree-node-container {
    position: relative;
    .tree-node {
      margin: 0 20px 20px;
      position: relative;
      display: flex;
      .tree-node-label {
        position: relative;
        cursor: pointer;
        .label {
          padding: 10px 20px;
          display: inline-block;
          height: 40px;
          min-width: 100px;
          text-align: center;
          display: flex;
          align-items: center;
          white-space: nowrap;
          .icon {
            width: 18px;
            height: 18px;
            margin-right: 5px;
          }
        }
        .add-sibling-node-container {
          display: none;
          position: absolute;
          right: -133px;
          top: 50%;
          transform: translateY(-50%);
          z-index: 999;
          padding-left: 7px;
          .add-sibling-node {
            border: 1px solid #3576AB;
            border-radius: 4px;
            box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
            padding: 5px 10px;
            background-color: #3576AB;
            display: flex;
            justify-content: center;
            align-items: center;
            .icon {
              width: 18px;
              height: 18px;
              fill: #ffffff;
            }
            span {
              padding-left: 5px;
              color: #ffffff;
            }
            .arrow-left {
              position: absolute;
              left: 0px;
              top: 50%;
              transform: translateY(-50%);
              width: 0;
              height: 0;
              border-top: 7px solid transparent;
              border-bottom: 7px solid transparent;
              border-right: 7px solid #3576AB;
            }
          }
        }
        .add-child-node-container {
          display: none;
          position: absolute;
          left: 50%;
          bottom: -37px;
          transform: translateX(-50%);
          z-index: 999;
          padding-top: 7px;
          width: 145px;
          justify-content: center;
          .add-child-node {
            border: 1px solid #3576AB;
            border-radius: 4px;
            box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
            padding: 5px 10px;
            background-color: #3576AB;
            display: flex;
            justify-content: center;
            align-items: center;
            .icon {
              width: 18px;
              height: 18px;
              fill: #ffffff;
            }
            span {
              padding-left: 5px;
              color: #ffffff;
            }
            .arrow-up {
              position: absolute;
              top: 0px;
              left: 50%;
              transform: translateX(-50%);
              width: 0;
              height: 0;
              border-left: 7px solid transparent;
              border-right: 7px solid transparent;
              border-bottom: 7px solid #3576AB;
            }
          }
        }
        &:hover {
          .add-sibling-node-container, .add-child-node-container {
            display: flex;
          }
        }
      }
      .highlight-new-entity {
        .label {
          border: 1px solid black;
        }
      }
      .icon-container {
        width: 20px;
        height: 20px;
        border-radius: 10px;
        position: absolute;
        left: 7px;
        bottom: -7px;
        transform: translateX(-50%);
        background: white;
        z-index: 1;
        cursor: pointer;
        .icon {
          width: 20px;
          height: 20px;
          fill: #939598;
          &.expanded {
            transform: rotate(90deg);
          }
        }
      }
      &.leaf {
        .icon-container {
          display: none;
        }
      }
    }
    .tree-node-children {
      display: flex;
      flex-direction: column;
      padding-left: 40px;
      .tree-node-container {
        &:first-child {
          &::after {
            content: '';
            border-left: 1px solid #939598;
            position: absolute;
            height: 30px;
            left: -10px;
            top: -20px;
          }
        }
        &:not(:last-child) {
          &::before {
            content: '';
            border-left: 1px solid #939598;
            position: absolute;
            height: 100%;
            left: -10px;
            top: 10px;
          }
        }
        .tree-node {
          &::before {
            content: '';
            border-top: 1px solid #939598;
            position: absolute;
            width: 30px;
            left: -30px;
            top: 10px;
          }
        }
      }
    }
  }
}

.vue-tree.file {
  margin-top: 10px;
  margin-left:20px;
  .tree-node-container {
    position: relative;
    .tree-node {
      margin: 0 20px 10px;
      position: relative;
      display: flex;
      align-items: center;
      height: 20px;
      padding-top: 3px;
      .label {
        display: flex;
        padding-left: 3px;
        align-items: center;
        white-space: nowrap;
        .icon {
            width: 18px;
            height: 18px;
            margin-right: 5px;
          }
        &.draggable {
          border: 1px solid #e2e2e2;
          background-color: #f8f8f8;
          padding: 3px 6px;
          border-radius: 4px;
          min-width: 90px;
          cursor: grab;
          z-index: 99;
          height: 30px;
        }
      }
      .icon-container {
        width: 16px;
        height: 16px;
        border-radius: 10px;
        position: absolute;
        left: -10px;
        bottom: 2px;
        transform: translateX(-50%);
        background: white;
        z-index: 1;
        cursor: pointer;
        .icon {
          width: 16px;
          height: 16px;
          fill: #3576AB;
          background-color: white;
        }
      }
      &.leaf {
        .icon-container {
          display: none;
        }
        &.draggable {
          height: 30px;
        }
      }
    }
    .tree-node-children {
      display: flex;
      flex-direction: column;
      padding-left: 20px;
      .tree-node-container {
        &:first-child {
          &::after {
            content: '';
            border-left: 1px solid #939598;
            position: absolute;
            height: 35px;
            left: -10px;
            top: -20px;
          }
        }
        &:not(:last-child) {
          &::before {
            content: '';
            border-left: 1px solid #939598;
            position: absolute;
            height: 100%;
            left: -10px;
            top: 15px;
          }
        }
        .tree-node {
          &::before {
            content: '';
            border-top: 1px solid  #939598;
            position: absolute;
            width: 28px;
            left: -30px;
            top: 15px;
          }
        }
      }
    }
  }
}

.vue-tree.map, .vue-tree.outline {
  .tree-node {
    &.organisation {
      span.label {
        background-color: #eae8e8;
        border-top: 2px solid gray !important;
        border: 1px solid #F1F3F4;
      }
    }
    &.project {
      span.label {
        background-color: #FBF6E8;
        border-top: 2px solid #FCD770 !important;
        border: 1px solid #F1F3F4;
        box-sizing: border-box;
      }
    }
    &.asset {
      span.label {
        background-color: #e9e1fb;
        border-top: 2px solid #7759A6 !important;
        border: 1px solid #F1F3F4;
        box-sizing: border-box;
      }
    }
    &.sensor {
      span.label {
        background-color: #EAFEFE;
        border-top: 2px solid #3CBFBD !important;
        border: 1px solid #F1F3F4;
        box-sizing: border-box;
      }
    }
    &.gateway {
      span.label {
        background-color: #ffcc99;
      }
    }
  }
}

.vue-tree {
  .tree-node {
    &.sensor {
      span.label {
        .icon {

        }
      }
      .tree-node-label.tree-sensor-node-gateway-label {
        margin-top:2px;
        text-align: left;
        span {
          display: inline-block !important;
          text-align: center;
          background-color: #f2f2f2 !important;
          border: 1px solid #7ad9ff;
        }
      }
      &.gateway-sensor {
        display: block !important;
      }
    }
  }
}

svg {
  vertical-align: baseline;
}

</style>

<style lang="scss">
  .vue-tree {
      &.map, &.outline {
        .tree-node.gateway {
          position: relative;
          .custom-checkbox {
            position: absolute;
            left: 10px;
            top: 50%;
            transform: translateY(-50%);
            z-index: 100;
            width: 18px;
          }
          .tree-node-label {
            .label {
              padding-left: 33px !important;
            }
            .icon {
              display: none;
            }
          }
        }
      }
    }
  .vue-tree.file {
    .custom-control-label {
      cursor: pointer;
      &::before, &::after {
        left: -21px;
      }
    }
  }
</style>
