var draw = function (g, state, drawInfo, extraConfig) {
    if (!extraConfig) {
        setDebugInfo(JSON.stringify(extraConfig));
        extraConfig = {};
    }
    var arrivalInfoList = drawInfo.arrivalInfoList;
    var texArea = drawInfo.texArea;
    var x = texArea[0];
    var y = texArea[1];
    var w = texArea[2];
    var h = texArea[3];
    var ctx = drawInfo.ctx;
    var block = drawInfo.block;

    g.drawImage(loadResource("img", "fangsu:pids/beijing/beijing_a.png"), x, y, w, h, null);

    var extraImage = extraConfig.imgPath;
    var shouleRendExtraImage = extraImage;
    var extraImageType = extraConfig.imgType ? extraConfig.imgType : "img";
    var extraBufferedImage;
    ctx.setDebugInfo("extraimage", "img: " + extraImage + " type: " + extraImageType);
    if (extraImageType == "png") extraBufferedImage = loadResource("img", extraImage);
    if (extraImageType == "gif") {
        extraBufferedImage = loadResource("gif", extraImage).getCurrent();
        drawInfo.ctx.setDebugInfo(loadResource("gif", extraImage).gt);
    }
    if (extraImageType == "webimg") {
        extraBufferedImage = loadResource("webimg", extraImage).get_awt_image();
        shouleRendExtraImage = extraBufferedImage.is_available();
    }
    if (shouleRendExtraImage) g.drawImage(extraBufferedImage, x + w * 0.40625, y + h * 0.09375, w * 0.59375, h * 0.72, null);

    if (typeof state.drawBeginTime === "undefined" || typeof state.drawFlag === "undefined") {
        state.drawBeginTime = Timing.elapsed();
        state.drawFlag = true;
    }
    if (typeof state.scollADrawBeginTime === "undefined") {
        state.scollADrawBeginTime = Timing.elapsed();
    }
    if (typeof state.scollBDrawBeginTime === "undefined" || typeof state.scollBDrawFlag === "undefined") {
        state.scollBDrawBeginTime = Timing.elapsed();
        state.scollBDrawFlag = true;
    }

    var baseFont = loadResource("systemFont", "方正姚体");

    g.setColor(rgbToColor(254, 243, 100));
    var timeStr = getWorldTime().h + ":" + getWorldTime().m;
    drawStrUnified(g, baseFont, timeStr, w * 0.1875, h * 0.2, h * 0.075, 1);

    var dateStr = formatDate(state.drawFlag);
    var weekdayStr = formatWeekday(state.drawFlag);
    drawStrUnified(g, baseFont, dateStr, w * 0.3, h * 0.07, h * 0.075, 1);
    drawStrUnified(g, baseFont, weekdayStr, w * 0.7, h * 0.07, h * 0.075, 1);

    var drawTotalTime = 5;

    drawStrUnified(g, baseFont, state.drawFlag ? "列车开往" : "Train to", w * 0.01, h * 0.33, h * 0.04, 0);
    drawStrUnified(g, baseFont, state.drawFlag ? "本次列车" : "This train", w * 0.01, h * 0.45, h * 0.04, 0);
    drawStrUnified(g, baseFont, state.drawFlag ? "下次列车" : "Next train", w * 0.01, h * 0.65, h * 0.04, 0);

    var arrivalInfo1 = arrivalInfoList[0];
    var arrivalInfo2 = arrivalInfoList[1];
    if (arrivalInfo1) {
        drawTotalTime = Math.max(
            drawTotalTime,
            drawScrollText(getMatching(arrivalInfo1.costomDestination || arrivalInfo1.destination, state.drawFlag), w * 0.2, w * 0.15, h * 0.375, baseFont.deriveFont(h * 0.07), state.drawBeginTime, 2)
        );
        drawStrUnified(g, baseFont, getDispArrival(parseInt((arrivalInfo1.arrivalMillis - Date.now()) / 1000), state.drawFlag), w * 0.1875, h * 0.55, h * 0.1, 1);
    }
    if (arrivalInfo2) drawStrUnified(g, baseFont, getDispArrival(parseInt((arrivalInfo2.arrivalMillis - Date.now()) / 1000), state.drawFlag), w * 0.1875, h * 0.75, h * 0.1, 1);

    // drawTotalTime = Math.max(drawTotalTime, drawScrollText());

    if (state.drawBeginTime + drawTotalTime < Timing.elapsed()) {
        state.drawBeginTime = Timing.elapsed();
        state.drawFlag = !state.drawFlag;
    }
    if (state.scollADrawBeginTime + scollADrawTotalTime < Timing.elapsed()) {
        state.scollADrawTotalTime = Timing.elapsed();
    }
    if (state.scollBDrawBeginTime + scollBDrawTotalTime < Timing.elapsed()) {
        state.scollBDrawBeginTime = Timing.elapsed();
        state.scollBDrawFlag = !state.scollBDrawFlag;
    }

    function drawScrollText(str, maxX, x, y, font, beginTime, forceScoll) {
        g.setFont(font);
        var thisWidth = g.getFontMetrics(font).stringWidth(str);
        if (thisWidth <= maxX && forceScoll !== true) {
            if (typeof forceScoll == "number") {
                switch (forceScoll) {
                    case 1:
                        g.drawString(str, x + (maxX - thisWidth) * 0.5, y);
                        return 0;
                    case 2:
                        g.drawString(str, x + maxX - thisWidth, y);
                        return 0;
                    default:
                }
            }
            g.drawString(str, x, y);
            return 0;
        }
        var originalClip = g.getClip();
        var totalTextLeng = g.getFontMetrics(font).stringWidth(str) + maxX;
        var speed = maxX * 0.25;
        var totalTime = parseInt(totalTextLeng / speed);
        g.setClip(new java.awt.Rectangle(x, y - g.getFontMetrics(font).getHeight() - 2, maxX, g.getFontMetrics(font).getHeight() * 1.25));
        g.drawString(str, x + maxX - ((Timing.elapsed() - beginTime - 0.1) % totalTime) * speed, y);
        g.setClip(originalClip);
        return totalTime;
    }

    function getDispArrival(time, flag) {
        if (time <= 2) return flag ? "列车到站" : "Arrived";
        else if (time <= 20) return flag ? "即将进站" : "Arriving";
        else if (time <= 60) return String(time) + (flag ? " 秒" : " sec");
        else if (time <= 3600) return String(parseInt(time / 60)) + (flag ? " 分" : " min");
        return String(parseInt(time / 3600)) + (flag ? " 时" : " hour");
    }

    function getWorldTime() {
        var totalTicks = MinecraftClient.worldDayTime();
        var hours = (parseInt(totalTicks / 1000) + 6) % 24;
        var minutes = parseInt((totalTicks % 1000) / 16.67);

        return {
            h: hours < 10 ? "0" + hours : String(hours),
            m: minutes < 10 ? "0" + minutes : String(minutes)
        };
    }
};
