<script setup lang="ts">
import backgroundPatternImage from '~/assets/background_pattern.png';
import circleBaseImage from '~/assets/bg_common_circlebase.png';
import circleLineImage from '~/assets/bg_common_circleline.png';

const background = ref<HTMLCanvasElement | null>(null);
const width = ref<number>(window.innerWidth);
const height = ref<number>(window.innerHeight);
const backgroundCtx = ref<CanvasRenderingContext2D | null>(null);
const imageAsset = reactive<{
  loadCompleteNumber: number,
  backgroundPattern: {
    image: HTMLImageElement | CanvasImageSource | null,
    canvas: HTMLCanvasElement | null,
    context: CanvasRenderingContext2D | null
  },
  circleBase: {
    image: HTMLImageElement | CanvasImageSource | null,
    width: number,
    height: number
  },
  circleLine: {
    image: HTMLImageElement | CanvasImageSource | null,
    width: number,
    height: number,
    canvas: HTMLCanvasElement | null,
    context: CanvasRenderingContext2D | null
  }
}>({
  loadCompleteNumber: 0,
  backgroundPattern: {
    image: null,
    canvas: null,
    context: null
  },
  circleBase: {
    image: null,
    width: 260,
    height: 260
  },
  circleLine: {
    image: null,
    width: 260,
    height: 260,
    canvas: null,
    context: null
  }
});

const initializeBackgroundAssets = () => {
  backgroundCtx.value = (background.value?.getContext('2d') as CanvasRenderingContext2D);
  imageAsset.backgroundPattern.canvas = document.createElement('canvas');
  imageAsset.backgroundPattern.context = imageAsset.backgroundPattern.canvas.getContext('2d');
  imageAsset.circleLine.canvas = document.createElement('canvas');
  imageAsset.circleLine.context = imageAsset.circleLine.canvas.getContext('2d');
  (imageAsset.backgroundPattern.image! as HTMLImageElement).onload = () => {
    initializeBackgroundPatternCanvas();
    imageAsset.loadCompleteNumber += 1;
  };
  (imageAsset.circleBase.image! as HTMLImageElement).onload = () => {
    imageAsset.loadCompleteNumber += 1;
  };
  (imageAsset.circleLine.image! as HTMLImageElement).onload = () => {
    imageAsset.circleLine.canvas!.width = imageAsset.circleLine.width;
    imageAsset.circleLine.canvas!.height = imageAsset.circleLine.height;
    imageAsset.loadCompleteNumber += 1;
  };
};
const initializeBackgroundPatternCanvas = () => {
  imageAsset.backgroundPattern.context?.clearRect(0, 0, width.value, height.value);
  imageAsset.backgroundPattern.canvas!.width = width.value + 268;
  imageAsset.backgroundPattern.canvas!.height = height.value + 200;
  imageAsset.backgroundPattern.context!.fillStyle = (imageAsset.backgroundPattern.context?.createPattern(
    imageAsset.backgroundPattern.image!, 'repeat'
  ) as CanvasPattern);
  imageAsset.backgroundPattern.context?.fillRect(
    0, 0, imageAsset.backgroundPattern.canvas!.width, imageAsset.backgroundPattern.canvas!.height);
};
const drawBackgroundLoop = () => {
  const currentTime = new Date().getTime();
  const patternPositionPercent = (currentTime % 14000) / 14000;
  const circlePositionPercent = (currentTime % 40000) / 40000;
  const patternOffset = {
    x: -267 + patternPositionPercent * 267,
    y: -patternPositionPercent * 200
  };
  backgroundCtx.value?.clearRect(0, 0, width.value, height.value);
  imageAsset.circleLine.context?.clearRect(0, 0, imageAsset.circleLine.canvas!.width, imageAsset.circleLine.canvas!.height);
  backgroundCtx.value?.drawImage(imageAsset.backgroundPattern.canvas!, patternOffset.x, patternOffset.y);
  backgroundCtx.value?.drawImage(
    imageAsset.circleBase.image!,
    (width.value - imageAsset.circleBase.width) / 2,
    (height.value - imageAsset.circleBase.height) / 2,
    imageAsset.circleBase.width, imageAsset.circleBase.height
  );
  imageAsset.circleLine.context?.translate(
    imageAsset.circleLine.canvas!.width / 2,
    imageAsset.circleLine.canvas!.height / 2
  );
  imageAsset.circleLine.context?.rotate(circlePositionPercent * 2 * Math.PI);
  imageAsset.circleLine.context?.drawImage(
    imageAsset.circleLine.image!,
    -imageAsset.circleLine.width / 2,
    -imageAsset.circleLine.height / 2,
    imageAsset.circleLine.width, imageAsset.circleLine.height
  );
  imageAsset.circleLine.context?.rotate(-circlePositionPercent * 2 * Math.PI);
  imageAsset.circleLine.context?.translate(
    -imageAsset.circleLine.canvas!.width / 2,
    -imageAsset.circleLine.canvas!.height / 2
  );
  backgroundCtx.value?.drawImage(
    imageAsset.circleLine.canvas!,
    (width.value - imageAsset.circleLine.canvas!.width) / 2,
    (height.value - imageAsset.circleLine.canvas!.height) / 2
  );
  requestAnimationFrame(drawBackgroundLoop);
};

watch(() => imageAsset.loadCompleteNumber, (newVal) => {
  if (newVal === 3) {
    drawBackgroundLoop();
  }
});

onMounted(() => {
  imageAsset.backgroundPattern.image = new Image();
  imageAsset.backgroundPattern.image.src = backgroundPatternImage;
  imageAsset.circleBase.image = new Image();
  imageAsset.circleBase.image.src = circleBaseImage;
  imageAsset.circleLine.image = new Image();
  imageAsset.circleLine.image.src = circleLineImage;
  initializeBackgroundAssets();
  window.onresize = () => {
    width.value = window.innerWidth;
    height.value = window.innerHeight;
    initializeBackgroundPatternCanvas();
  };
});
</script>

<template>
  <canvas id="background" ref="background" :width="width" :height="height" />
</template>

<style scoped>
#background {
  position: fixed;
  z-index: -1000;
  top: 0;
  left: 0;
}
</style>