<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { BLOCK_SIZE, STAGE_WIDTH, STAGE_HEIGHT } from './level/def'
import createLevel from './level'

import useTime from './util/useTime'
import useInput from './util/useInput'
import usePlayer from './util/usePlayer'

const { updateTime, timeOfDay, clock } = useTime()
const { player, direction, dx, dy } = usePlayer()
const { inputX, inputY, digging, paused } = useInput(player)
const level = createLevel(STAGE_WIDTH + 2, STAGE_HEIGHT + 2)

let animationFrame = 0
let lastTick = 0

let x = ref(0)
let y = ref(12)
const floorX = computed(() => Math.floor(x.value))
const floorY = computed(() => Math.floor(y.value))
const tx = computed(() => (x.value - floorX.value) * -BLOCK_SIZE)
const ty = computed(() => (y.value - floorY.value) * -BLOCK_SIZE)
const rows = computed(() => level.grid(floorX.value, floorY.value))

// TODO: mock
const blocked = {
  left: false,
  right: false,
  up: false,
  down: false,
}

function dig() {
  console.warn('digging not yet implemented')
}

function move(thisTick) {
  animationFrame = requestAnimationFrame(move)

  // do nothing when paused, otherwise keep roughly 20 fps
  if (paused.value || thisTick - lastTick < 50) return
  updateTime()

  player.vx = inputX.value
  player.vy = inputY.value

  if (inputX.value) player.lastDir = inputX.value

  let dx_ = dx.value
  let dy_ = dy.value

  if (dx > 0 && blocked.right) dx_ = 0
  else if (dx < 0 && blocked.left) dx_ = 0

  if (dy > 0 && blocked.down) dy_ = 0
  else if (dy < 0 && blocked.up) dy_ = 0

  if (!inputY.value && digging.value) {
    dx_ = 0
    dig()
  }

  x.value += dx_ * 32
  y.value += dy_ * 32
  lastTick = thisTick
}

onMounted(() => {
  lastTick = performance.now()
  move(lastTick)
})
</script>

<template>
  <div id="field" :class="timeOfDay">

    <div id="blocks" :style="{transform: `translate(${tx}px, ${ty}px)`}">
      <template v-for="(row, y) in rows">
        <div v-for="(block, x) in row" class="block" :class="[block.type]" />
      </template>
    </div>

    <div id="player" :class="direction" />
    <div id="level-indicator">
      x:{{ floorX }}, y:{{ floorY }}
      <template v-if="paused">(PAUSED)</template>
      <template v-else>({{ clock }})</template>
      <div>{{ inputX }}, {{ inputY }}, {{ player.lastDir }}</div>
      <div>{{ dx }}, {{ dy }}, {{ direction }}</div>
    </div>
  </div>
</template>
