<template>
    <div v-if="statisticsVisible" @click="hideStatistics"
         class="kf-statistics-box"
    >
      <div class="kf-statistics-box-item" v-for="item in statistics" :key="item">
        {{ item.key }} {{ item.key && item.value ? ":" : "" }} {{ item.value }} &nbsp;&nbsp;<a v-if="item.showMore != null" @click="item.showMore(item, $event)" src="javascript:return false" style="cursor: pointer; color: #00b8ff">更多</a>
      </div>
    </div>
</template>

<script>
import envModel from '../model/env.js'
import utils from '../utils/utils.js'
import {ref, watch} from "vue";

const statistics = ref([]);

const fetchPageStatistics = function () {
  let stats = [];
  try {
    let w = document.documentElement.clientWidth || document.body.clientWidth;
    let h = document.documentElement.clientHeight || document.body.clientHeight;
    stats.push({key: "时间", value: new Date().toLocaleString()});
    stats.push({key: "网址", value: window.location.href});
    stats.push({key: "系统", value: navigator.userAgent});
    stats.push({key: "桌面分辨率", value: window.screen.width + "*" + window.screen.height});
    stats.push({key: "窗口分辨率", value: w + "*" + h});
    stats.push({key: "缩放", value: utils.getScreenRatio().toFixed(2)});
    stats.push({});
    stats.push({key: "启动时间", value: envModel.startTime.toLocaleString()});
    stats.push({});
    let performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
    stats.push({key: "内存总数", value: Math.floor(window.performance.memory.jsHeapSizeLimit / (1024 * 1024)) + "MB"});
    stats.push({key: "使用内存", value: Math.floor(window.performance.memory.totalJSHeapSize / (1024 * 1024)) + "MB"});
    let memoryRatio = window.performance.memory.totalJSHeapSize / window.performance.memory.jsHeapSizeLimit * 100;
    stats.push({key: "内存比率", value: memoryRatio.toFixed(2) + "%"});

    const connection = window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection;
    if (connection) {
      stats.push({key: "网络类型", value: connection.effectiveType});
      stats.push({key: "估算带宽", value: connection.downlink});
    }
    stats.push({});

    let sceneId;

    if (window.Kc) {
      sceneId = Object.keys(window.Kc).find(key => {
        return key.indexOf("_engine") !== -1 || key.indexOf("_worker") !== -1;
      })
    }

    if (sceneId) {
      stats = stats.concat(fetchSceneStatistics(sceneId.substr(0, sceneId.indexOf("_"))));
    }
    stats.push({})
    stats.push({key: "Ctrl点击下载报告"})
  } catch (e) {
    console.log(e);
  }

  return stats;
}

