'use strict'

modules['lineTest'] = {
    config: [
      ['shell', 'int', 0],
      ['scale', 'float', 1],
      ['subdivisions', 'int', 1],
      ['style', 'int', 1],
      ['lineBrightness', 'float', 1],
      ['quadBrightness', 'float', 1],
    ],

    render: async (time, self, config) => {
      const {
        shell,
        scale,
        subdivisions,
        style,
        lineBrightness,
        quadBrightness,
      } = { ...config }

      // Build a shell of quads
      let quads = []
      if (shell === 0) {
        quads = [
          [[-1,-1,+1], [-1,+1,+1], [+1,+1,+1], [+1,-1,+1]],
          [[-1,-1,-1], [-1,+1,-1], [+1,+1,-1], [+1,-1,-1]],
  
          [[-1,+1,-1], [-1,+1,+1], [+1,+1,+1], [+1,+1,-1]],
          [[-1,-1,-1], [-1,-1,+1], [+1,-1,+1], [+1,-1,-1]],
  
          [[+1,-1,-1], [+1,-1,+1], [+1,+1,+1], [+1,+1,-1]],
          [[-1,-1,-1], [-1,-1,+1], [-1,+1,+1], [-1,+1,-1]],
        ]
      } else if (shell === 1) {
        quads = [
          [[ 0,-1,+1], [-1,0,+1], [0,+1,+1], [+1,0,+1]],
          [[ 0,-1,-1], [-1,0,-1], [0,+1,-1], [+1,0,-1]],

          [[ 0,+1,-1], [-1,+1,0], [0,+1,+1], [+1,+1,0]],
          [[ 0,-1,-1], [-1,-1,0], [0,-1,+1], [+1,-1,0]],

          [[ +1,0,-1], [+1,-1,0], [+1,0,+1], [+1,+1,0]],
          [[ -1,0,-1], [-1,-1,0], [-1,0,+1], [-1,+1,0]],
        ]
      }
      quads = quads.map(quad => {
        let [v0, v1, v2, v3] = quad
        v0 = m4.multiplyVector(m4.normalize(v0), scale)
        v1 = m4.multiplyVector(m4.normalize(v1), scale)
        v2 = m4.multiplyVector(m4.normalize(v2), scale)
        v3 = m4.multiplyVector(m4.normalize(v3), scale)
        return [v0, v1, v2, v3]
      })

      // Subdivide
      for (let i = 0; i < subdivisions; ++i)
      {
        const newQuads = []
        quads.forEach(quad => {
          let [v0, v1, v2, v3] = quad
          const v01 = m4.multiplyVector(m4.normalize([
            (v0[0]+v1[0])/2,
            (v0[1]+v1[1])/2,
            (v0[2]+v1[2])/2,
          ]), scale)
          const v12 = m4.multiplyVector(m4.normalize([
            (v1[0]+v2[0])/2,
            (v1[1]+v2[1])/2,
            (v1[2]+v2[2])/2,
          ]), scale)
          const v03 = m4.multiplyVector(m4.normalize([
            (v0[0]+v3[0])/2,
            (v0[1]+v3[1])/2,
            (v0[2]+v3[2])/2,
          ]), scale)
          const v23 = m4.multiplyVector(m4.normalize([
            (v2[0]+v3[0])/2,
            (v2[1]+v3[1])/2,
            (v2[2]+v3[2])/2,
          ]), scale)
          const vm = m4.multiplyVector(m4.normalize([
            (v0[0]+v1[0]+v2[0]+v3[0])/4,
            (v0[1]+v1[1]+v2[1]+v3[1])/4,
            (v0[2]+v1[2]+v2[2]+v3[2])/4,
          ]), scale)
          newQuads.push([v0, v01, vm, v03])
          newQuads.push([v01, v1, v12, vm])
          newQuads.push([vm, v12, v2, v23])
          newQuads.push([v03, vm, v23, v3])
        })
        quads = newQuads
      }

      // Build verts, lines and quads
      const vertList = []
      const lineList = []
      const quadList = []
      let index = 0
      quads.forEach(quad => {
          if (style === 0) {
            lineList.push([index+1, index+3, lineBrightness])
          } else if (style === 1) {
            lineList.push([index+0, index+2, lineBrightness])
            lineList.push([index+1, index+3, lineBrightness])
          } else if (style === 2) {
            lineList.push([index+0, index+1, lineBrightness])
            lineList.push([index+1, index+2, lineBrightness])
            lineList.push([index+2, index+3, lineBrightness])
            lineList.push([index+3, index+0, lineBrightness])
          }
          
          quadList.push([index+0, index+1, index+2, index+3, quadBrightness])

          vertList.push(...quad)
          index += 4
      })

      // Render
      renderer.drawLists(greyscaleBuffers[getOutputBufferId()], m4.identity(), vertList, lineList, lineBrightness, [], 1, quadList, quadBrightness)
    }
}
