<template>
  <div>
    <div ref="render" class="fit"></div>
  </div>
</template>

<style scoped></style>

<script lang="ts">
import {
  defineComponent,
  ref,
  Ref,
  watch,
  computed,
  onMounted,
  onBeforeUnmount,
  nextTick,
} from "vue";
const elementResizeDetectorMaker = require("element-resize-detector");
import { useStore } from "src/store";
import { useQuasar, copyToClipboard } from "quasar";
import { useI18n } from "vue-i18n";
import GlobalData from "src/common/GlobalData";

import CanvasPainter from "zrender/lib/canvas/Painter";
import * as zrender from "zrender";

import {
  EdgeBlendingInfo,
  EdgeBlendingPoint,
} from "src/entities/EdgeBlendingEntities";

class _GridItem {
  row = 0;
  col = 0;
  x = 0;
  y = 0;
  width = 0;
  height = 0;
  index = 0;
  points: EdgeBlendingPoint[] = [];
}

export default defineComponent({
  name: "ComponentEdgeBlendingControl",
  components: {},
  props: {
    edge_blending_info: {
      type: EdgeBlendingInfo,
      default: new EdgeBlendingInfo(),
    },
    all_points: {
      type: Array,
      default: [],
    },
  },
  setup($props) {
    let $store = useStore();
    let $q = useQuasar();
    let $t = useI18n();

    const render: Ref<any> = ref(null);

    const real_render_width = ref(0);
    const real_render_height = ref(0);
    const width_scaler = ref(0.0);
    const height_scaler = ref(0.0);

    let grid_items: _GridItem[] = [];

    let z_render: zrender.ZRenderType;
    let background_group: zrender.Group;
    let points_group: zrender.Group;

    const get_point = (row: number, col: number, index: number) => {
      const result = ($props.all_points as EdgeBlendingPoint[]).find(
        (element) =>
          element &&
          element.row == row &&
          element.col == col &&
          element.point_index == index
      );
      return result;
    };

    const refresh_grid_items = () => {
      const grid_width =
        $props.edge_blending_info.width / $props.edge_blending_info.col;
      const grid_height =
        $props.edge_blending_info.height / $props.edge_blending_info.row;

      grid_items = [];
      for (let row = 0; row < $props.edge_blending_info.row; ++row) {
        for (let col = 0; col < $props.edge_blending_info.col; ++col) {
          let item = new _GridItem();
          item.index = row * $props.edge_blending_info.col + col;
          item.row = row;
          item.col = col;
          item.x = grid_width * item.col;
          item.y = grid_height * item.row;
          item.width = grid_width;
          item.height = grid_height;
          item.points = [];

          for (let i = 0; i < $props.edge_blending_info.point_count; ++i) {
            const point = get_point(row, col, i);
            if (point) {
              item.points.push(point);
            }
          }

          grid_items.push(item);
        }
      }
    };

    const initialize_zrender = () => {
      if (render.value) {
        zrender.registerPainter("canvas", CanvasPainter);
        z_render = zrender.init(render.value);
        console.log(z_render);
        background_group = new zrender.Group();
        points_group = new zrender.Group();

        z_render.add(background_group);
        z_render.add(points_group);
      }
    };

    const render_background = () => {
      background_group.removeAll();
      for (const grid_item of grid_items) {
        if (grid_item) {
          var rect = new zrender.Rect({
            shape: {
              x: grid_item.x * width_scaler.value + 5,
              y: grid_item.y * height_scaler.value + 5,
              width: grid_item.width * width_scaler.value,
              height: grid_item.height * height_scaler.value,
            },
            style: {
              fill: "none",
              stroke: "#F00",
              lineDash: [10, 5],
            },
          });
          var text = new zrender.Text({
            style: {
              x: rect.shape.x,
              y: rect.shape.y,
              width: rect.shape.width,
              height: rect.shape.height,
              align: "center",
              verticalAlign: "middle",
              fill: "red",
              stroke: "none",
              text: "aaa",
            },
          });
          background_group.add(rect);
          background_group.add(text);
        }
      }
    };

    const render_points = () => {
      points_group.removeAll();
      for (const grid_item of grid_items) {
        if (grid_item) {
          for (const point of grid_item.points) {
            if (point) {
              var circle = new zrender.Circle({
                shape: {
                  cx: (grid_item.x + point.x) * width_scaler.value + 5,
                  cy: (grid_item.y + point.y) * height_scaler.value + 5,
                  r: 5,
                },
                style: {
                  fill: "black",
                  stroke: "none",
                },
                draggable: true,
              });
              points_group.add(circle);
            }
          }
        }
      }
    };

    const do_render = () => {
      render_background();
      render_points();
    };

    onMounted(() => {
      if (render.value) {
        elementResizeDetectorMaker().listenTo(
          render.value,
          (element: HTMLElement) => {
            if (element) {
              real_render_width.value = element.clientWidth - 10;
              real_render_height.value = element.clientHeight - 10;
              if (z_render) {
                z_render.resize({
                  width: element.clientWidth,
                  height: element.clientHeight,
                });
              }
              width_scaler.value =
                real_render_width.value / $props.edge_blending_info.width;
              height_scaler.value =
                real_render_height.value / $props.edge_blending_info.height;
              do_render();
            }
          }
        );
        initialize_zrender();
      }
    });

    refresh_grid_items();

    return {
      render,
      real_render_width,
      real_render_height,
      width_scaler,
      height_scaler,
    };
  },
});
</script>
