//priority: 3005

// Mod shortcuts
let MOD = (domain, id, x) => (x ? `${x}x ` : "") + (id ? (id.startsWith('#') ? '#' : "") : "") + domain + (id ? ":" : "") + (id ? id.replace('#', '') : "")
let AE2 = (id, x) => MOD("appliedenergistics2", id, x)
let AE2E = (id, x) => MOD("ae2extras", id, x)
let CR = (id, x) => MOD("create", id, x)
let CRAD = (id, x) => MOD("createaddition", id, x)
let CRG = (id, x) => MOD("creategears", id, x)
let CRGA = (id, x) => MOD("creategearaddon", id, x)
let CF = (id, x) => MOD("comforts", id, x)
let TC = (id, x) => MOD("tconstruct", id, x)
let CA = (id, x) => MOD("constructsarmory", id, x)
let MC = (id, x) => MOD("minecraft", id, x)
let KJ = (id, x) => MOD("kubejs", id, x)
let SD = (id, x) => MOD("storagedrawers", id, x)
let F = (id, x) => MOD("forge", id, x)
let Q = (id, x) => MOD("quark", id, x)
let PHCFC = (id, x) => MOD("pamhc2foodcore", id, x)
let ENS = (id, x) => MOD("exnihilosequentia", id, x)
let ENS_AE2 = (id, x) => MOD("exnihiloae", id, x)
let EE = (id, x) => MOD("emendatusenigmatica", id, x)
let MU = (id, x) => MOD("miniutilities", id, x)
let DU = (id, x) => MOD("darkutils", id, x)
let BT = (id, x) => MOD("boss_tools", id, x)
let IF = (id, x) => MOD("industrialforegoing", id, x)
let RTB = (id, x) => MOD("rftoolsbase", id, x)
let PR_C = (id, x) => MOD("projectred-core", id, x)
let PR_T = (id, x) => MOD("projectred-transmission", id, x)
let PR_I = (id, x) => MOD("projectred-illumination", id, x)
let PR_INT = (id, x) => MOD("projectred-integration", id, x)
let TM = (id, x) => MOD("torchmaster", id, x)
let M = (id, x) => MOD("mekanism", id, x)
let MG = (id, x) => MOD("mekanismgenerators", id, x)
let WH = (id, x) => MOD("woodenhopper", id, x)
let SH = (id, x) => MOD("speedyhoppers", id, x)
let CP = (id, x) => MOD("compressium", id, x)
let CG = (id, x) => MOD("cobblefordays", id, x)
let EC = (id, x) => MOD("extendedcrafting", id, x)
let ES = (id, x) => MOD("enderstorage", id, x)
let X = (id, x) => MOD("xnet", id, x)
let PRE = (id, x) => MOD("projecte", id, x)
let PREXP = (id, x) => MOD("projectexpansion", id, x)
let PREXT = (id, x) => MOD("projectextended", id, x)
let CM = (id, x) => MOD("cagedmobs", id, x)
let FFB = (id, x) => MOD("farmingforblockheads", id, x)
let AV = (id, x) => MOD("avaritia", id, x)
let TR = (id, x) => MOD("trashcans", id, x)
let BP = (id, x) => MOD("botanypots", id, x)
let PP = (id, x) => MOD("ftb-power-pots", id, x)
let IFC = (id, x) => MOD("ironfurnaces", id, x)
let IC = (id, x) => MOD("ironchest", id, x)
let FCD = (id, x) => MOD("framedcompactdrawers", id, x)
let CH = (id, x) => MOD("charm", id, x)
let MAT = (id, x) => MOD("materialis", id, x)
let BC = (id, x) => MOD("bettercompat", id, x)
let TA = (id, x) => MOD("tinkersarchery", id, x)
let SE = (id, x) => MOD("shieldexp", id, x)
let FN = (id, x) => MOD("fluxnetworks", id, x)
let MB = (id, x) => MOD("metalbarrels", id, x)
let CER = (id, x) => MOD("ceramics", id, x)
let FH = (id, x) => MOD("flopper", id, x)
let PZ = (id, x) => MOD("pipez", id, x)
let WST = (id, x) => MOD("wstweaks", id, x)
let CC = (id, x) => MOD("cataclysm", id, x)
let IA = (id, x) => MOD("immersive_armors", id, x)
let LS = (id, x) => MOD("yet_another_lightning_sword", id, x)
let SS = (id, x) => MOD("superior_swords", id, x)
let MBR = (id, x) => MOD("morebows", id, x)


