<template>
  <div
    
  >
    <svg :height="height" :width="visuals.showLabel ? '': width">
      <g
        class="node"
        :class="{
        hovered: isHovered,
        highlighted: isHighlighted
      }"
        :transform="`translate(${radius}, ${radius +  + (this.bundleSize > 0 ? 5 : 0)})`"
        @mouseover.exact="onMouseover"
        @mouseout="onMouseout"
      >
        <g class="node-icon">
          <circle
            v-if="node.type === 'group'"
            class="node-circle"
            :r="visCircleRadius + visuals.groupNodeRadiusDifference"
          />

          <!-- alias -->
          <circle
            v-if="node.type === 'alias'"
            class="node-circle"
            :cx="-visCircleRadius / 2.0"
            :cy="-visCircleRadius / 2.0"
            :r="visCircleRadius"
          />

          <!-- bundle -->
          <g v-if="bundleSize > 0" class="bundle-bubble">
            <circle
              class="node-circle bundle-circle"
              :r="visCircleRadius / 3.0"
              :cx="visCircleRadius + visBundleCircleDistance"
              :cy="-visCircleRadius - visBundleCircleDistance"
            />
            <text
              class="bundle-text"
              :class="{ small: visuals.smallLabel }"
              text-anchor="middle"
              :x="visCircleRadius + visBundleCircleDistance"
              :y="-visCircleRadius + visBundleCircleDistance - (['group', 'alias'].includes(node.type) ? visuals.groupNodeRadiusDifference * 2 : 0)"
            >{{ bundleSize }}</text>
          </g>

          <circle v-if="isHighlighted" class="node-circle-highlighted" :r="visCircleRadius" />
          <circle
            :id="`node-circle-${node.id}`"
            class="node-circle"
            :r="visCircleRadius"
            :fill="`#fff`"
          />
          <BaseIcon
            use-svg
            :name="node.type === 'group' ? 'group' : node.dataClass"
            :radius="visCircleRadius"
          />

          <text
            v-if="visuals.showLabel"
            class="node-label"
            :class="{ small: visuals.smallLabel }"
            :dx="visuals.smallLabel ? 18 : 27"
            :dy="visuals.smallLabel ? 5 : 7"
            >
          {{ visuals.maxLabelLength !== undefined ? node.label.substring(0, visuals.maxLabelLength) + '...' : node.label }}
        </text>
        </g>
      </g>
    </svg>
  </div>
</template>

<script>
import { mapMutations, mapState, mapActions, mapGetters } from 'vuex'

export default {
  props: {
    dataId: { type: Number, required: true },
    visuals: { type: Object, required: false, default: function () {
        return { baseNodeRadius: 15, groupNodeRadiusDifference: 3, smallLabel: false, maxLabelLength: undefined, showLabel: true }
      }
    },
    
    allowHover: { type: Boolean, required: false, default: true }
  },

  data() {
    return {
      isHovering: false
    }
  },

  computed: {
    ...mapState('interaction', ['inDebug']),
    node() {
      return this.$store.getters['data/getNodeById'](this.dataId)
    },
    isHovered() {
      return this.$store.getters['interaction/isNodeHovered'](this.dataId)
    },
    isHighlighted() {
      return this.$store.getters['interaction/isNodeHighlighted'](this.dataId)
    },
    radius() {
      let radius = this.visuals.baseNodeRadius + 2
      if (this.isDetailed && this.isSelected) radius += 1
      if (this.node.type === 'group') radius += this.visuals.groupNodeRadiusDifference
      return radius
    },
    visCircleRadius() {
      if (this.isDetailed && this.isSelected) return this.visuals.baseNodeRadius + 1
      if (this.isRemoved) return this.visuals.baseNodeRadius
      return this.visuals.baseNodeRadius
    },
    visBundleCircleDistance() {
      return (
        2 +
        (['group', 'alias'].includes(this.node.type) ? this.visuals.groupNodeRadiusDifference : 0)
      )
    },
    bundleSize: {
      cache: false,
      get: function() {
        return this.$store.getters['data/getNodeBundledNodeCount'](this.dataId)
      }
    },
    width() {
      return this.radius * 2 + (this.bundleSize > 0 ? 6 : 0)
    },
    height() {
      return this.radius * 2 + (this.bundleSize > 0 ? 6 : 0)
    }
  },

  methods: {
    ...mapActions('interaction', ['stopHighlighting']),
    ...mapMutations('interaction', [
      'SET_NODE_HIGHLIGHT',
      'UNSET_NODE_HIGHLIGHT',
      'SET_LINK_HIGHLIGHT'
    ]),
    onMouseover() {
        if (this.allowHover) this.SET_NODE_HIGHLIGHT(this.node.id)
    },
    onMouseout() {
        if (this.allowHover) this.UNSET_NODE_HIGHLIGHT(this.node.id)
    }
  }
}
</script>

<style lang="sass" scoped>
.hovered .node-circle
  stroke: #979797

.node-circle
  stroke-width: 1.5px
  stroke: #d8d8d8
  fill: #fff

.node-label
  font-size: 1em
  font-weight: 600
  fill: #666

.node-label.small
  font-size: 0.85em
  font-weight: 400
  fill: #666

.detailed .node-icon .node-circle
  stroke: #757575

.highlighted .node-icon .node-circle
  stroke: #979797
  fill: #979797

.selected .node-icon .node-circle
  stroke: #1e2dff
  stroke-width: 1.5px

.node-circle-detailed-and-selected
  stroke: #979797
  stroke-width: 3.5px

.node-circle.connected-link-hovered
  stroke: #757575

.bundle .bundle-bubble
  display: inline

.bundle-circle
  stroke-width: 1.5px
  stroke: #D8D8D8
  fill: #fff

.bundle-text
  font-size: 0.65em
  font-weight: 600
  fill: #666
.bundle-text.small
  font-size: 0.5em
  font-weight: 600  
</style>