<template>
  <div class="row">
    <div class="col-1"></div>
    <div class="col-10 q-pt-md">
      <div ref="div" style="width: 100%; background-color: #646464; height: 40vh">
        <div style="position: absolute">
          <Vue3DraggableResizable :class="[options_model == index ? 'action' : 'point']"
            v-for="(item, index) in value_point.length" :initW="point.w"  :adsorbParent="false" :initH="point.h" :resizable="false"
            v-model:x="value_point[index].x" v-model:y="value_point[index].y" @activated="options_model = index"
            @click="options_model = index" @dragging="dragStartHandle($event, index)">
            <span>{{
              index+ 1
            }}</span>
          </Vue3DraggableResizable>
        </div>
      </div>
    </div>
  </div>
  <div>
    <div class="row">
      <div class="col-1"></div>
      <div class="col-2 q-px-md"> <q-select class="q-pt-md" :label="$t('point')" :dense="true" filled
          v-model="options_model" @update:model-value="(val) => { options_model = val }" :options="options" emit-value
          map-options /></div>
      <div class="col-2 q-px-md"> <q-input filled type="number" class="q-pt-md" :dense="true"
          v-model="value[options_model].x" @update:model-value="chang(options_model, $event, 'h')" label="x"
          lazy-rules />

      </div>
      <div class="col-2 q-px-md"> <q-input filled type="number" class="q-pt-md" :dense="true"
          v-model="value[options_model].y" @update:model-value="chang(options_model, $event, 'h')" label="y"
          lazy-rules /></div>
      <div class="q-pt-md col-2">
        <q-btn color="white" @click="reset(options_model, true, 'h')" text-color="black" :label="$t('reset')" />
      </div>
      <div class="col-2 q-pt-md">
        <div><q-btn color="white" @click="resetall" text-color="black" :label="$t('resetall')" /></div>
      </div>
    </div>

  </div>
</template>

<style scoped>
.action {
  background-color: rgb(27, 180, 111);
  border-radius: 50%;
}

.point {
  background-color: rgb(186, 245, 245);
  border-radius: 50%;
}
</style>

<script lang="ts">
import {
  defineComponent,
  onMounted,
  ref,
  computed,
  watch,
  nextTick,
  onBeforeUnmount,
  defineExpose
} from "vue";
import { useStore } from "src/store";
import { useI18n } from "vue-i18n";
import Vue3DraggableResizable from 'vue3-draggable-resizable'
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'


import DensityCorrection from "src/entities/DensityCorrection";
import DensityCorrectionPoint from "src/entities/DensityCorrectionPoint";
import { config } from "process";
import { QSelect, QInput, QBtn } from "quasar";
import { div } from "zrender/lib/core/vector";
import GlobalData from "src/common/GlobalData";
import { number } from "@intlify/core-base";

