package io.gitlab.jfronny.libjf.config.impl.dsl; import io.gitlab.jfronny.libjf.config.api.v1.*; import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder; import io.gitlab.jfronny.libjf.config.api.v1.type.Type; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; public class CategoryBuilderImpl> implements CategoryBuilder { public final List> categories = new LinkedList<>(); public final String id; public final String categoryPath; public String translationPrefix; public final List> entries = new LinkedList<>(); public final Map> presets = new LinkedHashMap<>(); public final List> referencedConfigs = new LinkedList<>(); public final List> verifiers = new LinkedList<>(); private boolean built = false; public CategoryBuilderImpl(String id, String categoryPath) { this.id = id; this.categoryPath = categoryPath; this.translationPrefix = id + ".jfconfig." + categoryPath; } @Override public Builder setTranslationPrefix(String translationPrefix) { checkBuilt(); this.translationPrefix = translationPrefix; return asBuilder(); } @Override public String getTranslationPrefix() { checkBuilt(); return translationPrefix; } @Override public Builder addPreset(String id, Consumer action) { checkBuilt(); presets.put(id, action); return asBuilder(); } @Override public Builder addPreset(String id, Runnable preset) { return addPreset(id, cfg -> preset.run()); } @Override public Builder addVerifier(Consumer verifier) { checkBuilt(); verifiers.add(verifier); return asBuilder(); } @Override public Builder addVerifier(Runnable verifier) { return addVerifier(cfg -> verifier.run()); } @Override public Builder referenceConfig(String id) { checkBuilt(); referencedConfigs.add(() -> ConfigHolder.getInstance().get(id)); return asBuilder(); } @Override public Builder referenceConfig(ConfigInstance config) { checkBuilt(); referencedConfigs.add(() -> config); return asBuilder(); } @Override public Builder category(String id, CategoryBuilderFunction builder) { checkBuilt(); categories.add(builder.apply(new CategoryBuilderImpl(id, categoryPath + id + ".").setTranslationPrefix(translationPrefix + id + "."))); return asBuilder(); } @Override public Builder value(String id, int def, double min, double max, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TInt.INSTANCE, 100, min, max)); return asBuilder(); } @Override public Builder value(String id, long def, double min, double max, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TLong.INSTANCE, 100, min, max)); return asBuilder(); } @Override public Builder value(String id, float def, double min, double max, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TFloat.INSTANCE, 100, min, max)); return asBuilder(); } @Override public Builder value(String id, double def, double min, double max, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TDouble.INSTANCE, 100, min, max)); return asBuilder(); } @Override public Builder value(String id, String def, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TString.INSTANCE)); return asBuilder(); } @Override public Builder value(String id, boolean def, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TBool.INSTANCE)); return asBuilder(); } @Override public Builder value(String id, String def, String[] options, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, Type.TEnum.create(id, options))); return asBuilder(); } @Override public > Builder value(String id, T def, Class klazz, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, new Type.TEnum<>(klazz))); return asBuilder(); } @Override public Builder value(String id, T def, double min, double max, Type type, int width, Supplier get, Consumer set) { checkBuilt(); entries.add(new DslEntryInfo<>(id, def, get::get, set::accept, type, width, min, max)); return asBuilder(); } @Override public Builder value(EntryInfo entry) { checkBuilt(); entries.add(Objects.requireNonNull(entry)); return asBuilder(); } @Override public String getId() { return id; } protected Builder asBuilder() { //noinspection unchecked return (Builder) this; } protected void checkBuilt() { if (built) throw new IllegalStateException("This builder was already used to build a category!"); } protected void markBuilt() { checkBuilt(); built = true; } @Override public DslConfigCategory build(Supplier root) { markBuilt(); return new DslConfigCategory(id, categoryPath, translationPrefix, entries, presets, () -> referencedConfigs.stream().map(Supplier::get).toList(), categories.stream().collect(Collectors.toMap(CategoryBuilder::getId, b -> b.build(root))), root, verifiers); } }