importPackage(java.awt);
importPackage(java.awt.geom);
include("lcd.js");
include("ikisaki.js");
let g;
let errorImage = Resources.readBufferedImage(Resources.id("mtr:tx_3000_lcd/images/kr.png"));
function create(ctx, state, train) {
    state.dh = dhBase.create();
    state.rate = new RateLimit(0.5);
    state.modelRate = new RateLimit(0.05);

    state.rawMasconModel = ModelManager.loadRawModel(Resources.manager(), Resources.id("mtr:tx_3000/tx_3000_masukon.obj"), null);
    //state.rawDaisyaModel = ModelManager.loadRawModel(Resources.manager(), Resources.id("mtr:tx_3000/tx_3000_daisya_cycle.obj"), null);
    state.rawWiper1BModel = ModelManager.loadRawModel(Resources.manager(), Resources.id("mtr:tx_3000/tx_3000_wiper1_branch.obj"), null);
    state.rawWiper1MModel = ModelManager.loadRawModel(Resources.manager(), Resources.id("mtr:tx_3000/tx_3000_wiper1_main.obj"), null);

    state.dmhMascon = new DynamicModelHolder();
    state.dmhMascon1 = new DynamicModelHolder();
    //state.dmhWheel = new DynamicModelHolder();
    state.dmhWiper1B = new DynamicModelHolder();
    state.dmhWiper1M = new DynamicModelHolder();

    state.dmhMascon.uploadLater(state.rawMasconModel);
    state.dmhMascon1.uploadLater(state.rawMasconModel);
    //state.dmhWheel.uploadLater(state.rawDaisyaModel);
    state.dmhWiper1B.uploadLater(state.rawWiper1BModel);
    state.dmhWiper1M.uploadLater(state.rawWiper1MModel);

    // ノッチの状態保存
    state.lastNotch = null;
    //車輪の円周が2.848m
    //state.wheelCircumference = 2.848;
    // 車輪角度
    //state.wheelRotation = 0;
    // ワイパー角度の保存
    state.wiperAngle = 0;
}

function dispose(ctx, state, train) {
    state.dh.close();
    state.dmhMascon.close();
    //state.dmhWheel.close();
}

