<template>
  <div
    ref="wall"
    class="fit items-center justify-evenly wall"
    @dragenter="onDragEnter"
    @dragleave="onDragLeave"
    @dragover="onDragOver"
    @drop="onDrop"
  >
    <q-popup-proxy context-menu>
      <q-popup-proxy context-menu />
      <q-list>
        <q-item clickable v-close-popup>
          <q-item-section avatar>
            <q-icon name="close" color="red" />
          </q-item-section>
          <q-item-section> {{ $t("close all windwos") }} </q-item-section>
        </q-item>
      </q-list>
    </q-popup-proxy>
    <div id="windows" style="position: absolute">
      <div
        :ref="'window_' + index"
        v-for="(item, index) in windows"
        :key="index"
        class="window"
        :style="{
          top: item.y / wall_height_scaler + 'px',
          left: item.x / wall_width_scaler + 'px',
          width: item.width / wall_width_scaler + 'px',
          height: item.height / wall_height_scaler + 'px',
        }"
      >
        {{ wall_height_scaler }}
        {{ wall_width_scaler }}
      </div>
    </div>
    <div ref="wall_grids">
      <div
        v-for="row in wall_rows"
        :key="row"
        class="row"
        :style="{
          height: item_height + 'px',
        }"
      >
        <div
          :ref="'item' + (row - 1) * wall_cols * col"
          v-for="col in wall_cols"
          :key="col"
          class="col wall_item"
          :style="{
            width: item_witdh + 'px',
            height: item_height + 'px',
          }"
          @resize="(evt) => loga(evt)"
        >
          <q-popup-proxy context-menu no-parent-event>
            <q-popup-proxy context-menu />
            <q-list>
              <q-item clickable v-close-popup>
                <q-item-section avatar>
                  <q-icon name="close" color="red" />
                </q-item-section>
                <q-item-section> {{ $t("close this windwo") }} </q-item-section>
              </q-item>
              <q-item clickable v-close-popup>
                <q-item-section avatar>
                  <q-icon name="close" color="red" />
                </q-item-section>
                <q-item-section>
                  {{ $t("close other windwos") }}
                </q-item-section>
              </q-item>
              <q-item clickable v-close-popup>
                <q-item-section avatar>
                  <q-icon name="close" color="red" />
                </q-item-section>
                <q-item-section> {{ $t("close all windwos") }} </q-item-section>
              </q-item>
            </q-list>
          </q-popup-proxy>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.wall {
  border: 1px solid black;
}

.wall_item {
  border: 1px solid black;
}

.window {
  border: 1px solid rebeccapurple;
  position: absolute;
}
</style>

<script lang="ts">
import GlobalData from "src/common/GlobalData";
import { defineComponent, ref, Ref, computed, watch, onMounted } from "vue";
import { Common } from "src/common/Common";
import { Protocol } from "src/entities/WSProtocol";

import { useI18n } from "vue-i18n";
import { useStore } from "src/store";
import EventBus from "src/common/EventBus";

interface _OptionsType {
  $t: any;
  $store: ReturnType<typeof useStore> | undefined | null;
}

const _getSignalSources = async () => {
  const global_data = GlobalData.getInstance();
  return (await global_data
    .getCurrentClient()
    ?.getSignalSources()) as Protocol.GetSignalSourcesResponse;
};

const _initSignalSourceTree = async (options: _OptionsType) => {
  const $store = options?.$store;
  if ($store) {
    try {
      let response = await _getSignalSources();
      if (response) {
        $store.commit("buildSignalSourceTree", { options, response });
        GlobalData.getInstance().signal_source = response.signal_sources;
      }
    } catch (e) {
      console.error(e);
    }
  }
};

const _getApplicationConfig = async (options: _OptionsType) => {
  const global_data = GlobalData.getInstance();
  global_data.applicationConfig = (
    await global_data.getCurrentClient()?.getApplicationSettins()
  )?.config;

  let $store = options.$store;
  if (global_data.applicationConfig && $store) {
    $store.commit("setWallCol", global_data.applicationConfig.wall_col);
    $store.commit("setWallRow", global_data.applicationConfig.wall_row);
    $store.commit(
      "setDeviceScreenWidth",
      global_data.applicationConfig.screen_width
    );
    $store.commit(
      "setDeviceScreenHeight",
      global_data.applicationConfig.screen_height
    );
  }
};

