import { scene, axis, meshList, pointsList, axis2D, scene2D } from './history.js';
import { createAxisInfo } from './axisInfo/constant.js';
const lut = new THREE.Lut();
lut.addColorMap('axis', [[0.0, 0x00ee00], [0.25, 0xeeee00], [0.75, 0xee0000], [1.0, 0x4e0211]],);
lut.setColorMap('axis',1024)
let pointColors = [
    {
        material: new THREE.PointsMaterial({ color: 0xD94E5D, size: 2, sizeAttenuation: false }),
        colors: 0xD94E5D,
        num: 15,
    },
    {
        material: new THREE.PointsMaterial({ color: 0xE28B4A, size: 2, sizeAttenuation: false }),
        colors: 0xE28B4A,
        num: 14,
    },
    {
        material: new THREE.PointsMaterial({ color: 0xEAC736, size: 2, sizeAttenuation: false }),
        colors: 0xEAC736,
        num: 10,
    },
    {
        material: new THREE.PointsMaterial({ color: 0x9DB578, size: 2, sizeAttenuation: false }),
        colors: 0x9DB578,
        num: 7,
    },
    {
        material: new THREE.PointsMaterial({ color: 0x50A3BA, size: 2, sizeAttenuation: false }),
        colors: 0x50A3BA,
        num: 5,
    },
];
const initPoints = new THREE.Points(
    new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute([0.5, 0, 0], 3)),
    new THREE.PointsMaterial({ color: 0x0082df, size: 2, sizeAttenuation: false })
);
//柱子材质数据
let meterials = [
    {
        material: new THREE.MeshBasicMaterial({
            color: '#4e0211',
        }),
        max: 0.75
    },
    {
        material: new THREE.MeshBasicMaterial({
            color: '#ee0000',
        }),
        max: 0.5
    },
    {
        material: new THREE.MeshBasicMaterial({
            color: '#eeee00',
        }),
        max: 0.25
    },
    {
        material: new THREE.MeshBasicMaterial({
            color: '#00ee00',
        }),
        max: 0,
    },
];
const initGeometry = new THREE.BoxGeometry(0.6, 1, 2.5);
//绘制图表柱子
const drawChartsContent = (px, pz, py = 50, max, pxNum) => {
    let y = py < 0 ? -py : py;
    const material = new THREE.MeshBasicMaterial({color:lut.getColor(Number(y)/max)});//
    //const material = meterials.find(item => (y / max) >= item.max).material;
    //柱子宽高长
    const geometry = initGeometry.clone();
    geometry.scale(1, y, 1);
    geometry.translate(49.4 - pxNum, Math.fround(py / 2), 360 - pz);
    return { geometry, material }
}
//正弦曲线绘制
const drawSinLine = (obj) => {
    let { line, color } = obj, list = [];
    line.forEach(item => {
        list.push(new THREE.Vector3(...item));
    })
    let geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
    // 三维样条曲线  Catmull-Rom算法
    let curve = new THREE.CatmullRomCurve3(list);
    //getPoints是基类Curve的方法，返回一个vector3对象作为元素组成的数组
    let points = curve.getPoints(200); //分段数100，返回101个顶点
    // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
    geometry.setFromPoints(points);
    //材质对象
    let material = new THREE.LineBasicMaterial({
        color,
        linewidth: 1,
    });
    //线条模型对象
    let modelLine = new THREE.Line(geometry, material);
    return modelLine
    //scene.add(line); //线条对象添加到场景中
}
//绘制网格线条
const drawLine = (obj) => {
    let { line, color, position, margin, num } = obj
    let geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
    //3个为一组，表示一个顶点的xyz坐标
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(line, 3))
    // 线条渲染模式
    let material = new THREE.LineBasicMaterial({
        color, //线条颜色
    });//材质对象
    let LineList = [];
    let modelLine = new THREE.Line(geometry, material);//线条模型对象
    LineList.push(modelLine)
    for (let i = 1; i < num; i++) {
        let lineChildren = modelLine.clone()['translate' + position](i * margin)
        LineList.push(lineChildren);
    }
    return LineList
}
// 添加文字geometry
const add3DText = (text, callback) => {
    let { content, url, size, set, rotation, xyz } = text;
    let loader = new THREE.FontLoader();
    //加载相应的字体，下面字体名和样式组成gentilis_bold.typeface.json 完整文件名
    let fontJsonUrl = url ? url : 'common/fonts/Century Gothic_Regular.json'; //你的字体json路径，文件名规格随意
    loader.load(fontJsonUrl, function (font) {
        const color = 0xffffff;
        const matLite = new THREE.MeshBasicMaterial({
            color: color,          // 字体大小
        });
        const geometry = new THREE.TextGeometry(content, {
            font: font,
            size: size ? size : 5,
            height: 1,
        });
        geometry.translate(...xyz);
        if (rotation) {
            for (let i of rotation) {
                geometry['rotate' + i[0]](Math.PI / i[1])
            }

        }
        let mesh = new THREE.Mesh(geometry, matLite);
        // mesh.scale.set(2, 2, 2)
        if (set) {
            mesh.scale.set(...set);
        }
        mesh.castShadow = true;
        mesh.receiveShadow = true;
        mesh.name = 'text';
        callback(mesh)
    });
}
// 添加精灵图文字
const draw2DText = (obj) => {
    let scale = 1;//window.devicePixelRatio;
    let { content, w, h, color, font, xyz, size, cw, ch, rotate } = obj;
    cw = cw ? cw : 6;
    ch = ch ? ch : 8;
    let canvas = document.createElement('canvas')
    canvas.style.width = w * scale;
    canvas.style.height = h * scale;
    if (rotate) {
        canvas.width = w * cw * scale * 3;
        canvas.height = h * ch * scale * 2;
    } else {
        canvas.width = w * cw * scale * 2;
        canvas.height = h * ch * scale * 3;
    }

    let ctx = canvas.getContext('2d');
    ctx.fillStyle = color;
    ctx.strokeStyle = color;
    ctx.font = font;
    ctx.direction = "ltr"; // 文本方向从左向右
    ctx.textAlign = "left"; // 左对齐
    ctx.textBaseline = 'middle'//基线对齐选项，决定文字垂直方向的对齐方式
    if (rotate) {
        ctx.translate(canvas.width / 2, canvas.height);
        ctx.rotate(-Math.PI / 2);
        ctx.fillText(content, h, 0);
        //ctx.strokeText(content, h, 0);
    } else {
        for (let i = 0; i < 1; i++) {
            ctx.fillText(content[i], 0, canvas.height / 2);
           ctx.strokeText(content[i], 0, canvas.height / 2);
        }
    }
    let texture = new THREE.CanvasTexture(canvas)
    // texture.needsUpdate = true//如果编码类型在纹理已被一个材质使用之后发生了改变， 你需要来设置Material.needsUpdate为true来使得材质重新编译
    let geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
    //3个为一组，表示一个顶点的xyz坐标
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(xyz, 3));
    const material = new THREE.PointsMaterial({
        map: texture,
        transparent: true,//材质透明
        size: size ? size : 16.0, //点对象像素尺寸
    });

    const pointsText = new THREE.Points(geometry, material);
    pointsText.name = 'pointsText';
    return pointsText;
}