function render(ctx, state, train) {
    if (train.shouldRender() && state.rate.shouldUpdate()) {
        if (train.isReversed()) {
            try {
                g = state.dh.graphicsFor("lcd_door_right");
                lcdmain(g, train);
                lcdleft(g, train);

                g = state.dh.graphicsFor("lcd_door_left");
                lcdmain(g, train);
                lcdright(g, train);
            } catch (e) {
                print("Error:" + e);
                g = state.dh.graphicsFor("lcd_door_right");
                g.drawImage(errorImage, 398, 90, 100, 100, null);
                g = state.dh.graphicsFor("lcd_door_left");
                g.drawImage(errorImage, 398, 90, 100, 100, null);
            }
        } else {
            try {
                g = state.dh.graphicsFor("lcd_door_left");
                lcdmain(g, train);
                lcdleft(g, train);
                g = state.dh.graphicsFor("lcd_door_right");
                lcdmain(g, train);
                lcdright(g, train);
            } catch (e) {
                print("Error:" + e);
                g = state.dh.graphicsFor("lcd_door_right");
                g.drawImage(errorImage, 398, 90, 100, 100, null);
                g = state.dh.graphicsFor("lcd_door_left");
                g.drawImage(errorImage, 398, 90, 100, 100, null);
            }
        }
        //行き先表示
        try {
            g = state.dh.graphicsFor("out_left");
            ikisakiMain(g, train);
            g = state.dh.graphicsFor("out_right");
            ikisakiMain(g, train);
            g = state.dh.graphicsFor("out_front");
            ikisakiFront(g, train);
            g = state.dh.graphicsFor("out_back");
            ikisakiFront(g, train);
        } catch (e) {
            print("Error:" + e);
            g = state.dh.graphicsFor("out_left");
            g.drawImage(errorImage, 190, 30, 100, 100, null);
            g = state.dh.graphicsFor("out_right");
            g.drawImage(errorImage, 190, 30, 100, 100, null);
            g = state.dh.graphicsFor("out_front");
            g.drawImage(errorImage, 190, 30, 100, 100, null);
            g = state.dh.graphicsFor("out_back");
            g.drawImage(errorImage, 190, 30, 100, 100, null);
        }
        state.dh.upload();
    }
    for (let i = 0; i < train.trainCars(); i++) {
        if (state.modelRate.shouldUpdate()) {
            let notch = ctx.train.manualNotch;
            let angle;
            switch (notch) {
                case 2:
                    angle = -55;
                    break;
                case 1:
                    angle = -47.5;
                    break;
                case 0:
                    angle = -40;
                    break;
                case -1:
                    angle = -12.5;
                    break;
                case -2:
                    angle = 15;
                    break;
                case -3:
                    angle = 35;
                    break;
                default:
                    angle = -40;
            }

            if (state.lastNotch !== notch) {
                state.lastNotch = notch;

                let rotatedModel = state.rawMasconModel.copy();  // 元モデルは変更しない

                const centerX = 1.14064;
                const centerY = 1.16607;
                const centerZ = 9.30228;//符号が逆

                rotatedModel.applyTranslation(-centerX, -centerY, -centerZ);
                rotatedModel.applyRotation(new Vector3f(1, 0, 0), angle);  // 角度は度単位（公式仕様）
                rotatedModel.applyTranslation(centerX, centerY, centerZ);

                state.dmhMascon.uploadLater(rotatedModel);

                let rotatedModel1 = state.rawMasconModel.copy();

                rotatedModel1.applyTranslation(-centerX, -centerY, -centerZ);
                rotatedModel1.applyRotation(new Vector3f(1, 0, 0), angle);  // 角度は度単位（公式仕様）
                rotatedModel1.applyTranslation(centerX, centerY, centerZ);
                rotatedModel1.applyRotation(new Vector3f(0, 1, 0), 180);  // 後尾車用

                state.dmhMascon1.uploadLater(rotatedModel1);
            }
        }

        // 描画時には変換行列なし（頂点が回転済みのため）
        let modelToDraw = state.dmhMascon.getUploadedModel();
        let modelToDraw1 = state.dmhMascon1.getUploadedModel();
        if (modelToDraw != null) {
            ctx.drawCarModel(modelToDraw, 0, null);
            ctx.drawCarModel(modelToDraw1, train.trainCars() - 1, null);
        }

        //車輪の描画
        // let speed = train.speed() || 0;
        // const rotationPerMeter = 360 / state.wheelCircumference;
        // let deltaAngle = speed * rotationPerMeter;
        // state.wheelRotation = (state.wheelRotation + deltaAngle) % 360;

        // let matrices = new Matrices();
        // matrices.pushPose();
        // const cx = 0.552906, cy = -0.36, cz = 7.68796;
        // matrices.translate(-cx, -cy, -cz);
        // matrices.rotateX(state.wheelRotation);
        // matrices.translate(cx, cy, cz);

        // let wheelModel = state.dmhWheel.getUploadedModel();
        // if (wheelModel != null) {
        //     ctx.drawCarModel(wheelModel, i, matrices);
        // }
        // matrices.popPose();
        let matrices = new Matrices();
        matrices.pushPose();

        if (MinecraftClient.worldIsRainingAt(train.lastCarPosition[0])) {
            //ワイパー
            state.wiperAngle = getWiperAngle();
        } else {
            state.wiperAngle = 0;
        }

        // ワイパー支える部分(ブランチ)描画

        // 回転中心（付け根）に移動
        const wiper1BX = -0.828847;
        const wiper1BY = -1.06347;
        const wiper1BZ = 9.96597;

        matrices.translate(-wiper1BX, -wiper1BY, -wiper1BZ);

        // Z軸回転＋X軸回転
        matrices.rotateZ(-state.wiperAngle * Math.PI / 180);
        //matrices.rotateX(-state.wiperAngle / 5.333 * Math.PI / 180);

        // 元位置に戻す
        matrices.translate(wiper1BX, wiper1BY, wiper1BZ);

        // モデルのnullチェックと描画ループ
        let wiperModel1B = state.dmhWiper1B.getUploadedModel();
        if (wiperModel1B != null) {
            ctx.drawCarModel(wiperModel1B, 0, matrices);
        }
        matrices.popPose();

        //main
        let matricesMain = new Matrices();
        matricesMain.pushPose();
        matricesMain.translate(state.wiperAngle / 68.5, state.wiperAngle / 300, 0);

        let wiper1MModel = state.dmhWiper1M.getUploadedModel();
        if (wiper1MModel != null) {
            ctx.drawCarModel(wiper1MModel, 0, matricesMain);
        }
        matricesMain.popPose();

        // LCD描画
        ctx.drawCarModel(state.dh.model, i, null);
    }
}

const PHASE1 = 750;   // 0～0.75秒: 0°→80°
const PHASE2 = 1500;  // 0.75～1.5秒: 80°→0°
const ANGLE_MAX = 80; // 最大角度80度

function getWiperAngle() {
    let t = Date.now() % 5000;  // 0～4999 msの現在位相

    if (t < PHASE1) {
        // 0°→80°にリニアに増加
        let phase = t / PHASE1;
        return phase * ANGLE_MAX;
    } else if (t < PHASE2) {
        // 80°→0°にリニアに減少
        let phase = (t - PHASE1) / (PHASE2 - PHASE1);
        return ANGLE_MAX * (1 - phase);
    } else {
        // 1秒以降は0°
        return 0;
    }
}