package jas.spawner.refactor.entities;
import jas.spawner.modern.math.SetAlgebra;
import jas.spawner.modern.spawner.biome.group.BiomeHelper;
import jas.spawner.refactor.biome.BiomeMappings;
import jas.spawner.refactor.mvel.MVELExpression;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.minecraft.world.biome.BiomeGenBase;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* Note: Generics of Group is kinda fucked. results explicitly used String return type for results whereas Mappings
* allows and type to be used. Group as well as subclasses and Groups should reflect this.
*/
//TODO: needs to be replaced with jas.spawner.refactor.entities.GenericGroup<ID, CONTENT, RESULT>
public interface Group {
public String iD();
public Set<String> results();
public interface ContentGroup<T> extends Group {
public T content();
}
public static interface MutableContentGroup<T> extends ContentGroup<T> {
public void setResults(Set<String> results);
public void setContents(T expression);
}
public static interface Groups<T extends Group> {
public String key();
public Map<String, T> iDToGroup();
}
/** Maintains the inverse relationship of a Group: From Each mapping to all mappings that contain it */
public static interface ReversibleGroups<T extends Group> extends Groups<T> {
public Multimap<String, String> mappingToID();
}
public static class Parser {
public interface Context {
public ResultsBuilder builder();
}
public static class LocationContext<L extends Group> extends ContextBase {
private ArrayListMultimap<String, Integer> pckgNameToBiomeID;
protected Mappings<String, String> mappings;
public LocationContext(BiomeMappings mappings) {
this(mappings, null, null);
}
public LocationContext(BiomeMappings mappings, Groups dGroups) {
this(mappings, dGroups, null, null);
}
public LocationContext(BiomeMappings mappings, Groups dGroups, Groups aGroups) {
this(mappings, dGroups, aGroups, null);
}
public LocationContext(BiomeMappings mappings, Groups dGroups, Groups aGroups, Groups gGroups) {
super(dGroups, aGroups, gGroups);
this.mappings = mappings;
pckgNameToBiomeID = ArrayListMultimap.create();
for (BiomeGenBase biome : BiomeGenBase.getBiomeGenArray()) {
if (biome != null) {
pckgNameToBiomeID.put(BiomeHelper.getPackageName(biome), biome.biomeID);
}
}
}
public BiomeGenBase biome(String mapping) {
String packageName = mappings.mappingToKey().get(mapping);
int biomeID = pckgNameToBiomeID.get(packageName).get(0);
return BiomeGenBase.getBiomeGenArray()[biomeID];
}
}
public static class LivingContext extends ContextBase {
private LivingMappings mappings;
public LivingContext(LivingMappings mappings) {
this(mappings, null, null);
}
public LivingContext(LivingMappings mappings, Groups dGroups) {
this(mappings, dGroups, null, null);
}
public LivingContext(LivingMappings mappings, Groups dGroups, Groups aGroups) {
this(mappings, dGroups, aGroups, null);
}
public LivingContext(LivingMappings mappings, Groups dGroups, Groups aGroups, Groups gGroups) {
super(dGroups, aGroups, gGroups);
this.mappings = mappings;
}
}
public static class ContextBase implements Context {
public Map<String, Collection<String>> A;
public Map<String, Collection<String>> G;
public Map<String, Collection<String>> D;
public ContextBase() {
this(null, null, null);
}
public ContextBase(Groups dGroups) {
this(dGroups, null, null);
}
public ContextBase(Groups dGroups, Groups aGroups) {
this(dGroups, aGroups, null);
}
public ContextBase(Groups dGroups, Groups aGroups, Groups gGroups) {
A = aGroups != null ? convert(aGroups) : new HashMap<String, Collection<String>>();
G = gGroups != null ? convert(gGroups) : new HashMap<String, Collection<String>>();
D = dGroups != null ? convert(dGroups) : new HashMap<String, Collection<String>>();
}
private HashMap<String, Collection<String>> convert(Groups<Group> group) {
HashMap<String, Collection<String>> map = new HashMap<String, Collection<String>>();
for (Entry<String, Group> entry : group.iDToGroup().entrySet()) {
map.put(entry.getKey(), entry.getValue().results());
}
return map;
}
//TODO: Add alias builder S and start, startwith, with
@Override
public ResultsBuilder builder() {
return new ResultsBuilder();
}
public ResultsBuilder sw() {
return builder();
}
public ResultsBuilder startwith() {
return builder();
}
public ResultsBuilder with() {
return builder();
}
public ResultsBuilder w() {
return builder();
}
}
public static class ResultsBuilder {
public Set<String> resultMappings = new HashSet<String>();
public ResultsBuilder() {
}
public ResultsBuilder add(Collection<String> mappings) {
SetAlgebra.operate(resultMappings, mappings, SetAlgebra.OPERATION.UNION);
return this;
}
public ResultsBuilder remove(Collection<String> mappings) {
SetAlgebra.operate(resultMappings, mappings, SetAlgebra.OPERATION.COMPLEMENT);
return this;
}
public ResultsBuilder intersection(Collection<String> mappings) {
SetAlgebra.operate(resultMappings, mappings, SetAlgebra.OPERATION.INTERSECT);
return this;
}
public ResultsBuilder A(Collection<String> mappings) {
add(mappings);
return this;
}
public ResultsBuilder R(Collection<String> mappings) {
remove(mappings);
return this;
}
public ResultsBuilder I(Collection<String> mappings) {
intersection(mappings);
return this;
}
public ResultsBuilder add(String mappings) {
resultMappings.add(mappings);
return this;
}
public ResultsBuilder remove(String mappings) {
resultMappings.remove(mappings);
return this;
}
public ResultsBuilder A(String mappings) {
add(mappings);
return this;
}
public ResultsBuilder R(String mappings) {
remove(mappings);
return this;
}
}
public static void parseGroupContents(MutableContentGroup<String> mutableGroup, Context context) {
ResultsBuilder result = new MVELExpression<ResultsBuilder>(mutableGroup.content()).evaluate(context, "");
mutableGroup.setResults(result.resultMappings);
}
}
}