//script core ver 3.0.4

// include(Resources.id("mtrsteamloco:scripts/config_screen.js"));
include(Resources.id("mtrsteamloco:scripts/color_util.js"));
include(Resources.id("mtrsteamloco:scripts/js_util.js"));
include(Resources.id("fangsu:scripts/pzx_helper.js"));
include(Resources.id("fangsu:scripts/costom_item_helper.js"));
include(Resources.id("fangsu:scripts/mtrselect.js"));
include(Resources.id("fangsu:scripts/config_sc.js"));
include(Resources.id("fangsu:scripts/model_select_screen.js"));
include(Resources.id("fangsu:scripts/gt_helper.js"));
importPackage(java.awt);
importPackage(java.awt.geom);

function create(ctx, state, block) {
    state.mainModel = checkAndCacheConfig(block, state, "mainModel", "fangsu:duanmen/beijing_duanmen.json");

    state.subModel = checkAndCacheConfig(block, state, "subModel", "beijing_duanmen_bg_1_right");

    state.doorTarget = checkAndCacheConfig(block, state, "doorTarget", false);

    // state.length = checkAndCacheConfig(block, state, "length", 2);

    state.showDiaobanDoorLight = checkAndCacheConfig(block, state, "showDiaobanDoorLight", false);
    state.diaobanMainModel = checkAndCacheConfig(block, state, "diaobanMainModel", "fangsu:diaoban/mtr_diaoban.json");
    state.diaobanSubModel = checkAndCacheConfig(block, state, "diaobanSubModel", "mtr_diaoban_a");

    state.rendCd = 0;
    state.shape = [];

    state.needRef = true;

    state.cacheConfig = {};
    state.config = {};

    state.cacheMat = {
        rX: block.rotateX,
        rY: block.rotateY,
        rZ: block.rotateZ,
        tX: block.translateX,
        tY: block.translateY,
        tZ: block.translateZ
    };

    state.doorVal = block.doorTarget ? 1 : 0;

    state.dmh = new DynamicModelHolder();
    state.dmhDoor = new DynamicModelHolder();
    state.dmhOpen = new DynamicModelHolder();

    state.dmhOn = new DynamicModelHolder();
    state.dmhOff = new DynamicModelHolder();

    state.gtRtColor = new GraphicsTexture(16, 16);
    state.gtRtColor.graphics.setColor(Color.WHITE);
    state.gtRtColor.graphics.fillRect(0, 0, 16, 16);
}
function render(ctx, state, block) {
    if (JSON.stringify(state.config) != "{}" && state.config) setDebugInfo(JSON.stringify(state.config));
    if (state.config.mainModel) state.mainModel = state.config.mainModel;
    if (state.config.subModel) state.subModel = state.config.subModel;
    if (state.config.doorTarget != undefined) state.doorTarget = state.config.doorTarget;
    // if (state.config.length) state.length = state.config.length;
    if (state.config.showDiaobanDoorLight != undefined) state.showDiaobanDoorLight = state.config.showDiaobanDoorLight;
    if (state.config.diaobanMainModel != undefined) state.diaobanMainModel = state.config.diaobanMainModel;
    if (state.config.diaobanSubModel != undefined) state.diaobanSubModel = state.config.diaobanSubModel;

    state.config = {};

    if (state.rendCd <= 0) {
        state.needRefBox = checkCache(block, state, "doorTarget");
        state.dispInfo_save = JSON.stringify(state.dispInfo);
        state.needRef =
            checkCache(block, state, "subModel") ||
            // ||checkCache(block, state, "length")
            state.needRef ||
            checkCache(block, state, "showDiaobanDoorLight") ||
            checkCache(block, state, "diaobanMainModel") ||
            checkCache(block, state, "diaobanSubModel");
        state.mainModelRef = checkCache(block, state, "mainModel");
    }
    if (state.needRef || state.mainModelRef) {
        let loaded = parseObj(JSON.parse(loadResource("str", state.mainModel)).content);
        if (state.subModel in loaded) state.model = loaded[state.subModel];
        else {
            if (state.mainModelRef) {
                state.model = JSON.parse(loadResource("str", state.mainModel)).content[0];
                block.putCustomConfig("subModel", state.model.key);
                block.sendUpdateC2S();
                state.mainModelRef = false;
            } else {
                setWarnInfo(`你似乎没有加载包含 ${state.mainModel}-${state.subModel} 的附属包 !`);
                state.needRef = false;
                return;
            }
        }

        let model = loadResource("partedModel", state.model.model);
        let modelMain = model.get(state.model.subModels.main).copy();
        modelMain.sourceLocation = null;
        if (state.model.flipV) modelMain.applyUVMirror(false, true);
        let modelDoor = model.get(state.model.subModels.door).copy();
        modelDoor.sourceLocation = null;
        if (state.model.flipV) modelDoor.applyUVMirror(false, true);

        state.dmh.uploadLater(modelMain);
        state.dmhDoor.uploadLater(modelDoor);

        if (state.model.subModels.open) {
            let modelOpen = model.get(state.model.subModels.open).copy();
            modelOpen.sourceLocation = null;
            if (state.model.flipV) modelOpen.applyUVMirror(false, true);
            state.dmhOpen.uploadLater(modelOpen);
        }

        if (state.model.withDiaobanDoorlight && state.showDiaobanDoorLight) {
            try {
                let loadedDiaoban = parseObj(JSON.parse(loadResource("str", state.diaobanMainModel)).content);
                if (state.diaobanSubModel in loadedDiaoban) state.diaobanModel = loadedDiaoban[state.diaobanSubModel];
                else {
                    setWarnInfo(`你似乎没有加载包含(吊板) ${state.mainModel}-${state.subModel} 的附属包 !`);
                    state.needRef = false;
                    return;
                }
                let diaobanModel = loadResource("partedModel", state.diaobanModel.model);
                let modelDlOn = diaobanModel.get(state.diaobanModel.doorlight.on).copy();
                modelDlOn.sourceLocation = null;
                modelDlOn.applyTranslation(state.model.withDiaobanDoorlight.pos[0], state.model.withDiaobanDoorlight.pos[1], state.model.withDiaobanDoorlight.pos[2]);
                if (state.diaobanModel.flipV) modelDlOn.applyUVMirror(false, true);
                state.dmhOn.uploadLater(modelDlOn);
                let modelDlOff = diaobanModel.get(state.diaobanModel.doorlight.off).copy();
                modelDlOff.sourceLocation = null;
                modelDlOff.applyTranslation(state.model.withDiaobanDoorlight.pos[0], state.model.withDiaobanDoorlight.pos[1], state.model.withDiaobanDoorlight.pos[2]);
                if (state.diaobanModel.flipV) modelDlOff.applyUVMirror(false, true);
                state.dmhOff.uploadLater(modelDlOff);
            } catch (e) {
                setDebugInfo(e);
            }
        }

        state.needRef = false;
        state.needRefBox = true;
    }

    if (state.dmh.getUploadedModel() != null) {
        ctx.drawModel(state.dmh, null);
    }
    if (state.dmhDoor.getUploadedModel() != null) {
        let mat = new Matrices();
        mat.translate(state.model.doorPos[0], state.model.doorPos[1], state.model.doorPos[2]);
        mat.rotateY(0.5 * state.doorVal * state.model.doorAngle * Math.PI);
        mat.translate(-1 * state.model.doorPos[0], -1 * state.model.doorPos[1], -1 * state.model.doorPos[2]);
        ctx.drawModel(state.dmhDoor, mat);
    }
    if (state.model.subModels.open && state.dmhOpen.getUploadedModel() != null && state.doorVal > 0) {
        ctx.drawModel(state.dmhOpen, null);
    }

    if (state.model.withDiaobanDoorlight && state.showDiaobanDoorLight) {
        if (state.dmhOn.getUploadedModel() && state.dmhOff.getUploadedModel())
            try {
                if (state.doorVal > 0) ctx.drawModel(state.dmhOn, null);
                else ctx.drawModel(state.dmhOff, null);
            } catch (e) {}
    }

    if (state.doorTarget) {
        state.doorVal = 1;
    } else {
        state.doorVal = 0;
    }

    ctx.setDebugInfo("doorTarget", `${state.doorTarget} (${typeof state.doorTarget})`);

    if (
        state.cacheMat.rX != block.rotateX ||
        state.cacheMat.rY != block.rotateY ||
        state.cacheMat.rZ != block.rotateZ ||
        state.cacheMat.tX != block.translateX ||
        state.cacheMat.tY != block.translateY ||
        state.cacheMat.tZ != block.translateZ
    ) {
        // 如果有任一属性不同，则更新缓存并标记需要刷新
        state.cacheMat = {
            rX: block.rotateX,
            rY: block.rotateY,
            rZ: block.rotateZ,
            tX: block.translateX,
            tY: block.translateY,
            tZ: block.translateZ
        };
        state.needRefBox = true;
    }

    if (state.needRefBox == true) {
        let shape;
        if (state.model.shape) {
            shape = state.model.shape[state.doorTarget ? "open" : "close"];
            if (!shape) shape = [[0, 0, 0, 16, 16, 16]];
        } else shape = [[0, 0, 0, 16, 16, 16]];
        let finalShape = [];
        if (shape == [[0, 0, 0, 16, 16, 16]]) {
            finalShape = [[0, 0, 0, 16, 16, 16]];
        } else
            for (let subshape of shape) {
                // print(subshape);
                // print(rotateCollisionBox(subshape, Math.PI * block.rotateX, Math.PI * block.rotateY, Math.PI * block.rotateZ));
                finalShape = finalShape.concat(rotateCollisionBox(subshape, block, block.rotateX, block.rotateY, block.rotateZ, block.translateX * 16, block.translateY * 16, block.translateZ * 16));
            }
        // print(finalShape);
        finalShape = collisionBoxArrToStr(finalShape);
        // print(finalShape);
        block.setShape(finalShape);
        block.setCollisionShape(finalShape);
        block.sendUpdateC2S();
        state.needRefBox = false;
    }
    state.renderCD -= Timing.delta();
}

