'use strict'

modules['greetsFlyBy'] = {
    config: [
      ['scale', 'float3', [1, 1, 1]],
      ['xRotation', 'angle', 0],
      ['yRotation', 'angle', 0],
      ['zRotation', 'angle', 0],
    ],

    init: () => {
      const rng = new Math.seedrandom('flybyxyz')
      const myRng = (x) => {return (rng()*2-1) * x}

      const greets = []
      const layerSpeeds = {}
      for (let i = 0; i < 100; ++i) {
        let x, y, z
        while (true) {
          x = Math.floor(myRng(50))
          y = Math.floor(myRng(7))
          z = Math.floor(rng()*-8) * 2
          if (!greets.some(greet => {
            if (y === greet.base[1] &&
                z === greet.base[2] &&
                Math.abs(x - greet.base[0]) < 3) {
              return true
            } else {
              return false
            }
          })) {
            break
          }
        }
        const layerSpeedKey = `${y}_${z}`
        if (layerSpeeds[layerSpeedKey] === undefined) {
          do {
            layerSpeeds[layerSpeedKey] = myRng(3)
          } while (Math.abs(layerSpeeds[layerSpeedKey]) < 1)
        }
        greets.push({
          base: [x, y, z],
          speed: layerSpeeds[layerSpeedKey],
        })
      }

      return {
        greets
      }
    },

    render: async (frameTime, self, config) => {
      const {
        scale,
        xRotation,
        yRotation,
        zRotation,
      } = { ...config }

      const buffer = greyscaleBuffers[getOutputBufferId()]

      const xRotationMat = m4.xRotation(xRotation)
      const yRotationMat = m4.yRotation(yRotation)
      const zRotationMat = m4.zRotation(zRotation)
      const scaleMat = m4.scaling(scale[0], scale[1], scale[2])
      const modelMat = m4.multiply(scaleMat, m4.multiply(m4.multiply(zRotationMat, yRotationMat), xRotationMat))

      const wrapRange = 50
      const halfWrapRange = wrapRange / 2

      const models = [
        getModel('BLACKMAIDEN'),
        getModel('BLASPHEMY'),
        getModel('BYPASS'),
        getModel('DESIRE'),
        getModel('HOLON'),
        getModel('ORANGE'),
        getModel('ORB'),
        getModel('PURPLE'),
        getModel('REPLAY'),
        getModel('RIBBON'),
        getModel('SONIK'),
        getModel('TPOLM'),
        getModel('UKSCENE'),
        getModel('MIKUCOM_THANKFUL'),
      ]
      let modelIndex = 0

      self.greets.forEach(greet => {
        const speed = greet.speed
        let translation = [...greet.base]
        translation[0] += speed * frameTime
        if (speed > 0) {
          translation[0] = ((translation[0] + halfWrapRange) % wrapRange) - halfWrapRange
        } else {
          translation[0] = -(((-translation[0] + halfWrapRange) % wrapRange) - halfWrapRange)
        }

        const translationMat = m4.translation(translation[0], translation[1], translation[2])
        const worldMat = m4.multiply(translationMat, modelMat)
        renderer.drawModel(buffer, worldMat, models[modelIndex % models.length])
        modelIndex++
      })
    }
}
