importPackage(java.awt);
importPackage(java.awt.geom);

include("draw_num.js");

const num_leftPos = [[1.470637, 1.353106, 1.75], [1.479363, 0.353144, 1.75], [1.479363, 0.353144, -1.75], [1.470637, 1.353106, -1.75]];
const num_rightPos = [[-1.470637, 1.353106, -1.75], [-1.479363, 0.353144, -1.75], [-1.479363, 0.353144, 1.75], [-1.470637, 1.353106, 1.75]];
const vehicle_num_forwardsPos = getCubeVertices([-1.4375, 0.625, -10.4875], [1.4375, 0, -10.4875], [0, 0.3125, -10.4875], -10, 0, 0);
const vehicle_num_backwardsPos = getCubeVertices([1.4375, 0.625, 10.4875], [-1.4375, 0, 10.4875], [0, 0.3125, 10.4875], 10, 0, 0);

let num_slotCfg = {
    "version": 1,
    "texSize": [1120, 240],
    "slots": [
        {
            "name": "num_left",
            "texArea": [0, 0, 1120, 240],
            "pos": [num_leftPos],
            "offsets": [[0, 0, 0]]
        },
        {
            "name": "num_right",
            "texArea": [0, 0, 1120, 240],
            "pos": [num_rightPos],
            "offsets": [[0, 0, 0]]
        }
    ]
};

let vehicleNumForwards_slotCfg = {
    "version": 1,
    "texSize": [1120, 240],
    "slots": [
        {
            "name": "vehicle_num_forwards",
            "texArea": [0, 0, 1120, 240],
            "pos": [vehicle_num_forwardsPos],
            "offsets": [[0, 0, 0]]
        }
    ]
};

let vehicleNumBackwards_slotCfg = {
    "version": 1,
    "texSize": [1120, 240],
    "slots": [
        {
            "name": "vehicle_num_backwards",
            "texArea": [0, 0, 1120, 240],
            "pos": [vehicle_num_backwardsPos],
            "offsets": [[0, 0, 0]]
        }
    ]
};

var num_dhBase = new DisplayHelper(num_slotCfg);
var vehicleNumForwards_dhBase = new DisplayHelper(vehicleNumForwards_slotCfg);
var vehicleNumBackwards_dhBase = new DisplayHelper(vehicleNumBackwards_slotCfg);

function create(ctx, state, vehicle) {
    for (let i = 1; i <= vehicle.getCarCount(); i++) {
        state[`num_dh${i}`] = num_dhBase.create();
    }
    state.dhForwards = vehicleNumForwards_dhBase.create();
    state.dhBackwards = vehicleNumBackwards_dhBase.create();
    state.sidingNumBefore = "undefined";
}

function render(ctx, state, vehicle) {
    if (state.sidingNumBefore != vehicle.getSiding().getName()) {
        var sidingName = vehicle.getSiding().getName();
        var idx = sidingName.indexOf("/");
        if (idx !== -1) {
            var vehicleNum = sidingName.substring(0, idx);
            sidingName = sidingName.substring(idx + 1);
        }
        var carNum = sidingName.split("-");

        print("本列车车号为：" + vehicleNum + "，每节车厢的编号分别是：");
        for (let i = 0; i < carNum.length; i++) print(carNum[i]);

        for (let i = 1; i <= vehicle.getCarCount(); i++) {
            state[`num_dh${i}`].close();

            if (i == 1) {
                state[`num_dh${i}`] = num_dhBase.create();

                if (vehicle.getCarCount() !== carNum.length) {
                    drawError(state[`num_dh${i}`].graphicsFor("num_left"));
                    drawError(state[`num_dh${i}`].graphicsFor("num_right"));
                    state[`num_dh${i}`].upload();
                    continue;
                }

                drawNum(state[`num_dh${i}`].graphicsFor("num_left"), carNum[i - 1], 60);
                drawNum(state[`num_dh${i}`].graphicsFor("num_right"), carNum[i - 1], 60);
                state[`num_dh${i}`].upload();

                state.dhForwards.close();
                state.dhForwards = vehicleNumForwards_dhBase.create();

                drawNum(state.dhForwards.graphicsFor("vehicle_num_forwards"), vehicleNum, 30);
                state.dhForwards.upload();
                print("车号位于：" + JSON.stringify(vehicle_num_forwardsPos));

                continue;
            }

            if (i == vehicle.getCarCount()) {
                state[`num_dh${i}`] = num_dhBase.create();

                if (vehicle.getCarCount() !== carNum.length) {
                    drawError(state[`num_dh${i}`].graphicsFor("num_left"));
                    drawError(state[`num_dh${i}`].graphicsFor("num_right"));
                    state[`num_dh${i}`].upload();
                    continue;
                }

                drawNum(state[`num_dh${i}`].graphicsFor("num_left"), carNum[i - 1], 60);
                drawNum(state[`num_dh${i}`].graphicsFor("num_right"), carNum[i - 1], 60);
                state[`num_dh${i}`].upload();

                state.dhBackwards.close();
                state.dhBackwards = vehicleNumBackwards_dhBase.create();

                drawNum(state.dhBackwards.graphicsFor("vehicle_num_backwards"), vehicleNum, 30);
                state.dhBackwards.upload();
                print("车号位于：" + JSON.stringify(vehicle_num_backwardsPos));

                continue;
            }

            state[`num_dh${i}`] = num_dhBase.create();

            if (vehicle.getCarCount() !== carNum.length) {
                drawError(state[`num_dh${i}`].graphicsFor("num_left"));
                drawError(state[`num_dh${i}`].graphicsFor("num_right"));
                state[`num_dh${i}`].upload();
                continue;
            }

            drawNum(state[`num_dh${i}`].graphicsFor("num_left"), carNum[i - 1], 60);
            drawNum(state[`num_dh${i}`].graphicsFor("num_right"), carNum[i - 1], 60);
            state[`num_dh${i}`].upload();
        }

        state.sidingNumBefore = vehicle.getSiding().getName();
    }

    for (let i = 0; i < vehicle.getCarCount(); i++) {
        ctx.drawCarModel(state[`num_dh${i + 1}`].model, i, null);
        if (i == 0) {
            ctx.drawCarModel(state.dhForwards.model, i, null);
        } else if (i == vehicle.getCarCount() - 1) {
            ctx.drawCarModel(state.dhBackwards.model, i, null);
        }
    }
}

