package Tools;

/**
 * Display an ASCII progress bar to satiate users during slow
 * operations.
 */
public class ProgressBar {

	int range;
	long lastDisplay;
	int skip;
	int toSkip;

	static int totalLength = 60;
	static long timeThresh = 30;	// milliseconds between update

	public ProgressBar(int range) {
		this.range = range;
		if (range<1) {
			range = 1;
		}
		lastDisplay=0;
		skip=1;
		toSkip=0;
	}

	public void update(int value) {
		if (toSkip>0) {
			toSkip--;
			return;
		}

		long thisDisplay = System.currentTimeMillis();
		long delay = thisDisplay-lastDisplay;
		if (delay < timeThresh) {
			skip*=2;	// next time wait longer before updating
			// (That means that any "fast" burst can cause all future
			// updates to be high latency, but that's the price of not
			// doing some fancier averaging thing.)
		}
		lastDisplay = thisDisplay;

		double frac = ((double) value) / ((double) range);
		frac = Math.max(0.0, frac);
		frac = Math.min(1.0, frac);
		System.out.print("\r");
		System.out.print(update(frac));
		System.out.flush();

		toSkip = skip;
	}

	public void done() {
		System.out.print("\r");
		System.out.println(update(1.0));
		System.out.flush();
	}

	protected String update(double frac) {
		int length = (int) (totalLength*frac);
		StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (int i=0; i<length; i++) {
			sb.append("#");
		}
		for (int i=length; i<totalLength; i++) {
			sb.append(".");
		}
		sb.append("]");
		return sb.toString();
	}
}
