<template>
  <ui-editor-toolbar toolbar class="animation-toolbar">
    <div class="top-bar">
      <div class="play-bar">
        <ui-icon type="close" ctrl @click="play = !play" />
      </div>
      <div class="scale-bar">
        <ui-icon type="close" class="icon" ctrl />
        <Slider
          class="slider"
          v-model:value="scale"
          :min="0.5"
          :max="8"
          :step="0.01"
          :tooltipOpen="false"
        />
        <ui-icon type="close" class="icon" ctrl />
      </div>
    </div>
    <div class="oper-bar" :class="{ disabled: play }">
      <Renderer v-model:scale="scale">
        <TimeLine
          v-for="prop in tlProps"
          :items="am[prop.attr]"
          :height="prop.height"
          :top="prop.top"
          :itemsRenderer="prop.component"
          @update="({ ndx, time }) => (am[prop.attr][ndx].time = time)"
          @add="
            (item) => {
              am[prop.attr].push(item);
              $emit('update:active', { key: prop.attr, ndx: am[prop.attr].length - 1 });
            }
          "
          @del="(ndx) => am[prop.attr].splice(ndx, 1)"
          :active="prop.attr === active?.key ? am[prop.attr][active.ndx] : undefined"
          @update:active="(active: any) => $emit('update:active', active && { key: prop.attr, ndx: am[prop.attr].indexOf(active) })"
        />

        <Time @update-current-time="(time) => $emit('update:currentTime', time)">
          <TimeCurrent
            :currentTime="currentTime"
            @update:current-time="(time) => $emit('update:currentTime', time)"
            :follow="play"
          />
        </Time>
      </Renderer>
    </div>
  </ui-editor-toolbar>
</template>

<script lang="ts" setup>
import { Slider } from "ant-design-vue";
import { ref, watch } from "vue";
import { AnimationModel } from "@/store/animation";
import Renderer from "@/components/drawing/renderer.vue";
import Time from "@/components/drawing-time/time.vue";
import TimeCurrent from "@/components/drawing-time/current.vue";
import TimeLine from "@/components/drawing-time-line/index.vue";
import TimeLineFrame from "@/components/drawing-time-line/frame.vue";
import TimeLineAction from "@/components/drawing-time-line/action.vue";
import { Active } from "./type";

const props = defineProps<{ am: AnimationModel; active?: Active; currentTime: number }>();
const emit = defineEmits<{
  (e: "update:active", data: Active | undefined): void;
  (e: "update:currentTime", v: number): void;
}>();

const scale = ref(1);

const tlProps = [
  { attr: "frames", component: TimeLineFrame, height: 30, top: 24 },
  { attr: "actions", component: TimeLineAction, height: 30, top: 65 },
  { attr: "subtitles", component: TimeLineAction, height: 30, top: 105 },
  { attr: "paths", component: TimeLineAction, height: 30, top: 140 },
] as const;

const play = ref(false);

watch(play, (_a, _b, onCleanup) => {
  let isDes = false;
  let prevNow = Date.now();
  const animation = () => {
    if (play.value && !isDes) {
      const curNow = Date.now();
      emit("update:currentTime", props.currentTime + (curNow - prevNow) * 0.001);
      prevNow = curNow;
      requestAnimationFrame(animation);
    }
  };
  animation();
  onCleanup(() => (isDes = true));
});
</script>

<style scoped lang="scss">
.top-bar {
  display: flex;
  height: 40px;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
  .play-bar {
    flex: 1;
    display: flex;
    justify-content: center;
  }
  .scale-bar {
    width: 180px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    padding: 0 20px;
    position: relative;
    &::before {
      content: "";
      position: absolute;
      left: 0;
      width: 1px;
      height: 16px;
      background: rgba(255, 255, 255, 0.16);
    }

    .slider {
      flex: 1;
    }
    .icon {
      margin: 0 5px;
    }
  }
}
.oper-bar {
  height: calc(100% - 40px);
}
</style>
