<template>
  <div class="vore-container">
    <div class="container-name">{{container.name.capital}}</div>
    <div class="container-contents">
      <transition-group name="prey">
        <div :class="{ 'container-prey': true, 'container-prey-live': prey.vigors.Health > 0, 'container-prey-dead': prey.vigors.Health <= 0 }" v-for="(prey, index) in container.contents.concat(container.digested)" :key="'live-prey-' + index">{{prey.name.all}}</div>
      </transition-group>
    </div>
    <canvas class="container-waves"></canvas>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator'
import { Creature } from '@/game/creature'
import { POV } from '@/game/language'
import { Stats, Stat } from '@/game/combat'
import { Container, VoreContainer, Vore } from '@/game/vore'

function wiggle (contents: HTMLElement) {
  setTimeout(() => wiggle(contents), 3000)
  const width = contents.clientWidth
  const height = contents.clientHeight
  contents.querySelectorAll(".container-prey").forEach(elem => {
    const prey = elem as HTMLElement
    const preyWidth = prey.clientWidth
    const preyHeight = prey.clientHeight
    if (!prey.classList.contains("prey-leave-active")) {
      setTimeout(() => {
        (prey as HTMLElement).style.left = (Math.floor(Math.random() * (width - preyWidth)) + "px");
        (prey as HTMLElement).style.top = (Math.floor(Math.random() * (height - preyHeight)) + "px")
      }, Math.random() * 3000)
    }
  })
}

// yoinked from https://jsfiddle.net/yckart/0adfw47y/

function draw (delta: number, dt: number, total: number, parent: HTMLElement, canvas: HTMLCanvasElement, container: VoreContainer, smoothedFraction: number, smoothedLiveliness: number) {
  const ctx = canvas.getContext('2d') as CanvasRenderingContext2D

  canvas.width = parent.clientWidth
  canvas.height = parent.clientHeight
  ctx.fillStyle = container.fluidColor
  const fraction = container.fullness / container.capacity
  const livingFraction = container.contents.reduce((total: number, prey: Vore) => total + prey.voreStats.Bulk, 0) / container.capacity
  const deadFraction = container.digested.reduce((total: number, prey: Vore) => total + prey.voreStats.Bulk, 0) / container.capacity
  const liveliness = livingFraction + deadFraction * 0.5

  smoothedFraction = smoothedFraction * 0.995 + fraction * 0.005
  smoothedLiveliness = smoothedLiveliness * 0.995 + liveliness * 0.005

  total += dt * smoothedLiveliness

  requestAnimationFrame((newDelta: number) => draw(newDelta, newDelta - delta, total, parent, canvas, container, smoothedFraction, smoothedLiveliness))

  const randomLeft = Math.abs(Math.pow(Math.sin(total / 1000), 2)) * smoothedFraction * 100 + (1 - smoothedFraction) * canvas.height
  const randomRight = Math.abs(Math.pow(Math.sin((total / 1000) + 10), 2)) * smoothedFraction * 100 + (1 - smoothedFraction) * canvas.height
  const randomLeftConstraint = Math.abs(Math.pow(Math.sin((total / 1000) + 2), 2)) * smoothedFraction * 100 + (1 - smoothedFraction) * canvas.height
  const randomRightConstraint = Math.abs(Math.pow(Math.sin((total / 1000) + 1), 2)) * smoothedFraction * 100 + (1 - smoothedFraction) * canvas.height

  ctx.beginPath()
  ctx.moveTo(0, randomLeft)

  ctx.bezierCurveTo(canvas.width / 3, randomLeftConstraint, canvas.width / 3 * 2, randomRightConstraint, canvas.width, randomRight)
  ctx.lineTo(canvas.width, canvas.height)
  ctx.lineTo(0, canvas.height)
  ctx.lineTo(0, randomLeft)

  ctx.closePath()
  ctx.fill()
}

@Component
export default class ContainerView extends Vue {
  @Prop({ required: true })
  container!: VoreContainer

  mounted () {
    const canvas = this.$el.querySelector('.container-waves') as HTMLCanvasElement

    canvas.width = (this.$el as HTMLElement).clientWidth
    canvas.height = (this.$el as HTMLElement).clientHeight
    canvas.width = canvas.width + 0
    requestAnimationFrame((delta: number) => draw(delta, delta, Math.random() * 1000, this.$el as HTMLElement, canvas, (this.container as VoreContainer), 0, 0))

    wiggle(this.$el.querySelector(".container-contents") as HTMLElement)
  }
}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .vore-container {
    flex: 1 1;
    position: relative;
    min-height: 100pt;
    display: flex;
    flex-direction: column;
  }
  .container-name {
    margin: 8pt;
    font-size: 150%;
  }

  .container-fullness {
    margin: 6pt;
    font-size: 125%;
  }

  .container-waves {
    position: absolute;
    top: 0;
    left: 0;
  }

  .container-contents {
    position: relative;
    flex: 1;
  }

  .container-prey {
    position: absolute;
    transition: 3s top, 3s left;
    top: 25px;
    left: 25px;
    overflow: hidden;
    z-index: 1;
  }

  .container-prey-live {
    color: #eeeeee;
  }

  .container-prey-dead {
    color: #ff0000;
  }

  .prey-enter {
    opacity: 0;
  }

  .prey-enter-active {
    transition: 1s opacity;
  }

  .prey-leave {
    opacity: 1;
  }

  .container-prey-live.prey-leave-active {
    opacity: 0;
    transition: 1s opacity, 3s top, 3s left;
  }

  .container-prey-dead.prey-leave-active {
    opacity: 0;
    transition: 4s filter, 4s opacity, 3s top, 3s left;
    filter: blur(20px)
  }

</style>
