package client.vars;

import java.lang.reflect.Field;

import client.gui.element.Slider;
import client.gui.element.SliderCallback;
import common.util.ExtMath;
import common.util.Color;
import common.util.Util;

public class IntVar extends BaseVar {
	public static interface IntFunction extends VarFunction {
		void apply(IntVar cv, int value);
	}

	private final String unit;
	private final int precision;
	private final IntFunction func;
	private final int min;
	private final int max;
	private final int def;
	
	public IntVar(String name, String display, Field field, Object object, CVarCategory category, int min, int max, IntFunction 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;
		try {
			this.def = field.getInt(object);
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	public String getType() {
		return Color.GREEN + "int";
	}
	
	protected Integer parseValue(String str) {
		return Util.parseInt(str, 0);
	}
	
	protected String formatValue(int value) {
		return "" + value;
	}
	
	public boolean parse(String str) {
		Integer value = this.parseValue(str);
		if(value == null)
			return false;
		value = ExtMath.clampi(value, this.min, this.max);
		try {
			this.field.setInt(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 this.formatValue(this.field.getInt(this.object));
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	
	public String getDefault() {
		return this.formatValue(this.def);
	}
	
	public String getValues() {
		return this.min == Integer.MIN_VALUE && this.max == Integer.MAX_VALUE ? null : ((this.min == Integer.MIN_VALUE ? "" : ("" + this.min)) + 
				".." + (this.max == Integer.MAX_VALUE ? "" : ("" + this.max)));
	}
	
	public Slider selector(int x, int y, int w, int h) {
		try {
			return new Slider(x, y, w, h, this.precision, this.min, this.max, this.def, this.field.getInt(this.object), new SliderCallback() {
				public void use(Slider elem, int value) {
					IntVar.this.parse(IntVar.this.formatValue(value));
				}
			}, this.display, this.unit);
		}
		catch(IllegalArgumentException | IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
}
