<template>
  <svg :width="vis.width" :height="vis.height">
    <defs>
        <GraphLinkMarker
          v-for="t in [
            'single-link-arrow-end',
            'multi-link-arrow-end',
            'multi-link-arrow-opposite-end',
            'multi-link-arrow-bar-end',
            'multi-link-arrow-bar-opposite-end'
          ]"
          :key="`marker-${t}`"
          :type="t"
        />
    </defs>
    <g class="link" :class="{ detailed: isDetailed, highlighted: isHighlighted }">
      <line
        :id="`link-${link.id}`"
        :x1="positions.source.x"
        :y1="positions.source.y"
        :x2="positions.target.x"
        :y2="positions.target.y"
        class="link-line"
        :class="{
          hovered: isHovering,
          'with-arrows': link.direction === true,
          'user-defined': link.vis && link.vis.isUserDefined === true,
          transferred: isTransferred,
          multilink: link.vis && link.vis.isMultilink === true,
          'source-to-target': link.direction && link.direction.sourceToTarget,
          'target-to-source': link.direction && link.direction.targetToSource,
          'non-directional': link.direction && link.direction.nonDirectional
        }"
      ></line>

      <text
        v-if="link.description || isMultilink"
        class="label"
        :class="{ 'multilink-label': isMultilink }"
        :dy="(positions.source.y + positions.target.y) / 2 - 5"
        :dx="(positions.source.x + positions.target.x) / 2"
        text-anchor="middle"
      >
        {{ link.description }}
        {{ containedLinksCount > 0 ? containedLinksCount : '' }}
      </text>

      <line
        :x1="positions.source.x"
        :y1="positions.source.y"
        :x2="positions.target.x"
        :y2="positions.target.y"
        class="support-link"
        @mouseover.exact="isHovering = true"
        @mouseover.ctrl.exact="
          SET_LINK_HIGHLIGHT(dataId)
          SET_NODE_HIGHLIGHT(link.source)
          SET_NODE_HIGHLIGHT(link.target)
        "
        @mouseout="
          CLEAR_NODE_HIGHLIGHT()
          CLEAR_LINK_HIGHLIGHT()
          isHovering = false
        "
        @mousedown.prevent
      ></line>
    </g>
  </svg>
</template>

<script>
import { mapMutations, mapActions, mapState, mapGetters } from 'vuex'
import {
  getLinkSource,
  getLinkTarget,
  isBundledIn,
  isMultilink,
  isLinkTransferred
} from '@/store/modules/data.store.js'
import GraphLinkMarker from '@/components/NetworkGraph/GraphLinkMarker.vue'

export default {
  components: {
    GraphLinkMarker
  },
  
  props: {
    dataId: { type: Number, required: true },
    vis: { type: Object, required: true },
    showArrow: { type: Boolean, required: false, default: false }
  },

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

  computed: {
    ...mapGetters('data', ['getNodeById', 'getLinkById', 'getMultilinkLinks']),
    ...mapState('interaction', ['inDebug']),
    ...mapGetters('interaction', ['isLinkDetailed']),
    link() {
      return this.getLinkById(this.dataId)
    },
    isDetailed() {
      return this.isLinkDetailed(this.dataId)
    },
    isHighlighted() {
      return this.$store.getters['interaction/isLinkHighlighted'](this.dataId)
    },
    showLabel() {
      return this.isDetailed || this.isHovering
    },
    positions() {
        return { source: { x: 0, y: 18 }, target: { x: this.vis.width, y: 18 }}
    },
    sourceNode() {
      return this.getNodeById(getLinkSource(this.link))
    },
    targetNode() {
      return this.getNodeById(getLinkTarget(this.link))
    },
    isMultilink() {
      return isMultilink(this.link)
    },
    multilinkLinks() {
      if (!isMultilink(this.link)) return undefined
      return this.getMultilinkLinks(this.dataId)
    },
    containedLinksCount() {
      if (!isMultilink(this.link)) return 0
      return this.getMultilinkLinks(this.dataId).length
    },
    isTransferred: {
      cache: false,
      get: function() {
        return isLinkTransferred(this.link, this.$store)
      }
    }
  },

  methods: {
    ...mapMutations('interaction', [
      'SET_NODE_HIGHLIGHT',
      'CLEAR_NODE_HIGHLIGHT',
      'SET_LINK_HIGHLIGHT',
      'CLEAR_LINK_HIGHLIGHT'
    ]),
    setHighlighted(id) {
      this.isHighlighed ? this.CLEAR_LINK_HIGHLIGHT() : this.SET_LINK_HIGHLIGHT(id)
    },
    isNodeGroup(node) {
      return node.type === 'group'
    }
  }
}
</script>

<style lang="sass" scoped>
.link
  line
    stroke: #bbb
    &.with-arrows
      marker-end: url(#single-link-arrow-end)
    &.multilink
      stroke-width: 3px
      stroke: #000
      &.source-to-target
        marker-end: url(#multi-link-arrow-end)
        &.non-directional
          marker-end: url(#multi-link-arrow-bar-end)
      &.target-to-source
        marker-start: url(#multi-link-arrow-opposite-end)
        &.non-directional
          marker-start: url(#multi-link-arrow-bar-opposite-end)
    &.user-defined
      stroke-dasharray: 7,7
      stroke-linecap: round
    &.transferred
      stroke-dasharray: 0,6
      stroke-width: 2px
      stroke-linecap: round
      &.multilink
        stroke-width: 4px
    &.highlight.highlightable
      stroke: #444
  line.hovered
    stroke: #757575

.link.detailed line.link-line
    stroke: #757575

.link.highlighted line.link-line
    stroke: #757575

.support-link
  stroke-opacity: 0
  stroke-width: 16px

text.label
  font-size: 0.85em
  font-weight: 400
  &.multilink-label
    font-size: 1em
    font-weight: 600

.link-paws
  circle
    fill: #bbb
  .detailed
    fill: #444
  .hovered
    fill: #757575
  .highlighted
    fill: #757575
</style>
