# Simple progress meter library for Python
# Copyright 2006, 2007, 2012, 2013 Adam Sampson <ats@offog.org>

import sys
import time

def format_time(secs):
	if secs is None:
		return "--:--:--"
	else:
		h = secs / (60 * 60)
		secs = secs % (60 * 60)
		m = secs / 60
		secs = secs % 60
		return "%02d:%02d:%02d" % (h, m, secs)

class Progress:
	def __init__(self, total, name = ""):
		self.total = total
		self.name = name
		self.last_value = None
		self.last_time = None
		self.start_time = None
		self.closed = True
		self.log = []
		self.last_line = None

	def update(self, value):
		self.closed = False
		now = time.time()

		if self.start_time is None:
			self.start_time = now
		elapsed = now - self.start_time

		if self.log == [] or (now - self.log[-1][1]) >= 1.0:
			self.log.append((value, now))
			self.log = self.log[-4:]
		if self.log != []:
			(fv, ft) = self.log[0]
			(lv, lt) = self.log[-1]
			dv = lv - fv
			dt = lt - ft
			if dv == 0 or dt == 0:
				eta = None
			else:
				rate = dv / dt
				eta = int((self.total - value) / rate)
		else:
			eta = None

		s = "  %-40s  %3d%%  %s  %s\r" % (self.name[:60], int(100.0 * value / self.total), format_time(elapsed), format_time(eta))
		if s != self.last_line:
			sys.stderr.write(s)
			sys.stderr.flush()
			self.last_line = s

	def clear(self):
		"""Clear the progress display, in preparation for printing
		something else."""
		sys.stderr.write("\033[0K")
		sys.stderr.flush()
		self.last_line = None

	def close(self):
		if self.closed:
			return
		self.closed = True
		if self.last_line is not None:
			sys.stderr.write("\n")
			sys.stderr.flush()

if __name__ == "__main__":
	limit = 20
	print "Starting"
	bar = Progress(limit, "Testing")
	for i in range(limit):
		bar.update(i)
		if i % 4 == 0:
			bar.clear()
			print "Now at %d of %d" % (i, limit)
		time.sleep(0.4)
	bar.close()
	print "Done"
