package client.vars;

import java.lang.reflect.Field;

import client.gui.element.Slider;
import client.gui.element.SliderFloatCallback;
import common.util.ExtMath;
import common.util.Color;

public class FloatVar extends BaseVar {
	public static interface FloatFunction extends VarFunction {
		void apply(FloatVar cv, float value);
	}

	private final String unit;
	private final String format;
	private final int precision;
	private final float divider;
	private final FloatFunction func;
	private final float min;
	private final float max;
	private final float def;
	
	public static float getDivider(int precision) {
		int div = 1;
		for(int z = 0; z < precision; z++) {
			div *= 10;
		}
		return (float)div;
	}
	
	public FloatVar(String name, String display, Field field, Object object, CVarCategory category, float min, float max, FloatFunction func, String unit, int precision) {
		super(name, display, field, object, category);
		this.func = func;
		this.min = min;
		this.max = max;
		this.unit = unit;
		this.precision = precision;
		this.format = "%." + precision + "f";
		this.divider = getDivider(precision);
		try {
			this.def = field.getFloat(object);
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	public String getType() {
		return Color.YELLOW + "float";
	}
	
	public boolean parse(String str) {
		float value;
		try {
			value = Float.parseFloat(str);
		}
		catch(NumberFormatException e) {
			return false;
		}
		value = ExtMath.clampf(value, this.min, this.max);
		int round = (int)(value * this.divider);
		value = (float)round / this.divider;
		try {
			this.field.setFloat(this.object, value);
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
		if(this.func != null)
			this.func.apply(this, value);
		return true;
	}
	
	public String format() {
		try {
			return String.format(this.format, this.field.getFloat(this.object));
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	
	public String getDefault() {
		return String.format(this.format, this.def);
	}
	
	public String getValues() {
		return String.format(this.format + ".." + this.format, this.min, this.max);
	}
	
	public Slider selector(int x, int y, int w, int h) {
		try {
			return new Slider(x, y, w, h, this.unit.equals("%") ? -1 : this.precision, this.min, this.max, this.def, this.field.getFloat(this.object), new SliderFloatCallback() {
				public void use(Slider elem, float value) {
					FloatVar.this.parse(String.format(FloatVar.this.format, value));
				}
			}, this.display, this.unit);
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
}