function dispose(ctx, state, block) {
    state.dmh.close();
    state.dmhDoor.close();
    state.dmhOpen.close();
}

function use(ctx, state, block, player) {
    let needConf = false;
    // try {
    // let playerInfo = JSON.parse(player.getNBT() + "");
    // if (playerInfo.SelectedItem.id == "mtr:driver_key") state.config.doorTarget = !state.doorTarget;
    // if (playerInfo.SelectedItem.id == "minecraft:stick") needConf = true;
    // } catch (e) {
    needConf = true;
    // }
    if (needConf) {
        let configs = [];
        let sc;
        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("cfg.content.mainmodel")), "mainModel", {
                type: "duanmen",
                defaultVal: block.getCustomConfig("mainModel"),
                showConditition: true
            })
        );
        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("cfg.content.submodel")), "subModel", {
                type: "duanmen",
                saveKey: "subModel",
                path: "content",
                showConditition: true
            })
        );
        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("cfg.duanmen.doortarget")), "bool", {
                style: 2,
                type: "bool",
                savePos: "doorTarget",
                showConditition: Resources.getNTEVersionInt() < 10101,
                default: state.doorTarget == true
            })
        );
        // configs.push(buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("cfg.duanmen.extra_length")), "num", { default: state.length, isInt: true, min: 2, max: 30, savePos: "length" }));
        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("cfg.diaoban.doorlight")), "bool", {
                style: 2,
                type: "bool",
                savePos: "showDiaobanDoorLight",
                showConditition: () => state.model.withDiaobanDoorlight,
                default: state.showDiaobanDoorLight == true
            })
        );

        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("fangsu.item.diaoban")) + ComponentUtil.getString(ComponentUtil.translatable("cfg.content.mainmodel")), "function", {
                function: () => {
                    var cfgSc = createSelectionScreen({ type: "diaoban", path: "fangsu:custom_blocks.json" }, sc, "file", "diaobanMainModel", { ctx, state, entity: block, block });
                    displaySelectionScreen(cfgSc);
                },
                showConditition: () => checkCacheConfig(state, "showDiaobanDoorLight", true)
            })
        );
        configs.push(
            buildConfigItem(ComponentUtil.getString(ComponentUtil.translatable("fangsu.item.diaoban")) + ComponentUtil.getString(ComponentUtil.translatable("cfg.content.submodel")), "function", {
                function: () => {
                    var items = [];
                    let md = getByPath(JSON.parse(loadResource("str", state.diaobanMainModel)), "content");
                    if (md)
                        for (let m of md) {
                            items.push({
                                text: ComponentUtil.getString(ComponentUtil.translatable(m.text)),
                                type: "function",
                                val: {
                                    content: m.id,
                                    contentText: m.contentText
                                        ? ComponentUtil.getString(ComponentUtil.translatable(m.contentText))
                                        : ComponentUtil.getString(ComponentUtil.translatable("cfg.no_detail")),
                                    contentImage: m.contentImage || null
                                }
                            });
                        }
                    var cfgSc = createSelectionScreen({ type: "list", itemList: items }, sc, "list", "diaobanSubModel", { ctx, state, entity: block, block });
                    displaySelectionScreen(cfgSc);
                },
                showConditition: () => checkCacheConfig(state, "showDiaobanDoorLight", true)
            })
        );
        sc = createConfigSc(configs, null, { ctx, state, entity: block, block }, { title: ComponentUtil.getString(ComponentUtil.translatable("cfg.title")) });
        displayConfigSc(sc);
    }
}
