<template>
  <foreignObject
    :x="Math.round(parent_aspect_ratio * rectangle.left)"
    :y="rectangle.top"
    :width="Math.round(parent_aspect_ratio * rectangle.width)"
    :height="rectangle.height"
    :style="`transform: scaleX(${1 / parent_aspect_ratio})`"
  >
    <div
      v-if="variant !== undefined"
      xmlns="http://www.w3.org/1999/xhtml"
      class="px-4 is-flex is-align-items-center is-justify-content-center is-size-1 has-text-weight-bold"
    >
      <slot name="default" />
    </div>
  </foreignObject>
  <rect
    ref="rect"
    v-bind="$attrs"
    :class="variant !== undefined ? variant : ''"
    :x="rectangle.left"
    :y="rectangle.top"
    :width="rectangle.width"
    :height="rectangle.height"
  />
</template>

<script lang="ts">
import { Rectangle } from "@/lib/rectangle";
import { Options, Vue } from "vue-class-component";

type BulmaVariant =
  | "primary"
  | "link"
  | "info"
  | "success"
  | "warning"
  | "danger";

@Options({
  props: {
    variant: {
      type: String,
      required: false,
    },
    rectangle: Rectangle,
  },
})
export default class extends Vue {
  public variant?: BulmaVariant;
  public rectangle!: Rectangle;

  private refreshKey = 0;

  declare $refs: {
    rect: unknown;
  };

  private refresh() {
    window.setTimeout(() => {
      // don't loop endlessly
      if (this.refreshKey < 10000) {
        this.refreshKey++;
      }
    }, 100);
  }

  public get parent_aspect_ratio(): number {
    this.refreshKey; // read it just to force recompute on change

    if (
      !(this.$refs.rect instanceof SVGRectElement) ||
      this.$refs.rect.parentElement === null
    ) {
      this.refresh();
      return 1;
    }

    const parent = this.$refs.rect.parentElement;
    const result = parent.clientWidth / parent.clientHeight;

    // force recompute for suspicious results
    if (result === 0 || result === Infinity) {
      this.refresh();
      return 1;
    }

    return result;
  }
}
</script>

<style lang="scss" scoped>
@import "@/bulma-vars";

foreignObject > div {
  height: inherit;
}

rect {
  fill: transparent;
  fill-opacity: 0.3;
  stroke-opacity: 0.9;
  stroke-width: 1;

  &.primary {
    fill: $primary;
    stroke: $primary;
  }

  &.link {
    fill: $link;
    stroke: $link;
  }

  &.info {
    fill: $info;
    stroke: $info;
  }

  &.success {
    fill: $success;
    stroke: $success;
  }

  &.warning {
    fill: $warning;
    stroke: $warning;
  }

  &.danger {
    fill: $danger;
    stroke: $danger;
  }
}
</style>
