package de.tobiyas.racesandclasses.playermanagement.leveling.values;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import de.tobiyas.util.config.YAMLConfigExtended;
public class LevelValueModifyReader {
private final YAMLConfigExtended config;
private final String start;
public LevelValueModifyReader(YAMLConfigExtended config, String start) {
this.config = config;
String[] split = start.split(Pattern.quote("."));
if(split.length > 0){
List<String> list = new LinkedList<String>(Arrays.asList(split));
String last = list.remove(list.size()-1);
String parent = StringUtils.join(list, ".");
for(String val : config.getChildren(parent)){
if(val.equalsIgnoreCase(last)) {
start = parent + "." + last;
}
}
}
this.start = start;
}
/**
* Parses the Config at the start point.
*
* @return the parsed Modifier.
*/
public LevelModifier parse(double defaultValue){
if(!config.contains(start)) return new LevelModifier();
List<LevelModContainer> list = new LinkedList<LevelModContainer>();
if(!config.isConfigurationSection(start)){
return new LevelModifier(new LevelModContainer(parseToDouble(start, defaultValue)));
}
for(String key : config.getChildren(start)){
double value = parseToDouble(start+"."+key, defaultValue);
LevelModContainer container = LevelModContainer.parse(key, value);
if(container != null) list.add(container);
}
return new LevelModifier(list);
}
/**
* Parses the Value at that point.
* @param path to use
* @param defaultValue to use.
* @return the parsed value.
*/
private double parseToDouble(String path, double defaultValue){
if(!config.contains(path)) return defaultValue;
if(config.isDouble(path)) return config.getDouble(path,defaultValue);
if(config.isInt(path)) return config.getInt(path,(int)defaultValue);
if(config.isString(path)) {
try{
return Double.parseDouble(config.getString(path,String.valueOf(defaultValue)));
}catch (Exception e) {}
}
return defaultValue;
}
public static class LevelModContainer{
private final int startLevel;
private final int endLevel;
private final double value;
public LevelModContainer(int startLevel, int endLevel, double value) {
this.startLevel = startLevel;
this.endLevel = endLevel;
this.value = value;
}
public LevelModContainer(double value) {
this.startLevel = Integer.MIN_VALUE;
this.endLevel = Integer.MAX_VALUE;
this.value = value;
}
public double getValue() {
return value;
}
public int getStartLevel() {
return startLevel;
}
public int getEndLevel() {
return endLevel;
}
public static LevelModContainer parse(String toParse, double value){
try{
//Check for from-To values.
if(toParse.contains("-")){
String[] parts = toParse.split(Pattern.quote("-"));
if(parts.length != 2) return null;
int start = Integer.parseInt(parts[0]);
int end = Integer.parseInt(parts[1]);
return new LevelModContainer(start, end, value);
}
//Smaller Equals.
if(toParse.startsWith("<=")){
toParse = toParse.substring(2);
int end = Integer.parseInt(toParse);
return new LevelModContainer(Integer.MIN_VALUE, end, value);
}
//greater Equals.
if(toParse.startsWith(">=")){
toParse = toParse.substring(2);
int start = Integer.parseInt(toParse);
return new LevelModContainer(start, Integer.MAX_VALUE, value);
}
//Smaller.
if(toParse.startsWith("<")){
toParse = toParse.substring(1);
int end = Integer.parseInt(toParse);
return new LevelModContainer(Integer.MIN_VALUE, end-1, value);
}
//greater.
if(toParse.startsWith(">")){
toParse = toParse.substring(1);
int start = Integer.parseInt(toParse);
return new LevelModContainer(start+1, Integer.MAX_VALUE, value);
}
}catch(Throwable exp){}
return null;
}
}
public static class LevelModifier{
/**
* the default container +-0.
*/
private static final LevelModContainer defaultContainer = new LevelModContainer(0);
private final List<LevelModContainer> list;
public LevelModifier(List<LevelModContainer> list) {
this.list = list == null ? new LinkedList<LevelModContainer>() : list;
if(list.isEmpty()) list.add(defaultContainer);
}
public LevelModifier(LevelModContainer... containers) {
this(Arrays.asList(containers));
}
public LevelModifier() {
this.list = new LinkedList<LevelModContainer>();
this.list.add(defaultContainer);
}
/**
* Gets the Highest Value for the Level.
*
* @param level to get for.
*
* @return the best value.
*/
public double getForLevel(int level){
double highest = Integer.MIN_VALUE;
for(LevelModContainer container : list){
if(container.getEndLevel() >= level && container.getStartLevel() <= level){
highest = Math.max(highest, container.getValue());
}
}
return highest;
}
/**
* Generates an empty container.
*
* @return the container.
*/
public static LevelModifier empty() {
return single(0);
}
/**
* Generates an empty container.
*
* @return the container.
*/
public static LevelModifier single(double value) {
LevelModContainer empty = new LevelModContainer(value);
List<LevelModContainer> list = new LinkedList<LevelModContainer>();
list.add(empty);
return new LevelModifier(list);
}
}
}