<template>
    <div class="container">
        <div ref="threeDiv" id="webgl" class="webgl"></div>

        <div class="legend_box">
            <div class="legend_head"><span class="text_gradual head_text">显示选择</span></div>
            <div class="legend_content">
                <div class="legend_item" v-for="(v, k) in legendList" :key="k">
                    <div :class="{ icon_check: true, icon_checked: v.visible }" @click="handleCheck(v, k)"></div>
                    <!-- <img src="@/assets/bigScreen/point/icon_check.png" alt="" @click="handleCheck(v, k)">
                    <img src="@/assets/bigScreen/point/icon_check.png" alt="" @click="handleCheck(v,k)"> -->
                    <span :class="{ span_checked: v.visible }">{{ v.name }}</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
// 引入three.js
import * as THREE from 'three';
// // 引入扩展库OrbitControls.js
// import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// // 引入扩展库GLTFLoader.js
// import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';

import { Water } from 'three/examples/jsm/objects/Water.js';


import { drawAxes } from "@/utils/three.js";

import Scene from "@/components/Scene/index.vue";
export default {
    name: 'Home',
    props: {

    },
    components: {
        Scene
    },
    data(){
        return {
            scene: null,  //  场景
            camera: null,  //  相机
            renderer: null,  //  渲染器

            // 从图片中提取的数据
            xAxisLabels: ['A', 'B', 'C', 'D', 'E'],
            zAxisLabels: ['A', 'B', 'C', 'D', 'E'],
            labelRenderer: null,
            legendList: [
                { label: '红色通道', val: '1', checked: true },
                { label: '绿色通道', val: '2', checked: true },
                { label: '蓝色通道', val: '3', checked: true },
                { label: '灰色通道', val: '4', checked: true },],
            
        }
    },
    mounted(){
        // console.log(THREE.Scene); 
        // this.init()

        const sceneBox = document.getElementById('webgl');

        const options = {
            gridSize: { x: 50, y: 50, z: 50 }, // 三维网格尺寸
            // gridSize: { x: 100, y: 100, z: 100 }, // 三维网格尺寸
            // grid_uv_up = [5, 5],
            // grid_uv_down = [5, 5],
            grid_uv_left: [10, 10],
            // grid_uv_right = [5, 4],
            // grid_uv_front = [5, 4],
            grid_uv_back: [10, 10],
            show_water: true, // 是否显示水面
            water_height: 5, // 水面厚度
            data: {
                红球: [
                    [20, 40, 0],
                    [20, 40, 10],
                    [20, 40, 20],
                    [20, 40, 30],
                    [20, 40, 40],
                ],
                绿球: [
                    [10, 10, 0],
                    [10, 10, 10],
                    [10, 10, 20],
                ],
                蓝球: [
                    [20, 20, 0],
                    [20, 20, 10],
                    [20, 20, 20],
                    [40, 20, 20],
                    [40, 20, 0],
                ],
                灰球: [
                    [30, 30, 0],
                    [30, 30, 10],
                    [30, 30, 20],
                    [40, 30, 0],
                    [40, 30, 10],
                ],
                白球: [
                    [20, 50, 0],
                    [20, 50, 10],
                    [30, 50, 20],
                    [30, 50, 0],
                    [30, 50, 10],
                ],
            },
            // labels_left: ["", "A", "B", "C", "D", "E"],
            labels_left: ["", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"],
            // labels_back: ["", "A", "B", "C", "D", "E"],
            labels_back: ["", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"],
        };
        const demo1 = drawAxes(sceneBox, options,(val)=> {
            this.legendList = val
            
        })


    },
    methods: {
        handleCheck(v,k){
            if (this.legendList[k]) this.legendList[k].visible = !this.legendList[k].visible;
        },
        init(){
            //  创建场景
            this.scene = new THREE.Scene();

            
            // // 网格辅助线 -- 地表格（网格宽度、等分数、中心线颜色，网格线颜色）
            // const grid = new THREE.GridHelper(12, 12, 0x3a506b, 0x1a3a5a);
            // scene.add(grid);
            // this.createGrids()
            // 3. 创建网格辅助平面（只显示正方向）
            this.createPositivePlane(this.scene, 'XY', 0x6db1fc, 5, 5); // 红色XY平面
            this.createPositivePlane(this.scene, 'XZ', 0x6db1fc, 5, 5); // 绿色XZ平面
            this.createPositivePlane(this.scene, 'YZ', 0x6db1fc, 5, 5); // 蓝色YZ平面

            // 三维辅助线（长度）-- 三维坐标系
            // const axisHelper = new THREE.AxesHelper(5);
            // this.scene.add(axisHelper);
            this.addPositiveAxes(6)

            


            this.createWaterPool()


            
            //定义一个几何体
            // const geometry = new THREE.SphereGeometry(2, 30, 30);
            //创建一个长方体几何对象Geometry
            const geometry = new THREE.BoxGeometry(100, 100, 100);
            // //创建一个材质对象Material
            const material = new THREE.MeshBasicMaterial({
                color: 0xff0000,//0xff0000设置材质颜色为红色
            });
            //定义一种材质，显示为线框
            // const material = new THREE.MeshBasicMaterial({ color: 0xB3DD, wireframe: true });
            //网孔(Mesh)是用来承载几何模型的一个对象，可以把材料应用到它上面
            const ball = new THREE.Mesh(geometry, material);
            //把几何模型添加到场景中，对象被添加到原点(0,0,0)坐标。
            this.scene.add(ball);
            this.scene.position.set(-2.5, -2.5, -2.5);  //  修改 场景 中心点

            //创建透视投影相机，视角45度，画幅比例 宽比高，近平面距离0.1，远平面1000
            this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
            //移动相机位置
            // this.camera.position.z = 8
            this.camera.position.set(8, 6, 5);
            //相机观察目标指向Threejs 3D空间中某个位置
            this.camera.lookAt(0, 0, 0); //坐标原点;
            
            //创建渲染器
            this.renderer = new THREE.WebGLRenderer({
                alpha: true,  // 启用透明度
                // antialias: true
            });
            this.renderer.setClearColor(0x000000, 0); // 设置透明背景
            //渲染器canvas宽高设为与窗口一致
            this.renderer.setSize(window.innerWidth, window.innerHeight);
            this.renderer.render(this.scene, this.camera);
            //将渲染器对应的dom元素添加到body中
            const sceneBox = document.getElementById('webgl');
            sceneBox.appendChild(this.renderer.domElement);

           
            // function render() {
            //     //渲染循环，以每秒60次的频率来绘制场景
            //     requestAnimationFrame(render);
            //     //设置球体绕y轴旋转
            //     ball.rotation.y += 0.005;
            //     this.renderer.render(this.scene, this.camera);
            // }
            // render();


            // // 创建CSS2D渲染器用于标签
            // this.labelRenderer = new CSS2DRenderer();
            // this.labelRenderer.setSize(
            //     sceneBox.clientWidth,
            //     sceneBox.clientHeight
            // );
            // this.labelRenderer.domElement.style.position = 'absolute';
            // this.labelRenderer.domElement.style.top = '0';
            // this.labelRenderer.domElement.style.pointerEvents = 'none';
            // sceneBox.appendChild(this.labelRenderer.domElement);

            // this.addGridHelpers()


            /**
            * 创建轨道控制器（OrbitControls）
            * 可以使得相机围绕目标进行轨道运动
            */
            const controls = new OrbitControls(this.camera, this.renderer.domElement);
            controls.addEventListener('change',()=> {
                this.renderer.render(this.scene, this.camera);
            })
            // controls.autoRotate = true; // 相机是否自动旋转
            // controls.autoRotateSpeed = 3; // 自转速度
            // // // 设置控制器阻尼，让控制器更有真实效果，必须在动画循环render()中调用controls.update()()
            // controls.enableDamping = true;

            // 监听尺寸变化实现自适应画面
            window.addEventListener("resize", () => {
                // console.log("画面变化了");
                // 更新摄像头
                this.camera.aspect = window.innerWidth / window.innerHeight;
                // 更新摄像机的投影矩阵
                this.camera.updateProjectionMatrix();
                // 更新渲染器
                this.renderer.setSize(window.innerWidth, window.innerHeight);
                // 设置渲染器的像素比
                this.renderer.setPixelRatio(window.devicePixelRatio);
            });


        },
        //  创建坐标轴
        async addPositiveAxes(axisLength) {
            // axisLength  坐标轴长度
            const tickInterval = 1;   // 刻度间隔

            // 加载刻度图片（替换为你的图片路径）
            // const tickTexture = await loadTexture('/path/to/your/tick-image.png');
            const tickTextureX = [require('@/assets/icon_xz/x01.png'), require('@/assets/icon_xz/x02.png'),
                require('@/assets/icon_xz/x03.png'), require('@/assets/icon_xz/x04.png'), require('@/assets/icon_xz/x05.png')
            ]
            const tickTextureZ = [require('@/assets/icon_xz/z01.png'), require('@/assets/icon_xz/z02.png'),
                require('@/assets/icon_xz/z03.png'), require('@/assets/icon_xz/z04.png'), require('@/assets/icon_xz/z05.png')
            ]
            // const tickTextureX = ['@/assets/icon/x01.png', '@/assets/icon/x02.png',
            //     '@/assets/icon/x03.png', '@/assets/icon/x04.png', '@/assets/icon/x05.png'
            // ]
            // const tickTextureZ = ['@/assets/icon/z01.png', '@/assets/icon/z02.png',
            //     '@/assets/icon/z03.png', '@/assets/icon/z04.png', '@/assets/icon/z05.png'
            // ]
            // 创建X轴（红色，只显示正向）
            const xAxis = new THREE.ArrowHelper(
                new THREE.Vector3(1, 0, 0),  // 方向
                new THREE.Vector3(0, 0, 0),  // 起点
                axisLength,                  // 长度
                0xff0000,                     // 颜色（红色）
                0.2,                          // 头部长度
                0.1                           // 头部宽度
            );
            this.scene.add(xAxis);

            // 创建Y轴（绿色，只显示正向）
            const yAxis = new THREE.ArrowHelper(
                new THREE.Vector3(0, 1, 0),
                new THREE.Vector3(0, 0, 0),
                axisLength,
                0x00ff00,                     // 颜色（绿色）
                0.2,
                0.1
            );
            this.scene.add(yAxis);

            // 创建Z轴（蓝色，只显示正向）
            const zAxis = new THREE.ArrowHelper(
                new THREE.Vector3(0, 0, 1),
                new THREE.Vector3(0, 0, 0),
                axisLength,
                0x0000ff,                     // 颜色（蓝色）
                0.2,
                0.1
            );
            this.scene.add(zAxis);

            
            
            const texLoader = new THREE.TextureLoader();
            // 添加X轴刻度图片
            for (let i = tickInterval; i <= axisLength; i += tickInterval) {
                // .load()方法加载图像，返回一个纹理对象Texture
                // const texture = await new Promise(resolve => {
                //     texLoader.load(tickTextureX[i - 1], resolve);
                // });
                const texture =  texLoader.load(tickTextureX[i - 1]);
                const tick = this.createImageTick(texture, i, 0, 0, 'x');
                this.scene.add(tick);
            }

            // 添加Z轴刻度图片
            for (let j = tickInterval; j <= axisLength; j += tickInterval) {
                // .load()方法加载图像，返回一个纹理对象Texture
                const texture = texLoader.load(tickTextureZ[j -1])
                const tick = this.createImageTick(texture, 0, 0, j, 'z');
                this.scene.add(tick);
            }
            // 添加轴标签
            this.addAxisLabel('X', new THREE.Vector3(axisLength * 1.1, 0, 0), 0xff0000);
            this.addAxisLabel('Y', new THREE.Vector3(0, axisLength * 1.1, 0), 0x00ff00);
            this.addAxisLabel('Z', new THREE.Vector3(0, 0, axisLength * 1.1), 0x0000ff);


            this.addAxisLabel('A', new THREE.Vector3(1, 5.3, 0), 0x6db1fc);
            this.addAxisLabel('B', new THREE.Vector3(2, 5.3, 0), 0x6db1fc);
            this.addAxisLabel('C', new THREE.Vector3(3, 5.3, 0), 0x6db1fc);
            this.addAxisLabel('D', new THREE.Vector3(4, 5.3, 0), 0x6db1fc);
            this.addAxisLabel('E', new THREE.Vector3(5, 5.3, 0), 0x6db1fc);

            this.addAxisLabel('A', new THREE.Vector3(0, 5.3, 1), 0x6db1fc);
            this.addAxisLabel('B', new THREE.Vector3(0, 5.3, 2), 0x6db1fc);
            this.addAxisLabel('C', new THREE.Vector3(0, 5.3, 3), 0x6db1fc);
            this.addAxisLabel('D', new THREE.Vector3(0, 5.3, 4), 0x6db1fc);
            this.addAxisLabel('E', new THREE.Vector3(0, 5.3, 5), 0x6db1fc);
            
        },
        // 创建图片刻度
        createImageTick(texture, x, y, z, axis){
            const tickSize = 0.8;  // 刻度大小
            
            const material = new THREE.SpriteMaterial({ map: texture, transparent: true });
            const sprite = new THREE.Sprite(material);

            // 根据轴调整位置和旋转
            if (axis === 'x') {
                sprite.position.set(x, y, z);
            } else if (axis === 'z') {
                sprite.position.set(x, y, z);
            }

            sprite.scale.set(tickSize, tickSize, 1);
            return sprite;
        },
        // 添加轴标签
        addAxisLabel(text, position, color){
            const canvas = document.createElement('canvas');
            canvas.width = 128;
            canvas.height = 128;
            const context = canvas.getContext('2d');
            context.fillStyle = 'rgba(0, 0, 0, 0)';
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.font = 'Bold 48px Arial';
            context.textAlign = 'center';
            context.textBaseline = 'middle';
            context.fillStyle = `#${color.toString(16).padStart(6, '0')}`;
            context.fillText(text, canvas.width / 2, canvas.height / 2);

           

            const texture = new THREE.CanvasTexture(canvas);
            const material = new THREE.SpriteMaterial({ map: texture, transparent: true });
            const sprite = new THREE.Sprite(material);
            sprite.position.copy(position);
            sprite.scale.set(0.8, 0.8, 0.8);
            this.scene.add(sprite);
        },
        // 创建水池几何体 - 宽度和深度可以根据需要调整
        createWaterPool() {
            const width = 5;
            const depth = 5;
            const height = 0.5; // 水池高度0.5

            const geometry = new THREE.BoxGeometry(width, height, depth);

            // 创建半透明材质
            const material = new THREE.MeshPhongMaterial({
                color: 0x8ddefe,
                transparent: true,
                opacity: 0.3,
                side: THREE.DoubleSide,
                specular: 0x111111, // 高光
                shininess: 100, // 光泽度
                refractionRatio: 0.85 // 折射率
            });

            // 创建水池网格
            const pool = new THREE.Mesh(geometry, material);
            pool.position.set(2.5, -0.2, 2.5);
            pool.receiveShadow = true; // 接收阴影
            pool.castShadow = true; // 投射阴影

            // // 将水池放置在XZ平面，Y轴位置为高度的一半（因为几何体中心在原点）
            // pool.position.y = height / 2;

            this.scene.add(pool);

            // 添加一些光照
            const ambientLight = new THREE.AmbientLight(0x404040);
            this.scene.add(ambientLight);

            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(1, 1, 1);
            directionalLight.castShadow = true;
            this.scene.add(directionalLight);
            // this.addWaterEffect(pool)
            // this.createAdvancedWater()
        },
        //   水流动效果实现  
        addWaterEffect(pool) {
            // 创建着色器材质来实现水波效果
            const waterUniforms = {
                time: { type: "f", value: 0.0 },
                waterColor: { type: "c", value: new THREE.Color(0x8ddefe) }
            };

            const waterMaterial = new THREE.ShaderMaterial({
                uniforms: waterUniforms,
                vertexShader: `
                    uniform float time;
                    varying vec3 vPosition;
                    varying vec2 vUv;
                    
                    void main() {
                        vUv = uv;
                        vPosition = position;
                        
                        // 创建波浪效果
                        float waveHeight = sin(position.x * 2.0 + time) * 0.05;
                        waveHeight += sin(position.z * 1.5 + time * 1.5) * 0.03;
                        
                        vec3 newPosition = position;
                        newPosition.y += waveHeight;
                        
                        gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
                    }
                `,
                fragmentShader: `
                    uniform vec3 waterColor;
                    varying vec3 vPosition;
                    varying vec2 vUv;
                    
                    void main() {
                        // 创建水的颜色变化
                        float ripple = sin(vPosition.x * 10.0 + vPosition.z * 10.0) * 0.1;
                        vec3 color = waterColor + vec3(ripple * 0.2);
                        
                        // 透明度随波浪变化
                        float alpha = 0.3 + ripple * 0.1;
                        
                        gl_FragColor = vec4(color, alpha);
                    }
                `,
                transparent: true,
                side: THREE.DoubleSide,
                wireframe: false
            });

            // 替换原来的材质
            pool.material = waterMaterial;

            // 动画循环中更新time uniform
            const animate = () => {
                requestAnimationFrame(animate);
                waterUniforms.time.value += 0.05;
            };
            animate();
        },  

        //   水流动效果实现  方式 2
        createAdvancedWater() {
            const waterGeometry = new THREE.PlaneGeometry(5, 5);
            const water = new Water(
                waterGeometry,
                {
                    textureWidth: 512,
                    textureHeight: 512,
                    waterNormals: new THREE.TextureLoader().load('textures/waternormals.jpg', function (texture) {
                        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
                    }),
                    sunDirection: new THREE.Vector3(),
                    sunColor: 0xffffff,
                    waterColor: 0x8ddefe,
                    distortionScale: 3.7,
                    fog: this.scene.fog !== undefined
                }
            );

            water.rotation.x = -Math.PI / 2;
            // water.position.y = -0.2;
            water.position.set(2.5, -0.2, 2.5);

            this.scene.add(water);

            // 在动画循环中更新水
            const animate = () => {
                requestAnimationFrame(animate);
                water.material.uniforms.time.value += 0.05;
            };
            animate();
        },


        /**
         * 创建正方向网格平面
         * @param {THREE.Scene} scene - 场景对象
         * @param {string} planeType - 平面类型: 'XY', 'XZ', 'YZ'
         * @param {number} color - 网格颜色
         * @param {number} size - 网格尺寸
         * @param {number} divisions - 网格分割数
         */
        createPositivePlane(scene, planeType, color, size, divisions) {
            const step = size / divisions;
            const vertices = [];

            // 根据平面类型生成顶点数据
            switch (planeType) {
                case 'XY': // Z=0 平面 (X正方向, Y正方向)
                    for (let i = 0; i <= divisions; i++) {
                        // 平行于X轴的线 (Y变化)
                        vertices.push(i * step , 0, 0, i * step, size, 0);
                        // 平行于Y轴的线 (X变化)
                        vertices.push(0, i * step, 0, size, i * step, 0);
                    }
                    break; 
                case 'XZ': // Y=0 平面 (X正方向, Z正方向)
                    for (let i = 0; i <= divisions; i++) {
                        // 平行于X轴的线 (Z变化)
                        vertices.push(i * step, 0, 0, i * step, 0, size);
                        // 平行于Z轴的线 (X变化)
                        vertices.push(0, 0, i * step, size, 0, i * step);
                    }
                    break; 
                case 'YZ': // X=0 平面 (Y正方向, Z正方向)
                    for (let i = 0; i <= divisions; i++) {
                        // 平行于Y轴的线 (Z变化)
                        vertices.push(0, i * step, 0, 0, i * step, size);
                        // 平行于Z轴的线 (Y变化)
                        vertices.push(0, 0, i * step, 0, size, i * step);
                    }
                    break;
            }
            // 创建几何体和材质
            const geometry = new THREE.BufferGeometry();
            geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));

            const material = new THREE.LineBasicMaterial({
                color: color,
                transparent: true,
                opacity: 0.6
            });

            // 添加到场景
            const grid = new THREE.LineSegments(geometry, material);
            scene.add(grid);
        },
    }
}
</script>

