package net.sf.colossus.util; import java.util.ArrayList; import java.util.List; /** * An integer value, along with a detailed record of how and why * the value has the value it has. * @author Romain Dolbeau */ public class ValueRecorder implements IValueRecorderItem { /** The current value */ private int value = 0; private float scale = 1; private final String desc; /** All the explanations and value changes */ private final List<IValueRecorderItem> items = new ArrayList<IValueRecorderItem>(); public ValueRecorder() { desc = null; } public ValueRecorder(String desc) { this.desc = desc; } public boolean isReset() { return false; } private class TrivialValueRecorderItem implements IValueRecorderItem { private final int v; private final String why; private final boolean isReset; TrivialValueRecorderItem(int v, String why, boolean isReset) { this.v = v; this.why = why; this.isReset = isReset; } public int getValue() { return v; } public String getWhy(String prefix) { return why; } public String getFull(String prefix) { StringBuffer buf = new StringBuffer(); buf.append("\n"); buf.append(prefix); if (isReset()) { buf.append("| "); } else if (v >= 0) { buf.append("+ "); } buf.append(getValue()); buf.append(" [" + why + "]"); return buf.toString(); } public boolean isReset() { return isReset; } } /** Augment the value. * @param v By how much the value change. * @param r The reason of the change. */ public void add(int v, String r) { items.add(new TrivialValueRecorderItem(v, r, false)); value += v; } /** * Augment the value. * @param v By how much the value change, and why */ public void add(ValueRecorder v) { items.add(v); value += v.getValue(); } /** * Reset the value to a specific value. * @param v The new value to use. * @param r The reason of the change. */ public void resetTo(int v, String r) { items.add(new TrivialValueRecorderItem(v, r, true)); value = v; } /** Get the value. * @return The current value. */ public int getValue() { return Math.round(value * scale); } public void setScale(float scale) { this.scale = scale; } public boolean isEmpty() { return items.isEmpty(); } public String getWhy(String prefix) { StringBuffer buf = new StringBuffer(); for (IValueRecorderItem item : items) { buf.append(item.getFull(prefix + "\t")); } return buf.toString(); } public String getFull(String prefix) { StringBuffer buf = new StringBuffer(); buf.append("\n"); if (desc != null) buf.append(desc); buf.append(prefix); if (isReset()) { buf.append("| "); } else if (getValue() >= 0) { buf.append("+ "); } buf.append(getValue()); buf.append(" [" + getWhy(prefix) + "]"); if (scale != 1.) { buf.append(" * " + scale); } return buf.toString(); } /** Get the detailed explanations and final value as String. * @return The detailed explanations and final value. */ @Override public String toString() { return getWhy("") + " = " + getValue(); } }