<template>
  <div class="row">
    <div class="col-2">
      <q-input filled type="number" class="q-pt-xs" style="text-align: center" :dense="true"
        @focus="isactivearray[0] = false" v-model="four[0].x" label="x" lazy-rules />
      <q-input filled type="number" class="q-pt-xs" :dense="true" @focus="isactivearray[0] = false" v-model="four[0].y"
        label="y" lazy-rules />
      <q-btn size="sm" dense color="white" @click="reset(0)" text-color="black"
        :label="$t('reset') + $t('point') + '1'" />
    </div>
    <div class="col-8"></div>
    <div class="col-2">
      <q-input filled type="number" class="q-pt-xs" :dense="true" @focus="isactivearray[1] = false" v-model="four[1].x"
        label="x" lazy-rules />
      <q-input filled type="number" class="q-pt-xs" :dense="true" @focus="isactivearray[1] = false" v-model="four[1].y"
        label="y" lazy-rules />
      <q-btn size="sm" dense color="white" @click="reset(1)" text-color="black"
        :label="$t('reset') + $t('point') + '2'" />
    </div>

    <div class="col-2"></div>
    <div class="col-8">
      <div ref="div" style="background-color: #646464; height: 40vh">
        <div style="position: absolute">
          <vue3ResizeDrag style="border: 0;" :class="[now_index == 0 ? 'action' : '']" v-if="isshowarray[0]"
            :isActive="isactivearray[0]" @mousedown="activeMouseDown(0)" @mouseUpHandler="mouseUpHandler(0)" :w="20"
            :h="20" :x="points[0].x" :y="points[0].y" :isResizable="false" @moveHandler="moveHandler_1">
            <div class="point">1</div>
          </vue3ResizeDrag>
          <vue3ResizeDrag style="border: 0;" :class="[now_index == 1 ? 'action' : '']" v-if="isshowarray[1]"
            :isActive="isactivearray[1]" @mousedown="activeMouseDown(1)" @mouseUpHandler="mouseUpHandler(1)" :w="20"
            :h="20" :x="points[1].x" :y="points[1].y" :isResizable="false" @moveHandler="moveHandler_2">
            <div class="point">2</div>
          </vue3ResizeDrag>
          <vue3ResizeDrag style="border: 0;" :class="[now_index == 2 ? 'action' : '']" v-if="isshowarray[2]"
            :isActive="isactivearray[2]" @mousedown="activeMouseDown(2)" @mouseUpHandler="mouseUpHandler(2)" :w="20"
            :h="20" :x="points[2].x" :y="points[2].y" :isResizable="false" @moveHandler="moveHandler_3">
            <div class="point">3</div>
          </vue3ResizeDrag>
          <vue3ResizeDrag style="border: 0;" :class="[now_index == 3 ? 'action' : '']" v-if="isshowarray[3]"
            :isActive="isactivearray[3]" @mousedown="activeMouseDown(3)" @mouseUpHandler="mouseUpHandler(3)" :w="20"
            :h="20" :x="points[3].x" :y="points[3].y" :isResizable="false" @moveHandler="moveHandler_4">
            <div class="point">4</div>
          </vue3ResizeDrag>
        </div>
      </div>
    </div>
    <div class="col-2"></div>

    <div class="col-2">
      <q-input filled type="number" class="q-pt-xs" :dense="true" @focus="isactivearray[2] = false" v-model="four[2].x"
        label="x" lazy-rules />
      <q-input filled type="number" class="q-pt-xs" :dense="true" @focus="isactivearray[2] = false" v-model="four[2].y"
        label="y" lazy-rules />
      <q-btn size="sm" dense color="white" @click="reset(2)" text-color="black"
        :label="$t('reset') + $t('point') + '3'" />
    </div>
    <div class="col-8">
      <q-btn size="sm" dense color="white" @click="resetall" text-color="black" :label="$t('resetall')" />
    </div>
    <div class="col-2">
      <q-input filled type="number" class="" :dense="true" @focus="isactivearray[3] = false" v-model="four[3].x"
        label="x" lazy-rules />
      <q-input filled type="number" class="q-pt-md" :dense="true" @focus="isactivearray[3] = false" v-model="four[3].y"
        label="y" lazy-rules />
      <q-btn size="sm" dense color="white" @click="reset(3)" text-color="black"
        :label="$t('reset') + $t('point') + '4'" />
    </div>
  </div>
