# Copyright 2005-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import time
import signal

import portage


class ProgressHandler(object):
	def __init__(self):
		self.reset()

	def reset(self):
		self.curval = 0
		self.maxval = 0
		self.last_update = 0
		self.min_display_latency = 0.2

	def onProgress(self, maxval, curval):
		self.maxval = maxval
		self.curval = curval
		cur_time = time.time()
		if cur_time - self.last_update >= self.min_display_latency:
			self.last_update = cur_time
			self.display()

	def display(self):
		raise NotImplementedError(self)


class ProgressBar(ProgressHandler):
	"""Class to set up and return a Progress Bar"""

	def __init__(self, isatty, **kwargs):
		self.isatty = isatty
		self.kwargs = kwargs
		ProgressHandler.__init__(self)
		self.progressBar = None

	def start(self):
		if self.isatty:
			self.progressBar = portage.output.TermProgressBar(**self.kwargs)
			signal.signal(signal.SIGWINCH, self.sigwinch_handler)
		else:
			self.onProgress = None
		return self.onProgress

	def set_label(self, _label):
		self.kwargs['label'] = _label

	def display(self):
		self.progressBar.set(self.curval, self.maxval)

	def sigwinch_handler(self, signum, frame):
		lines, self.progressBar.term_columns = \
			portage.output.get_term_size()

	def stop(self):
		signal.signal(signal.SIGWINCH, signal.SIG_DFL)