const _getWindows = async (options: _OptionsType) => {
  const global_data = GlobalData.getInstance();
  let windows = (await global_data.getCurrentClient()?.getWindows())?.windows;
  let $store = options.$store;
  if (windows && $store) {
    $store.commit("setWindows", windows);
  }
};

const _initialize = async (options: _OptionsType) => {
  const global_data = GlobalData.getInstance();
  let client = global_data.getCurrentClient();
  if (client) {
    while (!client.is_login) {
      await Common.waitFor(100);
    }

    _initSignalSourceTree(options).then(() => {
      _getWindows(options);
    });
    _getApplicationConfig(options);
  }
};

export default defineComponent({
  name: "PageWall",

  components: {},

  setup() {
    const $store = useStore();
    const $t = useI18n();
    _initialize({
      $t,
      $store,
    });

    const windows = computed({
      get: () => $store.state.windows,
      set: (val) => $store.commit("setWindows", val),
    });

    const wall_rows = computed({
      get: () => $store.state.wall_row,
      set: (val) => $store.commit("setWallRow", val),
    });

    const wall_cols = computed({
      get: () => $store.state.wall_col,
      set: (val) => $store.commit("setWallCol", val),
    });

    const wall: Ref<HTMLElement | null> = ref(null);

    const item_witdh = computed({
      get: () => {
        if (wall.value && wall.value.parentElement) {
          return wall.value.parentElement.offsetWidth / wall_cols.value;
        }
        return 0;
      },
      set: (val) => $store.commit("setWallCol", val),
    });

    const item_height = computed({
      get: () => {
        if (wall.value && wall.value.parentElement) {
          const wv_scaler =
            $store.state.device_screen_width /
            $store.state.device_screen_height;

          return (
            wall.value.parentElement.offsetHeight / wv_scaler / wall_rows.value
          );
        }
        return 0;
      },
      set: (val) => $store.commit("setWallCol", val),
    });

    const wall_width_scaler = ref(0);
    const wall_height_scaler = ref(0);

    const calcWallVWScaler = () => {
      if (wall.value && wall.value.parentElement) {
        wall_height_scaler.value =
          $store.state.device_screen_height /
          (item_height.value * wall_rows.value);
        wall_width_scaler.value =
          $store.state.device_screen_width /
          wall.value.parentElement.offsetWidth;

        wall_height_scaler.value += 0.1;
        wall_width_scaler.value += 0.05;
      }
    };

    EventBus.getInstance().on("windowResize", () => {
      calcWallVWScaler();
    });

    onMounted(() => {
      calcWallVWScaler();
    });

    return {
      windows,
      wall,
      wall_rows,
      wall_cols,
      item_witdh,
      item_height,
      wall_width_scaler,
      wall_height_scaler,
      loga(a: any) {
        console.log(a);
      },
      onDrop(e: DragEvent) {
        e.preventDefault();
        let target = e.target as any;
        if (target) {
          target.classList.remove("drag-enter");
        }

        let uuid = e.dataTransfer?.getData("uuid");
        if (uuid) {
          let signal_sources = GlobalData.getInstance().signal_source.filter(
            (item) => (item as any)?.uuid == uuid
          );

          if (signal_sources.length) {
            let signal_source = signal_sources[0];
            console.log(signal_source);
          }
        }
      },

      onDragEnter(e: DragEvent) {
        let target = e.target as any;
        if (target && target.draggable !== true) {
          target.classList.add("drag-enter");
        }
      },

      onDragLeave(e: DragEvent) {
        let target = e.target as any;
        if (target) {
          target.classList.remove("drag-enter");
        }
      },

      onDragOver(e: DragEvent) {
        e.preventDefault();
      },
    };
  },
});
</script>