const fetchSceneStatistics = function (id) {
  let stats = [];
  try {
    let engine = window.Kc[id + "_engine"];
    let scene = window.Kc[id + "_scene"];
    let worker = window.Kc[id + "_worker"];

    if (engine && scene) {
      if (!engine.instrumentation) {
        engine.instrumentation = new Kingfisher.EngineInstrumentation(engine);
        engine.instrumentation.captureGPUFrameTime = true;
      }
      if (!scene.instrumentation) {
        scene.instrumentation = new Kingfisher.SceneInstrumentation(scene);
      }
      let glInfo = engine.getGlInfo();
      let drawCalls = scene.instrumentation.drawCallsCounter;

      stats.push({key: '场景', value: window.Kc[id + "_sceneUrl"]});
      stats.push({key: '帧率', value: engine.getFps().toFixed(1) + 'fps'});
      stats.push({
        key: '耗时',
        value: (engine.instrumentation.gpuFrameTimeCounter.current * 0.000001).toFixed(1) + 'ms'
      });
      stats.push({key: 'DrawCall', value: drawCalls.current});
      stats.push({key: '网格', value: scene.getActiveMeshes().length});
      stats.push({key: '面数', value: (Math.ceil(scene.getActiveIndices() / 3)).toLocaleString()});
      stats.push({});
      stats.push({key: '总网格', value: scene.meshes.filter((x) => !x.designerOnly).length});
      stats.push({key: '总灯光', value: scene.lights.filter((x) => !x.designerOnly).length});
      stats.push({key: '总材质', value: scene.materials.filter((x) => !x.designerOnly).length});
      stats.push({});

      let textureCount = 0;
      let targets = [];
      let text2d = [];
      let images = [];
      let dynamics = [];
      let t0 = 0;
      let t1 = 0;
      let t2 = 0;
      let t3 = 0;

      let textures = scene.textures;
      let temp = {};

      for (let i = 0; i < textures.length; i++) {
        let tex = textures[i];
        if (tex.designerOnly) {
          continue;
        }

        textureCount++;

        if (!tex._texture) {
          continue;
        }

        if (!tex._texture.guid) {
          tex._texture.guid = Kingfisher.getNanoID();
        }
        if (temp[tex._texture.guid]) {
          continue;
        }
        temp[tex._texture.guid] = true;

        let size = tex.getSize();
        let s = size.width * size.height;
        switch (tex.textureFormat) {
          case 0:
          case 1:
          case 6:
            break;
          case 2:
          case 7:
            s *= 2;
            break;
          default:
            s *= 4;
        }
        switch (tex.textureType) {
          case 1:
          case 6:
          case 7:
            s *= 4;
            break;
          case 2:
          case 4:
          case 5:
            s *= 2;
            break;
        }

        if (!tex.noMipmap) {
          s *= 1.3;
        }

        if (tex.isCube) {
          s *= 6;
        }

        if (tex.name === 'text2d') {
          text2d.push(tex);
          t0 += s;
        } else if (tex._texture._source === 5 || tex._texture._source === 6) {
          targets.push(tex);
          t1 += s;
        } else if (tex.url) {
          images.push(tex);
          t2 += s;
        } else {
          dynamics.push(tex);
          t3 += s;
        }
      }

      stats.push({key: '外置贴图', value: images.length + ' (' + (t2 / 1000000).toFixed(1) + 'MB)'});
      // stats.push('内置贴图', value:dynamics.length + ' (' + (t3 / 1000000).toFixed(1) + 'MB)');
      stats.push({key: '离屏缓存', value: targets.length + ' (' + (t1 / 1000000).toFixed(1) + 'MB)'});
      stats.push({key: '2D文字', value: text2d.length + ' (' + (t0 / 1000000).toFixed(1) + 'MB)'});
      stats.push({key: '总贴图', value: textureCount + ' (' + ((t0 + t1 + t2 + t3) / 1000000).toFixed(1) + 'MB)'});
      stats.push({});

      let geometries = scene.geometries;
      let geoCount = 0;
      let g0 = 0;
      for (let i = 0; i < geometries.length; i++) {
        let g = geometries[i];
        if (g.designerOnly) {
          continue;
        }

        geoCount++;
        let vs = g.getVertexBuffers();
        if (!vs) {
          continue;
        }

        let bs = 0;
        for (let key in vs) {
          bs += vs[key].byteStride;
        }

        g0 += bs * g.getTotalVertices();

        let indices = g.getIndexBuffer();
        if (!indices) {
          continue;
        }

        g0 += (indices.is32Bits ? 4 : 2) * g.getTotalIndices();
      }

      stats.push({key: '模型', value: geoCount + ' (' + (g0 / 1000000).toFixed(1) + 'MB)'});
      stats.push({key: '总显存', value: ((t0 + t1 + t2 + t3 + g0) / 1000000).toFixed(1) + 'MB'});
      stats.push({});
      stats.push({key: '画布分辨率', value: engine.getRenderWidth() + "x" + engine.getRenderHeight()});
      stats.push({key: '画布缩放', value: engine.getHardwareScalingLevel().toFixed(1)});
      stats.push({key: '渲染器', value: glInfo.renderer});
      stats.push({key: '渲染器版本', value: glInfo.version});
    } else if (worker) {
      worker.postMessage({method: 'getStatsInfo'});
      stats = (worker.statsInfo || []).map((x) => {
        let key = Object.keys(x)[0];
        if (key !== undefined) {
          return {key: key, value: x[key]};
        }
        return x;
      });
    }
  } catch (e) {
    console.error(e);
  }

  return stats;
}

let updateTimer;

const showStatistics = function () {
  envModel.statisticsVisible.value = true;
}

watch(envModel.statisticsVisible, ()=>{
  if (envModel.statisticsVisible.value) {
    statistics.value = fetchPageStatistics();
    updateTimer = setInterval(() => {
      statistics.value = fetchPageStatistics();
    }, 1000);
  } else {
    clearInterval(updateTimer);
  }
})

const hideStatistics = function () {
  if (window.event.ctrlKey) {
    let date = new Date();
    let fileName = `翠鸟统计数据_${date.getFullYear()}_${date.getMonth() + 1}_${date.getDate()}.json`
    utils.downloadJson(fetchPageStatistics().filter(item => {
      return item.value != null && item.key.indexOf("复制") === -1;
    }), fileName);
  }
  envModel.statisticsVisible.value = false;
}

export default {
  name: "statistics",
  setup() {
    return {
      fetchPageStatistics,
      fetchSceneStatistics,
      showStatistics,
      hideStatistics,
      statisticsVisible : envModel.statisticsVisible,
      statistics
    }
  }
}
</script>

<style>
.kf-statistics-box {
  position: absolute;
  z-index: 999999;
  top: 0;
  left: 0;
  width: calc(100% - 30px);
  height: calc(100% - 30px);
  padding-top: $size-30px;
  padding-left: $size-30px;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  overflow-y: auto;
  overflow-x: hidden;
  margin: 10px;
  font-size: 14px;

  .kf-statistics-box-item {
    width: 100%;
    display: flex;
    height: $size-24px;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    text-shadow: 0 4px 4px rgb(0 0 0 / 25%);
    font-size: $size-12px;
    flex-wrap: nowrap;
    padding: 0;
    margin: 0;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

.kf-statistics-box-item-icon {
  position: absolute;
  right: 10px;
  top: 10px;
  color: #fff;
  background: transparent;
  width: $size-25px;
  height: $size-25px;
  display: flex;
  justify-content: center;
  cursor: pointer;
  align-items: center;
  border-radius: $size-3px;

  &:hover {
    background: $color-btn-default;
  }
}
</style>
