<!--
 * 【界面概述】
 * 展示精灵图的用法，包含动图和切图
 *
 * 【控件介绍】
 * JsvSpriteImg：精灵图控件
 *                  spriteInfo {object}  (必需)精灵图配置信息{frames:[], meta:{}}
 *                  viewSize {object}  (必需){w:0, h:0}
 *                  imageUrl {string}  (必需)图片地址
 *                  duration {float}  (动图必需)动图的时间
 *                  onAnimEnd {fucntion} 动图结束回调
 *                  loop {string} 动图的循环次数 infinite/数字，默认为infinite
 *                  spriteName {string} 动图的名称，默认为null
 *                  autostart{boolean} 是否自动播放动图
 *                  ref 控制动图的对象
 *
 * 【技巧说明】
 * Q: 动图和切图如何实现?
 * A: spriteInfo中的frame有多个时为动图，只有一个时为切图
 *
 * Q: spriteInfo中属性的含义?
 * A: meta.size为整张切图的大小；frames中为每一帧的位置和大小信息，目前仅支持统一大小的帧
 -->

<script setup>
import {
  JsvSpriteAnim,
  JsvSpriteLoader,
  JsvSpriteStatic,
  JsvSpriteTools,
} from "jsview";
import localSpriteImage from "./images/egg_break.png";
import localConfigJson from "./images/egg_break.json";
import { shallowRef, watchEffect } from "vue";
import { useRouter } from "vue-router";

console.log(
  "test localSpriteImage =",
  localSpriteImage,
  "/n localConfigJson=",
  localConfigJson
);
const router = useRouter();
let useLocalData = shallowRef(true);
let animateImage = shallowRef(null);
let preloadJsonUrl = shallowRef(null);
let preloadCallback = shallowRef(null);
let spriteJsonInfo = shallowRef(null);
let spriteOriginSize = shallowRef(null);
let spriteStaticJsonInfo1 = shallowRef(null);
let spriteStaticJsonInfo2 = shallowRef(null);
let spriteStaticJsonInfo3 = shallowRef(null);

const _UseLocalData = () => {
  console.log("using local data");
  useLocalData.value = true;
  animateImage.value = `url(${localSpriteImage})`;
  preloadJsonUrl.value = null;
  preloadCallback.value = null;
  spriteJsonInfo.value = _formatInfo(localConfigJson).info;
  _applyStaticInfo(spriteJsonInfo.value, currentStatiIndex);

  // 调整设置的原图尺寸设置
  const guessSize = JsvSpriteTools.guessOriginSize(spriteJsonInfo.value);
  spriteOriginSize.value = guessSize;
};

const _UseRemoteData = () => {
  const testRemoteImageUrl = "http://192.168.2.179:8077/images/egg_break.png";
  const testRemoteConfigUrl = "http://192.168.2.179:8077/images/egg_break.json";

  useLocalData.value = false;
  animateImage.value = testRemoteImageUrl;
  preloadJsonUrl.value = testRemoteConfigUrl;
  preloadCallback.value = (config_json, resolve_set) => {
    spriteJsonInfo.value = _formatInfo(config_json).info;
    _applyStaticInfo(spriteJsonInfo.value, currentStatiIndex);

    // 调整设置的原图尺寸设置
    const guessSize = JsvSpriteTools.guessOriginSize(spriteJsonInfo.value);
    spriteOriginSize.value = guessSize;

    resolve_set(); // 通知loader数组设置完成
  };
};

const _formatInfo = (config_json) => {
  const info = {
    frames: [],
    meta: {
      size: config_json.meta.size,
    },
  };

  let frames_ref = info.frames;

  for (let i = 0; i < config_json.frames.length; i++) {
    const target = config_json.frames[i].spriteSourceSize;
    frames_ref.push({
      target,
      source: config_json.frames[i].frame,
    });
  }

  return { info };
};

const _applyStaticInfo = (wholeJsonInfo, index) => {
  let length = wholeJsonInfo.frames.length;
  // 设置第一张静图
  let useIndex = index % length;
  spriteStaticJsonInfo1.value = {
    frames: [wholeJsonInfo.frames[useIndex]],
    meta: {
      size: wholeJsonInfo.meta.size,
    },
  };

  // 设置第二张静图
  useIndex = (index + 1) % length;
  spriteStaticJsonInfo2.value = {
    frames: [wholeJsonInfo.frames[useIndex]],
    meta: {
      size: wholeJsonInfo.meta.size,
    },
  };

  // 设置第三张静图
  useIndex = (index + 2) % length;
  spriteStaticJsonInfo3.value = {
    frames: [wholeJsonInfo.frames[useIndex]],
    meta: {
      size: wholeJsonInfo.meta.size,
    },
  };
};

