importClass(java.awt.RenderingHints);
importClass(java.awt.image.BufferedImage);

function drawDisp(g, drawableRoute, texArea, state, train, trainConfig) {
    const originalClip = g.getClip();

    const dispFont = loadResource("font", trainConfig.dispFont);

    const imgLogo = loadResource("img", "mtrsteamloco:lcds/bj_new/logo.png");
    const imgDoor = loadResource("img", "mtrsteamloco:lcds/bj_new/door.png");

    let [x, y, w, h] = texArea;
    let trainStatus = drawableRoute.trainStatus;
    let { routeName, routeColor } = drawableRoute;

    if (!drawableRoute.finalFullRouteStations) return;

    let stations = drawableRoute.finalFullRouteStations;
    let index = drawableRoute.fullRouteIndex;
    if (index > stations.length - 1) index = stations.length - 1;

    let finalStr = String(state.dispText);

    let nextStn = stations[index];

    let stateChanged = state.dispCacheState != trainStatus;
    if (stateChanged) {
        finalStr = "";
        state.dispCacheState = trainStatus;
        state.beginTime = new Date().getTime() / 1000;
        if (trainStatus == STATUS_MAP.CHANGING || trainStatus == STATUS_MAP.DEPARTING || index == 0) {
            if (hasCjkPart(routeName)) finalStr += `欢迎乘坐地铁${getMatching(routeName, true)}列车! `;
            if (hasNonCjkPart(routeName)) finalStr += `Welcome to subway ${getMatching(routeName, false)}! `;
        } else if (trainStatus == STATUS_MAP.RUNNING) {
            if (hasCjkPart(nextStn.stationName)) {
                if (index != stations.length - 1) finalStr += `下一站: ${getMatching(nextStn.stationName, true)}。 `;
                else finalStr += `下一站是本次列车的终点站${getMatching(nextStn.stationName, true)}。 `;
                if (nextStn.transInfo.length > 0) {
                    let transNames = "换乘";
                    for (let i = 0; i < nextStn.transInfo.length; i++) {
                        let thisInfo = nextStn.transInfo[i];
                        if (hasCjkPart(thisInfo.routeName)) {
                            if (i > 0) transNames += "、";
                            transNames += getMatching(thisInfo.routeName, true);
                        }
                    }
                    transNames += "的乘客, 请准备下车。 ";
                    finalStr += transNames;
                }
            }
            if (hasNonCjkPart(nextStn.stationName)) {
                if (index != stations.length - 1) finalStr += `Next station: ${getMatching(nextStn.stationName, false)}. `;
                else finalStr += `Next station: ${getMatching(nextStn.stationName, false)} where the train terminates here. `;
                if (nextStn.transInfo.length > 0) {
                    let transNames = "Change here for ";
                    for (let i = 0; i < nextStn.transInfo.length; i++) {
                        let thisInfo = nextStn.transInfo[i];
                        if (hasNonCjkPart(thisInfo.routeName)) {
                            if (i > 0 && i < nextStn.transInfo.length - 1) transNames += ", ";
                            else if (i != 0 && i == nextStn.transInfo.length - 1) transNames += " or ";
                            transNames += getMatching(thisInfo.routeName, false);
                        }
                    }
                    transNames += ". ";
                    finalStr += transNames;
                }
            }
        } else if (trainStatus == STATUS_MAP.ARRIVED) {
            if (hasCjkPart(nextStn.stationName)) {
                if (index != stations.length - 1) finalStr += `列车即将到达${getMatching(nextStn.stationName, true)}。 `;
                else {
                    finalStr += `列车即将到达的是本次列车的终点站${getMatching(nextStn.stationName, true)}。 `;
                    if (hasCjkPart(routeName)) finalStr += `感谢您乘坐地铁${getMatching(routeName, true)}列车。 `;
                }
            }
            if (hasNonCjkPart(nextStn.stationName)) {
                if (index != stations.length - 1) finalStr += `We are now arriving at ${getMatching(nextStn.stationName, false)}. `;
                else {
                    finalStr += `We are now arriving at ${getMatching(nextStn.stationName, false)}. This train terminates here. `;
                    if (hasNonCjkPart(routeName)) finalStr += `Thank you for traveling on subway ${getMatching(routeName, false)}. `;
                }
            }
        }
        state.dispText = finalStr;
    }
    state.dispCacheState = trainStatus;

    drawMatrix(g, x, y, w, h, finalStr, dispFont, state, stateChanged);
}

