<template>
  <div class="compass-widget">
    <div class="compass-row-helper">
      <div class="compass-label compass-label-left">{{ leftLabel }}</div>
      <div class="compass-container">
        <div class="compass-label compass-label-top">{{ topLabel }}</div>
        <div class="compass">
          <div class="compass-x-axis"></div>
          <div class="compass-y-axis"></div>
          <div
            class="compass-marker compass-select-marker"
            :style="{
              bottom: markerBottom,
              left: markerLeft,
            }"
          ></div>
          <div class="context-markers"></div>
        </div>
        <div class="compass-label compass-label-bottom">{{ bottomLabel }}</div>
      </div>
      <div class="compass-label compass-label-right">{{ rightLabel }}</div>
    </div>

    <div class="compass-fields">
      <div class="compass-field">
        <label for="compass_field_x_{{ widget.name }}">
          {{ xLabel }}
        </label>
        <input
          type="number"
          v-model.number="xVal"
          :min="-xRange"
          :max="xRange"
        />
      </div>
      <div class="compass-field">
        <label for="compass_field_y_{{ widget.name }}">
          {{ yLabel }}
        </label>
        <input
          type="number"
          v-model.number="yVal"
          :min="-yRange"
          :max="yRange"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { asDict } from "@/lib/entity";
import { IEntry } from "@/types/base";
import { defineComponent, PropType, ref } from "vue";

export default defineComponent({
  name: "Compass",
  props: {
    attributes: {
      type: Array as PropType<[string, IEntry][]>,
      required: true,
    },
    xAttrName: {
      type: String,
      required: true,
    },
    yAttrName: {
      type: String,
      required: true,
    },
    xLabel: {
      type: String,
      default: "X",
    },
    yLabel: {
      type: String,
      default: "Y",
    },
    xRange: {
      type: Number,
      default: 100,
    },
    yRange: {
      type: Number,
      default: 100,
    },
  },
  computed: {
    topLabel(): string | undefined {
      return this.yLabel.includes("//")
        ? this.yLabel.split("//")[1]
        : undefined;
    },
    bottomLabel(): string | undefined {
      return this.yLabel.includes("//")
        ? this.yLabel.split("//")[0]
        : undefined;
    },
    leftLabel(): string | undefined {
      return this.xLabel.includes("//")
        ? this.xLabel.split("//")[0]
        : undefined;
    },
    rightLabel(): string | undefined {
      return this.xLabel.includes("//")
        ? this.xLabel.split("//")[1]
        : undefined;
    },
    markerBottom(): string {
      return `${((this.yVal + this.yRange) / (this.yRange * 2)) * 100}%`;
    },
    markerLeft(): string {
      return `${((this.xVal + this.xRange) / (this.xRange * 2)) * 100}%`;
    },
  },
  setup(props) {
    const attrs = asDict(props.attributes);
    const xVal = ref(parseInt(attrs[props.xAttrName]) || -1);
    const yVal = ref(parseInt(attrs[props.yAttrName]) || -1);

    return {
      xVal,
      yVal,
    };
  },
});
</script>

<style lang="scss" scoped>
.compass-container {
  width: 100%;
}

.compass {
  position: relative;

  width: 100%;
  padding-top: 100%; /* 1:1 Aspect Ratio */
}

.compass-row-helper {
  display: flex;
  align-items: center;
}

.compass-label {
  margin: 0.5em;
  text-align: center;
}

.compass-marker {
  position: absolute;
  width: 1.5%;
  height: 1.5%;
  background: red;
}

.context-markers div {
  opacity: 25%;
}

.compass-x-axis {
  position: absolute;
  top: 50%;
  left: 0;
  height: 0;
  width: 100%;
  border: 1px dashed gray;
}

.compass-y-axis {
  position: absolute;
  top: 0;
  left: 50%;
  width: 0;
  height: 100%;
  border: 1px dashed gray;
}

.compass-fields {
  display: flex;
  justify-content: center;
  margin: 1rem 0;

  .compass-field {
    margin: 0 1em;
    text-align: center;

    label {
      display: inline-block;
      margin: 0 0.5em;
    }

    input {
      width: 4em;
      font-family: monospace;
      text-align: left;
    }
  }
}
</style>