<style lang="scss" scoped>
.container{
    width: 100%;
    height: 100%;
    position: relative;
    .webgl{
        width: 100%;
        height: 100%;
    }
    .legend_box{
        position: absolute;
        top: 120px;
        right: 150px;
        width: 195px;
        height: fit-content;
        .legend_head{
            width: 100%;
            height: 38px;
            background-image: url('~@/assets/bigScreen/point/icon_bg_1.png');
            background-repeat: no-repeat;
            background-size: 100% 100%;
            text-align: center;
            line-height: 38px;
            user-select: none;
            .head_text{
                font-weight: 700;
                font-size: 16px;
            }
        }
        .legend_content{
            width: 100%;
            height: fit-content;
            // height: 316px;
            background-image: url('~@/assets/bigScreen/point/icon_bg_2.png');
            background-repeat: no-repeat;
            background-size: 100% 100%;
            padding: 30px 20px;
            .legend_item{
                width: 100%;
                height: 42px;
                display: flex;
                align-items: center;
                justify-content: center;
                color: #99bbd7;
                .icon_check{
                    width: 20px;
                    height: 20px;
                    cursor: pointer;
                    background-image: url('~@/assets/bigScreen/point/icon_check.png');
                    background-repeat: no-repeat;
                    background-size: 100% 100%;
                }
                .icon_checked{
                    background-image: url('~@/assets/bigScreen/point/icon_checked.png');
                }
                span{
                    margin-left: 15px;
                    font-size: 16px;
                }
                .span_checked{
                    color: #69ffdd;
                }
            }
        }
    }
}
</style>