</template>

<style scoped>
.point {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: #0000ff;
  color: aliceblue;
}

.action {
  background-color: aqua;
}
</style>
<script lang="ts">
import vue3ResizeDrag from "src/third_lib/vue3-resize-drag/components/vue3-resize-drag/index.vue";
import { dom } from "quasar";

import {
  defineComponent,
  ref,
  watch,
  computed,
  defineProps,
  withDefaults,
  onMounted,
  reactive,
  onBeforeUnmount,
} from "vue";
import { useStore } from "src/store";
import { useI18n } from "vue-i18n";
import ClientConnection from "src/common/ClientConnection";
import GlobalData from "src/common/GlobalData";
import { Console } from "console";

export default defineComponent({
  name: "ComponentFourPointCalibration",
  components: {
    vue3ResizeDrag,
  },
  setup() {
    let $store = useStore();
    let $t = useI18n();
    let config = JSON.parse($store.state.fusion_configuration).projectors[0];
    let set = GlobalData.getInstance().getCurrentClient();
    const configselsect = computed(() => {
      return $store.state.selected_projector;
    });
    //用于计算当前投影仪的索引
    let serverconfig = JSON.parse($store.state.fusion_configuration);
    const selectedprojector = computed(() => {
      return (
        $store.getters.GetTheCurrentlySelectedCamera[0] * serverconfig.col +
        $store.getters.GetTheCurrentlySelectedCamera[1]
      );
    });
    const set_cache: any = ref([]);
    let four = reactive([
      { x: config.point4[0].x, y: config.point4[0].y },
      { x: config.point4[1].x, y: config.point4[1].y },
      { x: config.point4[2].x, y: config.point4[2].x },
      { x: config.point4[3].x, y: config.point4[3].y },
    ]);
    let defaultfour = ref([
      { x: 0, y: 1080 },
      { x: 1920, y: 1080 },
      { x: 0, y: 0 },
      { x: 1920, y: 0 },
    ]);
    let defaultfourpostion: any = ref([
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
    ]);
    let fourpostion: any = ref([
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
    ]);
    let div: any = ref(null);
    let Proportion = ref({ x: 0, y: 0 }); //缩放比例
    let points = reactive([
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
      { x: 0, y: 0 },
    ]); //点的位置
    const now_index = ref(0)
    const isshowarray = ref([true, true, true, true]);
    const isactivearray = ref([true, true, true, true]);
    const ste_status = ref(0);
    const save = () => {
      set?.SaveBlendingConfig("");
      setTimeout(() => {
        set?.GetBlendingConfig("").then((res) => {
          $store.commit("setfusion_configuration", res?.config);
        });
      }, 1000);
    };
    const use_set_cache = () => {
      if (set_cache.value[selectedprojector.value] != null) {
        let tmp = JSON.parse(set_cache.value[selectedprojector.value]);
        deepcopy(four, tmp);
      }
      syncpoint();
    };
    const deepcopy = (o1: any, o2: any) => {
      for (let k in o2) {
        if (typeof o2[k] === "object") {
          o1[k] = {};
          deepcopy(o1[k], o2[k]);
        } else {
          o1[k] = o2[k];
        }
      }
    };
    const save_set_cache = () => {
      set_cache.value[selectedprojector.value] = JSON.stringify(four);
    };
    onBeforeUnmount(() => {
      sessionStorage.FourPointCalibration = JSON.stringify(set_cache.value);
    });
    const activeMouseDown = (index: number) => {
      isactivearray.value[index] = true;
      now_index.value = index
    };
    const mouseUpHandler = (index: number) => {
      isactivearray.value[index] = false;
    };
    const keyDown = () => {
      document.onkeydown = (e) => {


        // let x = Math.ceil(four[now_index.value].x / Proportion.value.x);
        // let y = Math.ceil((config.height - four[now_index.value].y) / Proportion.value.y);
        // points[now_index.value].x!=x?points[now_index.value].x = x:''
        // points[now_index.value].y!= y?points[now_index.value].y = y:''

        let e1 = e || window.event || arguments.callee.caller.arguments[0]
        switch (e.code) {
          case "KeyW":
            points[now_index.value].x
            points[now_index.value].y--
            break;
          case "KeyA":
            points[now_index.value].x--;
            points[now_index.value].y
            break;
          case "KeyS":
            points[now_index.value].x;
            points[now_index.value].y++
            break;
          case "KeyD":
            points[now_index.value].x++;
            points[now_index.value].y
            break;
          default:
            break;
        }
        let tmp = { left: points[now_index.value].x, top: points[now_index.value].y }
        eval(`moveHandler_${now_index.value+1}(tmp)`);
        isactivearray.value[now_index.value] = false;
        isshowarray.value[now_index.value] = false;
        setTimeout(() => {
          isshowarray.value[now_index.value] = true;
        }, 100);
      }
    }
    onMounted(() => {
      ste_status.value = 1;
      keyDown()
      setpoa();

      setTimeout(() => {
        ste_status.value = 0;
      }, 100);
    });

    const use_server_config = () => {
      for (let index = 0; index < fourpostion.value.length; index++) {
        defaultfour.value[index].x = config.point4[index].def_x;
        defaultfour.value[index].y = config.point4[index].def_y;
        four[index].x = config.point4[index].x;
        four[index].y = config.point4[index].y;
      }
    };

    const setpoa = () => {
      try {
        points[0].x = 0;
        points[0].y = 0;

        points[1].x = div.value.offsetWidth - 25;
        points[1].y = 0;

        points[2].x = 0;
        points[2].y = div.value.offsetHeight - 25;

        points[3].x = div.value.offsetWidth - 25;
        points[3].y = div.value.offsetHeight - 25;

        fourpostion.value[0].x = 0;
        fourpostion.value[0].y = 0;

        fourpostion.value[1].x = div.value.offsetWidth - 25;
        fourpostion.value[1].y = 0;

        fourpostion.value[2].x = 0;
        fourpostion.value[2].y = div.value.offsetHeight - 25;

        fourpostion.value[3].x = div.value.offsetWidth - 25;
        fourpostion.value[3].y = div.value.offsetHeight - 25;

        Proportion.value.x = config.width / (div.value.offsetWidth - 25);
        Proportion.value.y = config.height / (div.value.offsetHeight - 25);
        for (let index = 0; index < fourpostion.value.length; index++) {
          defaultfourpostion.value[index].x = fourpostion.value[index].x;
          defaultfourpostion.value[index].y = fourpostion.value[index].y;
          defaultfour.value[index].x = config.point4[index].def_x;
          defaultfour.value[index].y = config.point4[index].def_y;
          four[index].x = config.point4[index].x;
          four[index].y = config.point4[index].y;
        }
        if (
          sessionStorage.FourPointCalibration &&
          sessionStorage.FourPointCalibration.length > 0
        ) {
          set_cache.value = JSON.parse(sessionStorage.FourPointCalibration);
          use_set_cache();
        } else {
        }
        set_point_x();
      } catch (error) {

      }
    };
    watch(
      () => four[0],
      (newVal, oldVal) => {
        if ($store.state.enablefusion && ste_status.value == 0)
          set?.setBlendingCorrection(
            $store.getters.GetTheCurrentlySelectedCamera[0],
            $store.getters.GetTheCurrentlySelectedCamera[1],
            4,
            1,
            Number(newVal.x),
            Number(newVal.y)
          );
        if (!isactivearray.value[0]) {
          let x = Math.ceil(newVal.x / Proportion.value.x);
          let y = Math.ceil((config.height - newVal.y) / Proportion.value.y);
          points[0].x = x;
          points[0].y = y;
          isshowarray.value[0] = false;
          isactivearray.value[0] = false;
          setTimeout(() => {
            isshowarray.value[0] = true;
          }, 100);
        }
        now_index.value = 0
        save_set_cache();
      },
      { deep: true }
    );
    watch(
      () => four[1],
      (newVal, oldVal) => {
        if ($store.state.enablefusion && ste_status.value == 0)
          set?.setBlendingCorrection(
            $store.getters.GetTheCurrentlySelectedCamera[0],
            $store.getters.GetTheCurrentlySelectedCamera[1],
            4,
            2,
            Number(newVal.x),
            Number(newVal.y)
          );
        if (!isactivearray.value[1]) {
          let x = Math.ceil(newVal.x / Proportion.value.x);
          let y = Math.ceil((config.height - newVal.y) / Proportion.value.y);
          points[1].x = x;
          points[1].y = y;
          isshowarray.value[1] = false;
          isactivearray.value[1] = false;
          setTimeout(() => {
            isshowarray.value[1] = true;
          }, 100);
        }
        now_index.value = 1
        save_set_cache();
      },
      { deep: true }
    );
    watch(
      () => four[2],
      (newVal, oldVal) => {
        if ($store.state.enablefusion && ste_status.value == 0)
          set?.setBlendingCorrection(
            $store.getters.GetTheCurrentlySelectedCamera[0],
            $store.getters.GetTheCurrentlySelectedCamera[1],
            4,
            3,
            Number(newVal.x),
            Number(newVal.y)
          );
        if (!isactivearray.value[2]) {
          let x = Math.ceil(newVal.x / Proportion.value.x);
          let y = Math.ceil(
            config.height / Proportion.value.y - newVal.y / Proportion.value.y
          );

          points[2].x = x;
          points[2].y = y;
          isshowarray.value[2] = false;
          setTimeout(() => {
            isshowarray.value[2] = true;
          }, 100);
        }
        now_index.value = 2
        save_set_cache();
      },
      { deep: true }
    );
    watch(
      () => four[3],
      (newVal, oldVal) => {
        if ($store.state.enablefusion && ste_status.value == 0)
          set?.setBlendingCorrection(
            $store.getters.GetTheCurrentlySelectedCamera[0],
            $store.getters.GetTheCurrentlySelectedCamera[1],
            4,
            4,
            Number(newVal.x),
            Number(newVal.y)
          );
        if (!isactivearray.value[3]) {
          let x = Math.ceil(newVal.x / Proportion.value.x);
          let y = Math.ceil(
            config.height / Proportion.value.y - newVal.y / Proportion.value.y
          );

          points[3].x = x;
          points[3].y = y;
          isshowarray.value[3] = false;
          setTimeout(() => {
            isshowarray.value[3] = true;
          }, 100);
        }
        now_index.value = 3
        save_set_cache();
      },
      { deep: true }
    );

    watch(
      () => configselsect,
      (newVal, oldVal) => {
        let tmp = JSON.parse($store.state.fusion_configuration);
        let fortmp = null;
        let i;
        for (i of tmp.projectors) {
          if (
            i.col === $store.getters.GetTheCurrentlySelectedCamera[1] &&
            i.row === $store.getters.GetTheCurrentlySelectedCamera[0]
          ) {
            fortmp = JSON.parse(JSON.stringify(i));
          }
        }
        ste_status.value = 1;
        config = JSON.parse(JSON.stringify(fortmp));
        use_server_config();
        use_set_cache();
        setTimeout(() => {
          ste_status.value = 0;
        }, 100);
        set_point_x();
      },
      { deep: true }
    );
    watch(() => now_index, (newval, oldval) => {
      set?.SetBlendingOption("blending_grids_select_point", `4:${now_index.value + 1}`)
    }, { deep: true })
    //为了加载 缓存的配置时 同步点的位置
    const syncpoint = () => {
      for (let index = 0; index < fourpostion.value.length; index++) {
        isactivearray.value[index] = false;
      }
    };
    //手动同步
    const set_point_x = () => {
      let x = Math.ceil(four[0].x / Proportion.value.x);
      let y = Math.ceil((config.height - four[0].y) / Proportion.value.y);
      set_point(0, x, y);

      x = Math.ceil(four[1].x / Proportion.value.x);
      y = Math.ceil((config.height - four[1].y) / Proportion.value.y);
      set_point(1, x, y);

      x = Math.ceil(four[2].x / Proportion.value.x);
      y = Math.ceil(
        config.height / Proportion.value.y - four[2].y / Proportion.value.y
      );
      set_point(2, x, y);

      x = Math.ceil(four[3].x / Proportion.value.x);
      y = Math.ceil(
        config.height / Proportion.value.y - four[3].y / Proportion.value.y
      );
      set_point(3, x, y);
    };

    const set_point = (index: number, x: number, y: number) => {
      points[index].x = x;
      points[index].y = y;
      isshowarray.value[index] = false;
      isactivearray.value[index] = false;
      setTimeout(() => {
        isshowarray.value[index] = true;
      }, 100);
    };
    const reset = (index: number) => {
      fourpostion.value[index].x = defaultfourpostion.value[index].x;
      fourpostion.value[index].y = defaultfourpostion.value[index].y;

      four[index].x = config.point4[index].def_x;
      four[index].y = config.point4[index].def_y;

      set?.setBlendingCorrection(
        $store.getters.GetTheCurrentlySelectedCamera[0],
        $store.getters.GetTheCurrentlySelectedCamera[1],
        4,
        index + 1,
        Number(config.point4[index].def_x),
        Number(config.point4[index].def_y)
      );

      isshowarray.value[index] = false;
      setTimeout(() => {
        isshowarray.value[index] = true;
      }, 100);
    };

    const resetall = () => {
      for (let index = 0; index < fourpostion.value.length; index++) {
        reset(index);
      }
    };

    const moveHandler_1 = (data: any) => {
      let x = Math.round(
        (data.left - fourpostion.value[0].x) * Proportion.value.x + 0
      );
      let y = Math.round(
        config.height - data.top * Proportion.value.y - fourpostion.value[0].y
      );

      four[0].x = x > config.width ? config.width : x && x < 0 ? 0 : x;
      four[0].y = y > config.height ? config.height : y && y < 0 ? 0 : y;
      isactivearray.value[0] = true;
      save_set_cache();
    };
    const moveHandler_2 = (data: any) => {
      let x = Math.round(
        (data.left - fourpostion.value[1].x) * Proportion.value.x + config.width
      );
      let y = Math.round(
        config.height - data.top * Proportion.value.y - fourpostion.value[1].y
      );
      four[1].x = x > config.width ? config.width : x && x < 0 ? 0 : x;
      four[1].y = y > config.height ? config.height : y && y < 0 ? 0 : y;
      save_set_cache();
    };
    const moveHandler_3 = (data: any) => {
      let x = Math.round(
        (data.left - fourpostion.value[2].x) * Proportion.value.x
      );
      let y = Math.abs(
        Math.round((data.top - fourpostion.value[2].y) * Proportion.value.y)
      );
      four[2].x = x > config.width ? config.width : x && x < 0 ? 0 : x;
      four[2].y = y > config.height ? config.height : y && y < 0 ? 0 : y;
      save_set_cache();
    };
    const moveHandler_4 = (data: any) => {
      let x = Math.round(
        (data.left - fourpostion.value[3].x) * Proportion.value.x + config.width
      );
      let y = Math.abs(
        Math.round((data.top - fourpostion.value[3].y) * Proportion.value.y)
      );
      four[3].x = x > config.width ? config.width : x && x < 0 ? 0 : x;
      four[3].y = y > config.height ? config.height : y && y < 0 ? 0 : y;
      save_set_cache();
    };
    //窗口变动重新渲染
    onMounted(() => {
      //监听窗口变化
      window.onresize = () => {
        return (() => {
          ste_status.value = 1;
          if (div != null) setpoa();

          setTimeout(() => {
            ste_status.value = 0;
          }, 100);
        })();
      };
    });
    return {
      now_index,
      div,
      fourpostion,
      reset,
      resetall,
      moveHandler_1,
      moveHandler_2,
      moveHandler_3,
      moveHandler_4,
      four,
      save,
      isshowarray,
      isactivearray,
      activeMouseDown,
      mouseUpHandler,
      points,
    };
  },
});
</script>
