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

include(Resources.id("mtrsteamloco:scripts/display_helper.js"));
include("draw_lcd.js");
// include("mtr_util.js");

var meetNTEVersionRequirement = Resources.getNTEVersionInt() >= 402;
var isMTR4 = Resources.getMTRVersion().includes("4.0");

var slotCfg = {
    "version": 1,
    "texSize": [2048, 1024],
    "slots": [
        {
            "name": "lcd_door_left",
            "texArea": [0, 0, 2048, 402],
            "pos": [
                [[-0.945, 2.2, -5.73], [-0.995, 2, -5.73], [-0.995, 2, -6.78], [-0.945, 2.2, -6.78]]
            ],
            "offsets": [[0, 0, 0], [0.014, 0, 6.265], [0.014, 0, 12.53]]
        },
        {
            "name": "lcd_door_right",
            "texArea": [0, 512, 2048, 402],
            "pos": [
                [[0.945, 2.2, -6.78], [0.995, 2, -6.78], [0.995, 2, -5.73], [0.945, 2.2, -5.73]]
            ],
            "offsets": [[-0.014, 0, 0], [-0.014, 0, 6.265], [-0.014, 0, 12.53]]
        }
    ]
};

var dhBase = new DisplayHelper(slotCfg);

function create(ctx, state, train) {
    state.dh = dhBase.create();

    if (!meetNTEVersionRequirement || isMTR4) {
        let g = state.dh.graphicsFor("lcd_door_left");
        drawBlueScreen(g, 2048, 402);

        g = state.dh.graphicsFor("lcd_door_right");
        drawBlueScreen(g, 2048, 402);

        state.dh.upload();

        return;
    }

    state.routeMapType = "full";
    state.routeMapToggleTime = 0;
    state.arrowAnimationFrame = 0;
    state.flashPhase = 0;
    state.doorAnimationOffset = 0;
    state.doorAnimationDirection = 1;
    state.pisRateLimit = new RateLimit(0.05);
}

function drawBlueScreen(g, width, height) {
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, width, height);

    let font = ROBOTO_BOLD.deriveFont(66.0);
    let fm = g.getFontMetrics(font);
    g.setFont(font);
    g.setColor(Color.WHITE);
    let x = (width - fm.stringWidth("NO SIGNAL")) / 2;
    let y = (height - fm.getHeight()) / 2 + fm.getAscent();
    g.drawString("NO SIGNAL", x, y);

    font = ROBOTO_REGULAR.deriveFont(32.0);
    fm = g.getFontMetrics(font);
    g.setFont(font);
    x = width - 30 - fm.stringWidth("HDMI 1");
    y = 30 + fm.getAscent();
    g.drawString("HDMI 1", x, y);

    font = ROBOTO_REGULAR.deriveFont(16.0);
    fm = g.getFontMetrics(font);
    g.setFont(font);
    x = width - 30 - fm.stringWidth("1920x1080 60Hz");
    y += fm.getAscent() + 5;
    g.drawString("1920x1080 60Hz", x, y);
}

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

