package io.github.minecraftgui.models.attributes;
/**
* Created by Samuel on 2015-12-13.
*/
public abstract class AttributeVariable<V> extends Attribute<V>{
private final AttributeGroup<V> attributeGroup;
private Attribute<V> valueEndTransition;//This attribute is the value the transition will be at the end or the value changed by the percentage.
private double percentage = 1;
private double time = 0;//millisecond
private long timeStarted = System.currentTimeMillis();
private V valueAtStartOfAnimation;
private double timePercentage = 0;
private double percentageLastUpdate = 0;
private V valueEndTransitionLastUpdate;
private long lastUpdateId = Long.MIN_VALUE;
protected abstract V getValue(V value, double percentage);
protected abstract V getValue(V valueAtTheEnd, V valueAtStart, double percentage, double timePercentage);
public AttributeVariable(Attribute<V> value, AttributeGroup<V> attributeGroup) {
super(null);
this.valueEndTransition = value;
this.attributeGroup = attributeGroup;
}
public AttributeVariable(Attribute<V> value, AttributeGroup<V> attributeGroup, double percentage) {
super(null);
this.valueEndTransition = value;
this.attributeGroup = attributeGroup;
this.percentage = percentage;
}
public AttributeVariable(Attribute<V> value, AttributeGroup<V> attributeGroup, long time) {
super(null);
this.valueEndTransition = value;
this.attributeGroup = attributeGroup;
this.time = time;
}
public AttributeVariable(Attribute<V> value, AttributeGroup<V> attributeGroup, double percentage, long time) {
super(null);
this.valueEndTransition = value;
this.attributeGroup = attributeGroup;
this.percentage = percentage;
this.time = time;
}
public void setAttribute(Attribute<V> value) {
this.valueEndTransition = value;
this.value = value.getValue();
}
public double getTime() {
return time;
}
public double getPercentage() {
return percentage;
}
public void setTime(long time) {
this.time = time;
}
public void setPercentage(double percentage) {
this.percentage = percentage;
}
@Override
public void update(long updateId){
if(lastUpdateId != updateId) {
if (valueEndTransition != null) {
valueEndTransition.update(updateId);
boolean attrChanged = valueEndTransitionLastUpdate == null ? true : !valueEndTransitionLastUpdate.equals(valueEndTransition.getValue());
boolean percentageChanged = percentage != percentageLastUpdate;
if (time > 0 || (attrChanged && time > 0) || (percentageChanged && time > 0)) {
long currentTime = System.currentTimeMillis();
if (lastUpdateId + 1 != updateId || attrChanged || percentageChanged) {
timeStarted = currentTime;
valueAtStartOfAnimation = attributeGroup.getValue();
timePercentage = 0;
}
double lastTimePercentage = timePercentage;
valueAtStartOfAnimation = valueAtStartOfAnimation == null?attributeGroup.getDefaultValue():valueAtStartOfAnimation;
timePercentage = (currentTime - timeStarted) / time;
if (lastTimePercentage != 1) {
timePercentage = timePercentage > 1 ? 1 : timePercentage;
this.value = getValue(valueEndTransition.getValue(), valueAtStartOfAnimation, percentage, timePercentage);
}
} else if (percentageChanged || attrChanged)
this.value = getValue(valueEndTransition.getValue(), percentage);
if (percentageChanged)
percentageLastUpdate = percentage;
valueEndTransitionLastUpdate = valueEndTransition.getValue();
}
lastUpdateId = updateId;
}
}
}