function drawMatrix(g, x, y, w, h, str, baseFont, state, stateChanged) {
    var t = new Date().getTime() / 1000 - state.beginTime;

    /* ===============================
     *  内部显示开关
     * =============================== */
    var DRAW_OFF_PIXELS = false; // true=画灭灯，false=只画亮灯

    /* ===============================
     *  点阵参数（与你原逻辑一致）
     * =============================== */
    var targetCell = 4.5;
    var rows = Math.max(6, Math.floor(h / targetCell));
    var cell = h / rows;

    var dot = Math.max(2, Math.floor(cell * 0.95));
    var gap = Math.max(1, Math.floor(cell - dot));
    var step = dot + gap;
    var cols = Math.floor(w / step);
    if (rows <= 0 || cols <= 0) return;

    /* ===============================
     *  是否重建 bitmap（只信 stateChanged）
     * =============================== */
    var needRebuild = stateChanged || !state.dispBitmapCols || !state.dispBitmapCols.length;

    if (needRebuild) {
        var fontSize = Math.floor(rows * 0.75);

        var font = baseFont.deriveFont(Font.PLAIN, fontSize);
        var frc = new FontRenderContext(null, false, false);

        var gv = font.createGlyphVector(frc, str);
        var vb = gv.getVisualBounds();
        var textWidth = Math.max(1, Math.ceil(vb.getWidth()));

        var imgW = textWidth + step * 2;
        var imgH = rows;

        var img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_BYTE_BINARY);

        var ig = img.createGraphics();
        ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        ig.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

        ig.setFont(font);
        ig.setColor(Color.WHITE);

        var fm = ig.getFontMetrics(font);
        var ascent = fm.getAscent();
        var descent = fm.getDescent();
        var textHeight = ascent + descent;

        // 垂直居中（修复点）
        var textY = Math.floor((imgH - textHeight) * 0.5 + ascent);

        ig.drawString(str, step, textY);
        ig.dispose();

        var bitmapCols = [];
        for (var ix = 0; ix < imgW; ix++) {
            var col = new Array(rows);
            for (var iy = 0; iy < rows; iy++) {
                col[iy] = (img.getRGB(ix, iy) & 0xffffff) !== 0;
            }
            bitmapCols.push(col);
        }

        state.dispBitmapCols = bitmapCols;
        state.dispRows = rows;
        state.dispDot = dot;
        state.dispGap = gap;
        state.dispStep = step;
        state.dispFontSize = fontSize;
    }

    var bitmap = state.dispBitmapCols;
    if (!bitmap || bitmap.length === 0) return;

    /* ===============================
     *  滚动（列级）
     * =============================== */
    var scrollSpeed = 60;
    var totalCols = bitmap.length + cols;
    var colOffset = Math.floor(t * scrollSpeed) % totalCols;

    var oldComp = g.getComposite();
    g.setComposite(AlphaComposite.Clear);
    g.fillRect(x, y, w, h);
    g.setComposite(oldComp);

    /* ===============================
     *  绘制
     * =============================== */
    var onColor = rgbToColor(255, 40, 40);
    var offColor = rgbToColor(6, 1, 1);

    for (var ry = 0; ry < rows; ry++) {
        var py = y + ry * step;
        for (var rx = 0; rx < cols; rx++) {
            var srcCol = rx + colOffset - cols;
            var on = srcCol >= 0 && srcCol < bitmap.length && bitmap[srcCol][ry];

            if (on) {
                g.setColor(onColor);
                g.fillOval(x + rx * step, py, dot, dot);
            } else if (DRAW_OFF_PIXELS) {
                g.setColor(offColor);
                g.fillOval(x + rx * step, py, dot, dot);
            }
        }
    }
}
