package com.github.pfichtner.jrunalyser.base.data; import java.io.Serializable; import com.github.pfichtner.jrunalyser.base.data.stat.Functions; import com.google.common.collect.Ordering; import com.google.common.primitives.Doubles; public class DefaultGradient implements Gradient, Serializable { private static final long serialVersionUID = 6479473476841062802L; private static final Ordering<Gradient> orderByDistanceUnit = Ordering .natural().onResultOf(Functions.Gradients.distanceUnit); private DistanceUnit distanceUnit; private double value; private DefaultGradient(double value, DistanceUnit distanceUnit) { this.value = value; this.distanceUnit = distanceUnit; } public double getValue() { return this.value; } public DistanceUnit getDistanceUnit() { return this.distanceUnit; } public static DefaultGradient of(Distance distance, Distance height) { DistanceUnit distanceUnit = height.getDistanceUnit(); return new DefaultGradient(calc(height.getValue(distanceUnit), distance.getValue(distanceUnit)), distanceUnit); } private static double calc(double height, double distance) { return 100 * height / distance; } public static DefaultGradient of(double value, DistanceUnit distanceUnit) { return new DefaultGradient(value, distanceUnit); } public DefaultGradient convertTo(DistanceUnit distanceUnit) { return DefaultGradient.of( distanceUnit.convert(getValue(), this.distanceUnit), distanceUnit); } @Override public int compareTo(Gradient other) { final DistanceUnit smaller = findSmallerUnit(other); return Doubles.compare(convertTo(smaller).getValue(), other.convertTo(smaller).getValue()); } private DistanceUnit findSmallerUnit(final Gradient other) { return orderByDistanceUnit.min(this, other).getDistanceUnit(); } @Override public Gradient add(Gradient other) { return DefaultGradient.of(this.value + getOtherVal(other), this.distanceUnit); } @Override public Gradient subtract(Gradient other) { return DefaultGradient.of(this.value - getOtherVal(other), this.distanceUnit); } @Override public Gradient divide(double divider) { return DefaultGradient.of(this.value / divider, this.distanceUnit); } @Override public Gradient multiply(double multiplier) { return DefaultGradient.of(this.value * multiplier, this.distanceUnit); } private double getOtherVal(Gradient other) { return other.convertTo(this.distanceUnit).getValue(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((this.distanceUnit == null) ? 0 : this.distanceUnit .hashCode()); long temp; temp = Double.doubleToLongBits(this.value); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DefaultGradient other = (DefaultGradient) obj; if (this.distanceUnit != other.distanceUnit) return false; if (Double.doubleToLongBits(this.value) != Double .doubleToLongBits(other.value)) return false; return true; } @Override public String toString() { return "DefaultGradient [value=" + this.value + ", distanceUnit=" + this.distanceUnit + "]"; } }