function dispose(ctx, state, vehicle) {
    for (let i = 1; i <= vehicle.getCarCount(); i++) {
        state[`num_dh${i}`].close();
    }
    state.dhForwards.close();
    state.dhBackwards.close();
}

function getCubeVertices(p1, p2, center, rx, ry, rz) {
    const rxRad = rx * Math.PI / 180;
    const ryRad = ry * Math.PI / 180;
    const rzRad = rz * Math.PI / 180;

    let c = new Vector3f(center[0], center[1], center[2]);

    if (p1[1] == p2[1]) {
        let v1 = new Vector3f(p1[0], p1[1], p1[2]);
        let v2 = new Vector3f(p2[0], p1[1], p1[2]);
        let v3 = new Vector3f(p2[0], p2[1], p2[2]);
        let v4 = new Vector3f(p1[0], p2[1], p2[2]);

        v1.sub(c);
        v1.rotX(rxRad);
        v1.rotY(ryRad);
        v1.rotZ(rzRad);
        v1.add(c);

        v2.sub(c);
        v2.rotX(rxRad);
        v2.rotY(ryRad);
        v2.rotZ(rzRad);
        v2.add(c);

        v3.sub(c);
        v3.rotX(rxRad);
        v3.rotY(ryRad);
        v3.rotZ(rzRad);
        v3.add(c);

        v4.sub(c);
        v4.rotX(rxRad);
        v4.rotY(ryRad);
        v4.rotZ(rzRad);
        v4.add(c);

        return [
            [v1.x(), v1.y(), v1.z()],
            [v2.x(), v2.y(), v2.z()],
            [v3.x(), v3.y(), v3.z()],
            [v4.x(), v4.y(), v4.z()]
        ];
    }
    else if (p1[0] == p2[0]) {
        let v1 = new Vector3f(p1[0], p1[1], p1[2]);
        let v2 = new Vector3f(p1[0], p2[1], p1[2]);
        let v3 = new Vector3f(p2[0], p2[1], p2[2]);
        let v4 = new Vector3f(p2[0], p1[1], p2[2]);

        v1.sub(c);
        v1.rotX(rxRad);
        v1.rotY(ryRad);
        v1.rotZ(rzRad);
        v1.add(c);

        v2.sub(c);
        v2.rotX(rxRad);
        v2.rotY(ryRad);
        v2.rotZ(rzRad);
        v2.add(c);

        v3.sub(c);
        v3.rotX(rxRad);
        v3.rotY(ryRad);
        v3.rotZ(rzRad);
        v3.add(c);

        v4.sub(c);
        v4.rotX(rxRad);
        v4.rotY(ryRad);
        v4.rotZ(rzRad);
        v4.add(c);

        return [
            [v1.x(), v1.y(), v1.z()],
            [v2.x(), v2.y(), v2.z()],
            [v3.x(), v3.y(), v3.z()],
            [v4.x(), v4.y(), v4.z()]
        ];
    }
    else if (p1[2] == p2[2]) {
        let v1 = new Vector3f(p1[0], p1[1], p1[2]);
        let v2 = new Vector3f(p1[0], p1[1], p2[2]);
        let v3 = new Vector3f(p2[0], p2[1], p2[2]);
        let v4 = new Vector3f(p2[0], p2[1], p1[2]);

        v1.sub(c);
        v1.rotX(rxRad);
        v1.rotY(ryRad);
        v1.rotZ(rzRad);
        v1.add(c);

        v2.sub(c);
        v2.rotX(rxRad);
        v2.rotY(ryRad);
        v2.rotZ(rzRad);
        v2.add(c);

        v3.sub(c);
        v3.rotX(rxRad);
        v3.rotY(ryRad);
        v3.rotZ(rzRad);
        v3.add(c);

        v4.sub(c);
        v4.rotX(rxRad);
        v4.rotY(ryRad);
        v4.rotZ(rzRad);
        v4.add(c);

        return [
            [v1.x(), v1.y(), v1.z()],
            [v2.x(), v2.y(), v2.z()],
            [v3.x(), v3.y(), v3.z()],
            [v4.x(), v4.y(), v4.z()]
        ];
    }
    else {
        throw "指定对角顶点不与地面垂直或平行：顶点一 [" + p1 + "]，顶点二 [" + p2 + "]。";
    }
}