export default defineComponent({
  name: "ComponentDensityCorrection",
  components: {
    Vue3DraggableResizable
  },
  setup() {
    let set = GlobalData.getInstance().getCurrentClient();
    let $store = useStore();
    let $t = useI18n();
    const ste_status = ref(0);
    let allconfig = JSON.parse($store.state.fusion_configuration);
    let config = JSON.parse($store.state.fusion_configuration).projectors[0];
    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 value_point_amount = ref(5)


    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 use_server_config = () => {
      value.value = []
      value_point.value = []
      for (let index = 0; index < config.point4.length; index++) {
        let tmp: DensityCorrectionPoint = config.point4[index];
        value.value.push(tmp)
        let x_y = coordinate_transformation_value_to_xy(tmp.x, tmp.y)
        let def_x_f = coordinate_transformation_value_to_xy(tmp.def_x, tmp.def_y)
        let tmp_point: DensityCorrectionPoint = {
          control_point: tmp.control_point,
          x: x_y.x,
          y: x_y.y,
          def_x: def_x_f.x,
          def_y: def_x_f.y
        }
        value_point.value.push(tmp_point)
      }
    }

    const use_set_cache = () => {
      if (set_cache.value[selectedprojector.value] != null) {
        let tmp = JSON.parse(set_cache.value[selectedprojector.value]);
        deepcopy(value.value, tmp.value)
        deepcopy(value_point.value, tmp.value_point)
        recalculate_coordinates()
      }
    }

    const save_set_cache = () => {
      let tmp = { value: value.value, value_point: value_point.value }
      set_cache.value[selectedprojector.value] = JSON.stringify(tmp);
    }

    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);
      },
      { deep: true }
    );



    const set_cache: any = ref([]);
    //值
    let value = ref(<DensityCorrection[]>[]);
    //位置
    let value_point = ref(<DensityCorrectionPoint[]>[]);
    /**
     * 当前选中的点的索引
     */
    const options_model = ref(0)

    const div = ref();
    const max = ref({ x: 0, y: 0 })
    const point = ref({ w: 20, h: 20 })

    watch(() => options_model, (newval, oldval) => {
      set?.SetBlendingOption("blending_grids_select_point", `4:${options_model.value + 1}`)
    }, { deep: true })

    /**
     * 分辨率和页面的比例
     */
    let Proportion = ref({ x: 100, y: 1000 });
    nextTick(() => {
      max.value.x = div.value.offsetWidth
      max.value.y = div.value.offsetHeight
    })

    const options = computed(() => {
      let tmp = []
      for (let index = 0; index < value_point.value.length; index++) {
        tmp.push({
          label: `${index + 1}`,
          value: index,
        })
      }
      return tmp
    })

    const chang_point_amount = (val: number) => {
      start_point()
    }

    const dragStartHandle = ($event: any, index: number) => {
      let obj_x = $event.x
      let obj_y = $event.y
      let tmp = coordinate_transformation_xy_to_value(obj_x, obj_y)
      value.value[index].x = Math.round(tmp.x)
      value.value[index].y = Math.round(tmp.y)
      send_value(index, Math.round(tmp.x), Math.round(tmp.y))
      save_set_cache()
    }

    const chang = (index: number, $event: any, type: string) => {
      index = Number(index)
      let tmp = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y)
      value_point.value[index].y = Math.round(tmp.y)
      value_point.value[index].x = Math.round(tmp.x)
      send_value(index, Math.round(value.value[index].x), Math.round(value.value[index].y))

      save_set_cache()
    }

    /**
     * 将分辨率的坐标转换为 页面的坐标
     * @param x x坐标
     * @param y y坐标
     */
    const coordinate_transformation_value_to_xy = (x: number, y: number): { x: number, y: number } => {
      x = x / Proportion.value.x
      y = (allconfig.projector_height - y) / Proportion.value.y
      return { x, y }
    }


    /**
     * 将页面的坐标转换为 分辨率的坐标
     * @param x x坐标
     * @param y y坐标
     */
    const coordinate_transformation_xy_to_value = (x: number, y: number): { x: number, y: number } => {
      x = (x + point.value.w / 14) * Proportion.value.x
      // x = (x-point.value.w) * Proportion.value.x
      y = (max.value.y - (y + point.value.h)) * Proportion.value.y
      return { x, y }
    }

    const start_point = () => {
      value.value = []
      value_point.value = []
      for (let index = 0; index < config.point4.length; index++) {
        let tmp: DensityCorrectionPoint = config.point4[index];
        value.value.push(tmp)
        let x_y = coordinate_transformation_value_to_xy(tmp.x, tmp.y)
        let def_x_f = coordinate_transformation_value_to_xy(tmp.def_x, tmp.def_y)
        let tmp_point: DensityCorrectionPoint = {
          control_point: tmp.control_point,
          x: x_y.x,
          y: x_y.y,
          def_x: def_x_f.x,
          def_y: def_x_f.y
        }
        value_point.value.push(tmp_point)
      }
    }

    /**
     * 创建空值 让dom先渲染
     */
    const start = () => {
      let tmp: DensityCorrectionPoint = { control_point: 0, x: 0, y: 0, def_x: 0, def_y: 0 };
      value.value.push(tmp)
      value_point.value.push(tmp)
    }
    start()
    onMounted(() => {
      Proportion.value.x = allconfig.projector_width / (div.value.offsetWidth - point.value.w)
      Proportion.value.y = allconfig.projector_height / (div.value.offsetHeight - point.value.h)
      start_point()
      start()
      use_server_config()
      if (
        sessionStorage.FourPointCalibration &&
        sessionStorage.FourPointCalibration.length > 0
      ) {
        set_cache.value = JSON.parse(sessionStorage.FourPointCalibration);
        use_set_cache();
      }
      window.onresize = () => {
        return (() => {
          if (div != null) {
            recalculate_coordinates()
          }
        })();
      };
    })

    onBeforeUnmount(() => {
      sessionStorage.FourPointCalibration = JSON.stringify(set_cache.value);
    });

    const reset = (index: number, send: boolean, type: string) => {
      value.value[index].x = value.value[index].def_x
      value.value[index].y = value.value[index].def_y
      chang(index, value.value[index].def_y, type)
      save_set_cache()
    }
    const send_value = (index: number, x: number, y: number) => {
      let row = $store.getters.GetTheCurrentlySelectedCamera[0]
      let col = $store.getters.GetTheCurrentlySelectedCamera[1]
      set?.setBlendingCorrection(row, col, 4, value_point.value.length, index + 1, Number(x), Number(y));
    }
    const resetall = () => {
      for (let index = 0; index < value_point.value.length; index++) {
        value.value[index].x = value.value[index].def_x
      value.value[index].y = value.value[index].def_y
      let tmp = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y)
      value_point.value[index].y = Math.round(tmp.y)
      value_point.value[index].x = Math.round(tmp.x)
      }
      send_value(-2,0,0)
    }
    const recalculate_coordinates = () => {
      try {
        Proportion.value.x = allconfig.projector_width / (div.value.offsetWidth - point.value.w)
        Proportion.value.y = allconfig.projector_height / (div.value.offsetHeight - point.value.h)
        max.value.x = div.value.offsetWidth
        max.value.y = div.value.offsetHeight
        for (let index = 0; index < value.value.length; index++) {
          let x_y = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y)
          let def_x_y = coordinate_transformation_value_to_xy(value.value[index].def_x, value.value[index].def_x)
          value_point.value[index].x = x_y.x
          value_point.value[index].y = x_y.y
          value_point.value[index].def_x = def_x_y.x
          value_point.value[index].def_y = def_x_y.y
        }
      } catch (error) {

      }
    }
    defineExpose({
      options_model,
    });
    return {
      resetall,
      div,
      max,
      point,
      options_model,
      value,
      value_point,
      dragStartHandle,
      chang,
      reset,
      value_point_amount,
      chang_point_amount,
      options
    }
  }
})

</script>