function render(ctx, state, train) {
    for (let i = 0; i < train.trainCars(); i++) {
        ctx.drawCarModel(state.dh.model, i, null);
    }

    if (!meetNTEVersionRequirement || isMTR4) {
        return;
    }

    let trainStatus = getTrainStatus(train);

    if (!state.lastDoorOpeningState) {
        state.lastDoorOpeningState = train.isDoorOpening();
    }
    if (!state.lastRailProgress) {
        state.lastRailProgress = train.getRailProgress(0);
    }

    if (trainStatus == STATUS_ARRIVED) {
        if (train.isDoorOpening()) {
        } else if (state.lastDoorOpeningState) {
        } else {
            let currentProgress = train.getRailProgress(0);
            if (Math.abs(currentProgress - state.lastRailProgress) > 0.01) {
                trainStatus = STATUS_ON_ROUTE;
            }
        }
    }

    state.lastDoorOpeningState = train.isDoorOpening();
    state.lastRailProgress = train.getRailProgress(0);

    if (trainStatus == STATUS_ON_ROUTE) {
        state.routeMapToggleTime++;
        if (state.routeMapToggleTime >= 300) {
            if (state.routeInfo && state.routeInfo.stationInfoList && state.routeInfo.stationInfoList.length > 3) {
                state.routeMapType = state.routeMapType === "full" ? "section" : "full";
            } else {
                state.routeMapType = "full";
            }
            state.routeMapToggleTime = 0;
        }
    } else {
        state.routeMapType = "full";
        state.routeMapToggleTime = 0;
    }

    if (!state.doorAnimationOffset) {
        state.doorAnimationOffset = 0;
    }
    if (!state.doorAnimationDirection) {
        state.doorAnimationDirection = 1;
    }

    let doorValue = train.doorValue();
    let doorThisSide = train.doorLeftOpen[0];
    let shouldAnimate = doorValue > 0 && doorThisSide;

    if (shouldAnimate) {
        state.doorAnimationOffset += 0.5 * state.doorAnimationDirection;
        if (state.doorAnimationOffset >= 20 || state.doorAnimationOffset <= 0) {
            state.doorAnimationDirection *= -1;
        }
    } else {
        state.doorAnimationOffset = 0;
        state.doorAnimationDirection = 1;
    }

    let shouldUpdate = state.pisRateLimit.shouldUpdate();
    if (shouldAnimate) {
        shouldUpdate = true;
    }

    if (train.shouldRender() && train.shouldRenderDetail() && shouldUpdate) {
        if (!checkProperty(state, "trainStatus", trainStatus)) {
            print("列车 " + train.id() + " 状态更新为：" + trainStatus);
            state.trainStatus = trainStatus;
        }

        let platformInfo;
        switch (trainStatus) {
            case STATUS_NO_ROUTE:
                platformInfo = null;
                break;
            case STATUS_RETURNING_TO_DEPOT:
                platformInfo = train.getAllPlatforms().get(train.getAllPlatforms().size() - 1);
                break;
            case STATUS_WAITING_FOR_DEPARTURE:
                platformInfo = train.getAllPlatforms().get(0);
                break;
            case STATUS_CHANGING_ROUTE:
                platformInfo = train.getAllPlatforms().get(train.getAllPlatformsNextIndex());
                break;
            default:
                platformInfo = train.getThisRoutePlatforms().get(train.getThisRoutePlatformsNextIndex());
                break;
        }

        const routeInfo = getRouteInfo(train, trainStatus, platformInfo);
        if (!checkJsonProperty(state, "routeInfo", routeInfo)) {
            print("列车 " + train.id() + " 的当前路线信息：" + JSON.stringify(routeInfo));
            state.routeInfo = routeInfo;
        }

        const doorOpeningSide = getDoorOpeningSide(train);
        if (!checkJsonProperty(state, "doorOpeningSide", doorOpeningSide)) {
            print("列车 " + train.id() + " 的开门方向：" + doorOpeningSide);
            state.doorOpeningSide = doorOpeningSide;
        }

        let nextStationIndex = trainStatus == STATUS_RETURNING_TO_DEPOT ? 1 : train.getThisRoutePlatformsNextIndex();

        let g = state.dh.graphicsFor("lcd_door_left");
        drawScreen(slotCfg.slots[0].texArea[2], slotCfg.slots[0].texArea[3], g, state.routeInfo, null, nextStationIndex, trainStatus, false, state.doorOpeningSide, train.isReversed(), train, state);

        g = state.dh.graphicsFor("lcd_door_right");
        drawScreen(slotCfg.slots[1].texArea[2], slotCfg.slots[1].texArea[3], g, state.routeInfo, null, nextStationIndex, trainStatus, true, state.doorOpeningSide, !train.isReversed(), train, state);

        state.dh.upload();
    }
}