<template>
  <div id="root" class="flex-row">
    <div id="options" class="flex-col" size="large">
        <div>
            <Checkbox label="环境光" v-model="ambientOptions.visible">环境光</Checkbox>
            <Slider class="flex-1" v-model="ambientOptions.intensity" step=.01 max=5></Slider>
        </div>
        <div>
            <Checkbox label="平行光" v-model="directOptions.visible">平行光</Checkbox>
            <Slider class="flex-1" v-model="directOptions.intensity" step=.1 max=10></Slider>
        </div>
        <div>
            <Checkbox label="点光源" v-model="pointOptions.visible">点光源</Checkbox>
            <Slider class="flex-1" v-model="pointLight.intensity" step=1 max=1000></Slider>
        </div>
        <div>
            <Checkbox label="聚光灯" v-model="spotOptions.visible">聚光灯</Checkbox>
            <Slider class="flex-1" v-model="spotOptions.intensity" step=10 max=10000></Slider>
        </div>
    </div>
    <div id="container" ref="container"></div>
  </div>
</template>

<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import * as TT from '../threejs-tools'
import * as THREE from 'three'

const container = ref(null)
const td = new TT.ThreejsDefault(container)

// add mesh
td.scene.add(TT.createPlane())

const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshLambertMaterial({ color: 0xffffff })
const cube = new THREE.Mesh(geometry, material)
cube.position.y = 1
td.onAnimate(() => {
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
})
td.scene.add(cube)

// add light
function initLight(opts = {}, lightClass, lightArgs = [], helperClass, helperArgs = []) {
    // 合并options
    const defaultOpts = {
        color: 0xffffff,
        intensity: 1,
        visible: true,
    }
    const options = reactive({
        ...defaultOpts,
        ...opts,
    })

    // 添加light
    const light = new lightClass(options.color, options.intensity, ...lightArgs)
    light.visible = options.visible
    options.position && light.position.set(...options.position)
    td.scene.add(light)

    // 添加helper
    let helper = {}
    if (helperClass) {
        helper = new helperClass(light, ...helperArgs)
        helper.visible = options.visible
        td.scene.add(helper)
    }

    // 监听options变化
    watch(options, () => {
        light.visible = options.visible
        light.intensity = options.intensity
        helper.visible = options.visible
    })

    return [options, light, helper]
}

const [ambientOptions] = initLight({visible: true, intensity: .1}, THREE.AmbientLight)
const [directOptions] = initLight(
    {position: [-4, 5, -3], color: 0xff0000, intensity: 5},
    THREE.DirectionalLight, [],
    THREE.DirectionalLightHelper,
)
const [pointOptions, pointLight] = initLight(
    {position: [3, 3, -2], color: 0x00ff00, intensity: 100},
    THREE.PointLight, [],
    THREE.PointLightHelper, [.5],
)
const [spotOptions, spotLight, spotHelper] = initLight(
    {position: [-1, 7, 1], color: 0x0000ff, intensity: 5000},
    THREE.SpotLight, [10, .2, 1],
    THREE.SpotLightHelper,
)

</script>

<style scoped>
#root {
  width: 100%;
  height: 100%;
  align-items: flex-start;
}
#options {
  width: 100%;
  height: 100%;
  flex: 1;
  padding: 40px 20px;
  align-items: flex-start;
}
#options > div {
  margin-top: 20px;
  display: flex;
  align-items: center;
  width: 100%;

}
#container {
  flex: 5;
  width: 100%;
  height: 100%;
}

</style>