let colours = ['white', 'orange', 'magenta', 'light_blue', 'lime', 'pink', 'purple', 'light_gray', 'gray', 'cyan', 'brown', 'green', 'blue', 'red', 'black', 'yellow']
let wood_types = [MC('oak'), MC('spruce'), MC('birch'), MC('jungle'), MC('acacia'), MC('dark_oak'), MC('crimson'), MC('warped')]
let mc_wood_types = ['oak', 'spruce', 'birch', 'jungle', 'acacia', 'dark_oak', 'crimson', 'warped']

const processingTimesDefault = {
	milling: 300,
	crushing: 100,
}

let donutCraft = (event, output, center, ring) => {
	event.shaped(output, [
		'SSS',
		'SCS',
		'SSS'
	], {
		C: center,
		S: ring
	})
}

function ifiniDeploying(output, input, tool) {
	return {
		"type": "create:deploying",
		"ingredients": [
			Ingredient.of(input).toJson(),
			Ingredient.of(tool).toJson()
		],
		"results": [
			Item.of(output).toResultJson()
		],
		"keepHeldItem": true
	}
}

const air = 'minecraft:air';

const modPriorities = [
    'appliedenergistics2',
    'emendatusenigmatica',
    'minecraft',
    'mekanism',
    'kubejs',
    'create',
    'industrialforegoing',
    'quark',
    'titanium',
    'exnihilosequentia',
    'tconstruct',
    'bettercompat',
    'miniutilities',
    'boss_tools'
];

function shapedRecipe(result, pattern, key, id) {
    return { result: result, pattern: pattern, key: key, id: id };
}

let modifyShaped = (e, result, count, pattern, ingredients) => {
    e.remove({ output: result, type: 'minecraft:crafting_shaped' })
    e.shaped(item.of(result, count), pattern, ingredients).id(`kubejs:shaped/${result.replace(':', '/')}`)
}

function shapelessRecipe(result, ingredients, id) {
    return { result: result, ingredients: ingredients, id: id };
}

let modifyShapeless = (e, result, count, ingredients) => {
    e.remove({ output: result, type: 'minecraft:crafting_shapeless' })
    e.shapeless(item.of(result, count), ingredients).id(`kubejs:shapeless/${result.replace(':', '/')}`)
}

let modifySmelt = (e, result, ingredients) => {
    e.remove({ output: result, type: 'minecraft:smelting' })
    e.smelting(result, ingredients).id(`kubejs:smelting/${result.replace(':', '/')}`)
}

let removeRecipeByID = (e, recipes) => {
    recipes.forEach(recipe => {
        e.remove({ id: recipe })
    })
}

let removeRecipeByInput = (e, recipes) => {
    recipes.forEach(recipe => {
        if (Array.isArray(recipe)) {
            e.remove({ type: recipe[1], input: recipe[0] })
        } else {
            e.remove({ input: recipe })
        }
    })
}

let removeRecipeByOutput = (e, recipes) => {
    recipes.forEach(recipe => {
        if (Array.isArray(recipe)) {
            e.remove({ type: recipe[1], output: recipe[0] })
        } else {
            e.remove({ output: recipe })
        }
    })
}

function tagIsEmpty(tag) {
    return getPreferredItemInTag(Ingredient.of(tag)).id == air;
}

function getPreferredItemInTag(tag) {
    let pref =
        utils
            .listOf(tag.stacks)
            .toArray()
            .sort(({ mod: a }, { mod: b }) => compareIndices(a, b, tag))[0] || Item.of(air);
    return pref;
}
function compareIndices(a, b, tag) {
    if (a == b) return 0; // if a == b, they'll be found at the same position in modPriorities

    for (let mod of modPriorities) {
        if (mod == a) return -1; // if a comes before b, then idx(a) < idx(b), so -1
        if (mod == b) return 1; // if a comes after b, then idx(a) > idx(b), so 1
    }

    console.error('[' + a + ', ' + b + '] were both unaccounted for in mod unification' + (tag ? ' for ' + tag : '!'));
    return 0;
}

const playerHas = (item, player) => {
    return player.inventory.find(item) != -1;
};