const drawAxis = (size, minNum, is2DInit) => {
    scene.remove(...scene.children.filter(item => item.name === 'axisNumberText'))
    if (axis.children.length) {
        axis.remove(...axis.children)
    }
    let axisText = new THREE.Group();
    axisText.name = 'axisNumberText';
    scene.add(axisText)
    const data = createAxisInfo(size, minNum);
    axis.scale.set(...data[size]['set'])
    meshList.scale.set(...data[size]['set'])
    pointsList.scale.set(...data[size]['set'])
    data[size]['prps'].forEach(async item => {
        switch (item.type) {
            case 'plan':
                axis.add(drawPlan(item));
                break;
            case 'line':
                axis.add(...drawLine(item));
                break;
            case 'curveLine':
                axis.add(drawSinLine(item));
                break;
            case 'text':
                axisText.add(draw2DText(item));
        }
    });
    if (is2DInit) {
        return;
    }
    drawAxis2D(size, minNum);
}
const drawAxis2D = (size, minNum) => {
    if (axis2D.children.length) {
        axis2D.remove(...axis2D.children)
    }
    let axisList = scene2D?.children.filter(item => item.name === 'axisNumberText');
    axisList && scene2D.remove(...axisList)
    let axisText = new THREE.Group();
    const data = createAxisInfo(size, minNum);
    axisText.name = 'axisNumberText';
    scene2D.add(axisText)
    axis2D.scale.set(...data[size]['set'])
    let list = scene2D.getObjectByName('chartsPoint')
    if (list) {
        list.scale.set(...data[size]['set'])
    }
    data[size]['prpd'].forEach(async item => {
        switch (item.type) {
            case 'line':
                axis2D.add(...drawLine(item));
                break;
            case 'curveLine':
                axis2D.add(drawSinLine(item));
                break;
            case 'text':
                axisText.add(draw2DText(item));
        }
    });
}
//绘制平面
const drawPlan = (obj) => {
    const { size, color } = obj;
    let geometry = new THREE.PlaneGeometry(size, 360); //创建一个Buffer类型几何体对象
    geometry.rotateX(Math.PI / 2).translate(size/2, 0, 180);
    // 三角面(网格)渲染模式
    let material = new THREE.MeshBasicMaterial({
        color, //三角面颜色
        transparent: true,//透明
        opacity: 0.2,
        side: THREE.DoubleSide, //两面可见
    }); //材质对象
    let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    mesh.name = 'plan';
    //scene.add(mesh);
    return mesh
}
export { drawChartsContent, drawSinLine, drawLine, add3DText, draw2DText, drawAxis, drawAxis2D, initPoints, pointColors, drawPlan }