let staticFromIndex = shallowRef(0);
let currentStatiIndex = 0;
watchEffect(() => {
  if (staticFromIndex.value != currentStatiIndex) {
    currentStatiIndex = staticFromIndex.value;
    if (spriteJsonInfo.value != null) {
      _applyStaticInfo(spriteJsonInfo.value, currentStatiIndex);
    }
  }
});

const spriteController = shallowRef(null);

let show = shallowRef(true);

const spriteAnimEnd = () => {
  show.value = false;
};
const onKeyDown = (ev) => {
  if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
    router?.go(-1); // 有router时，是从DemoHomepage进入，回退
    return true;
  } else if (ev.keyCode == 13) {
    // 静态引用信息变化
    staticFromIndex.value++;
  }
  return true;
};

_UseLocalData();
// TODO: 当需要测试远程数据时打开
// setTimeout(() => {
//   _UseRemoteData();
// }, 2000);
</script>

<template>
  <jsv-focus-block
    autoFocus
    :onAction="{
      onKeyDown: onKeyDown,
    }"
  >
    <div class="bgStyle" />

    <!-- 静态精灵图测试 -->
    <div
      :style="{
        textAlign: 'center',
        fontSize: 30,
        lineHeight: 50,
        color: '#ffffff',
        left: 100,
        top: 75,
        width: 280,
        height: 100,
        backgroundColor: 'rgba(27,38,151,0.8)',
      }"
    >
      {{ "精灵图效果(静态)\nOK键切换图组" }}
    </div>
    <JsvSpriteLoader
      :imageUrl="animateImage"
      :configUrl="preloadJsonUrl"
      :noNeedResource="useLocalData"
    >
      <div :style="{ left: 140, top: 175 }">
        <JsvSpriteStatic
          :spriteInfo="spriteStaticJsonInfo1"
          :viewSize="{ w: 200 }"
          :spriteFrameSize="spriteOriginSize"
          :imageUrl="animateImage"
        />
      </div>
      <div :style="{ left: 140, top: 325 }">
        <JsvSpriteStatic
          :spriteInfo="spriteStaticJsonInfo2"
          :viewSize="{ w: 200 }"
          :spriteFrameSize="spriteOriginSize"
          :imageUrl="animateImage"
        />
      </div>
      <div :style="{ left: 140, top: 505 }">
        <JsvSpriteStatic
          :spriteInfo="spriteStaticJsonInfo3"
          :viewSize="{ w: 200 }"
          :spriteFrameSize="spriteOriginSize"
          :imageUrl="animateImage"
        />
      </div>
    </JsvSpriteLoader>

    <!-- 动态精灵图测试 -->
    <div
      :style="{
        textAlign: 'center',
        fontSize: 30,
        lineHeight: 50,
        color: '#ffffff',
        left: 460,
        top: 100,
        width: 280,
        height: 50,
        backgroundColor: 'rgba(27,38,151,0.8)',
      }"
    >
      精灵图效果(动态)
    </div>
    <!--
                通过show进行 清理精灵图，用于验证精灵图清理后，StyleSheet中cssRules的keyFrame清理工作能正常完成
            -->
    <div v-show="show" :style="{ left: 460, top: 150 }">
      <JsvSpriteLoader
        :imageUrl="animateImage"
        :configUrl="preloadJsonUrl"
        :onConfigReady="preloadCallback"
        :noNeedResource="useLocalData"
      >
        <JsvSpriteAnim
          ref="spriteController"
          :spriteInfo="spriteJsonInfo"
          :loop="3"
          :duration="0.8"
          :viewSize="{ w: 280 }"
          :spriteFrameSize="spriteOriginSize"
          :autostart="true"
          :onAnimEnd="spriteAnimEnd"
          :imageUrl="animateImage"
        />
      </JsvSpriteLoader>
    </div>

    <div
      :style="{
        textAlign: 'center',
        fontSize: 30,
        lineHeight: 50,
        color: '#ffffff',
        left: 800,
        top: 100,
        width: 434,
        height: 50,
        backgroundColor: 'rgba(27,38,151,0.8)',
      }"
    >
      原始图片
    </div>
    <div
      :style="{
        left: 800,
        top: 150,
        width: 434,
        height: 372,
        backgroundImage: animateImage,
      }"
    />
  </jsv-focus-block>
</template>

<style scoped>
.bgStyle {
  width: 1280;
  height: 720;
  background-color: #4d5e8c;
}
</style>
