'use strict'

modules['modelTunnel'] = {
    config: [
        ['distance', 'float', 0],
        ['startDepth', 'float', 50],
        ['repeatCount', 'int', 10],
        ['componentDepth', 'float', 5],
        ['models', 'string', ''],
        ['excludeObjects', 'string', ''],
        ['rotationMod', 'float', 0],
        ['depthBias', 'float', 0],
    ],

    init: () => {
        const rng = new Math.seedrandom('tunnel')
        const parts = []
        for (let i = 0; i < 50; ++i) {
            parts.push({
                baseAngle: i * .3,
                rotSpeed: (rng() - 0.5) * 0.2,
                modelRng: rng()
            })
        }
        return {
            parts
        }
    },

    render: async (time, self, config) => {
        const {
            distance,
            startDepth,
            repeatCount,
            componentDepth,
            models,
            excludeObjects,
            rotationMod,
            depthBias,
        } = { ...config }

        const buffer = greyscaleBuffers[getOutputBufferId()]

        const modelList = models.split(',')
        const excludeObjectArray = excludeObjects.split(',')

        const thingsToRender = []
        let index = (Math.floor(distance / componentDepth) - repeatCount + self.parts.length) % self.parts.length
        let z = startDepth + (distance % componentDepth) + repeatCount * componentDepth
        for (let i = -repeatCount; i <= repeatCount; ++i) {
            const partIndex = index % self.parts.length
            const part = self.parts[partIndex]
            const rotation = part.baseAngle + part.rotSpeed*(time + rotationMod)
            const zRotationMat = m4.zRotation(rotation)
            const xRotationMat = m4.xRotation(Math.PI/2)
            const transMat = m4.translation(0, 0, z)
            const worldMat = m4.multiply(transMat, m4.multiply(zRotationMat, xRotationMat))

            const modelId = Math.floor(part.modelRng * (modelList.length-1))
            thingsToRender.push([worldMat, getModel(modelList[modelId])])
            index++
            z -= componentDepth
        }

        const state = renderer.saveRenderState()
        renderer.setDepthBias(state.depthBias + depthBias)
        thingsToRender.forEach(thing => {
            renderer.drawModel(buffer, thing[0], thing[1], excludeObjectArray)
        })
        renderer.setDepthBias(state.depthBias)
    }
}
