#!/usr/bin/python

from __future__ import print_function

import use_lldb_suite
import six

import sys
import time


class ProgressBar(object):
    """ProgressBar class holds the options of the progress bar.
    The options are:
        start   State from which start the progress. For example, if start is
                5 and the end is 10, the progress of this state is 50%
        end     State in which the progress has terminated.
        width   --
        fill    String to use for "filled" used to represent the progress
        blank   String to use for "filled" used to represent remaining space.
        format  Format
        incremental
    """
    light_block = six.unichr(0x2591).encode("utf-8")
    solid_block = six.unichr(0x2588).encode("utf-8")
    solid_right_arrow = six.unichr(0x25BA).encode("utf-8")

    def __init__(self,
                 start=0,
                 end=10,
                 width=12,
                 fill=six.unichr(0x25C9).encode("utf-8"),
                 blank=six.unichr(0x25CC).encode("utf-8"),
                 marker=six.unichr(0x25CE).encode("utf-8"),
                 format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
                 incremental=True):
        super(ProgressBar, self).__init__()

        self.start = start
        self.end = end
        self.width = width
        self.fill = fill
        self.blank = blank
        self.marker = marker
        self.format = format
        self.incremental = incremental
        self.step = 100 / float(width)  # fix
        self.reset()

    def __add__(self, increment):
        increment = self._get_progress(increment)
        if 100 > self.progress + increment:
            self.progress += increment
        else:
            self.progress = 100
        return self

    def complete(self):
        self.progress = 100
        return self

    def __str__(self):
        progressed = int(self.progress / self.step)  # fix
        fill = progressed * self.fill
        blank = (self.width - progressed) * self.blank
        return self.format % {
            'fill': fill,
            'blank': blank,
            'marker': self.marker,
            'progress': int(
                self.progress)}

    __repr__ = __str__

    def _get_progress(self, increment):
        return float(increment * 100) / self.end

    def reset(self):
        """Resets the current progress to the start point"""
        self.progress = self._get_progress(self.start)
        return self


class AnimatedProgressBar(ProgressBar):
    """Extends ProgressBar to allow you to use it straighforward on a script.
    Accepts an extra keyword argument named `stdout` (by default use sys.stdout)
    and may be any file-object to which send the progress status.
    """

    def __init__(self,
                 start=0,
                 end=10,
                 width=12,
                 fill=six.unichr(0x25C9).encode("utf-8"),
                 blank=six.unichr(0x25CC).encode("utf-8"),
                 marker=six.unichr(0x25CE).encode("utf-8"),
                 format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
                 incremental=True,
                 stdout=sys.stdout):
        super(
            AnimatedProgressBar,
            self).__init__(
            start,
            end,
            width,
            fill,
            blank,
            marker,
            format,
            incremental)
        self.stdout = stdout

    def show_progress(self):
        if hasattr(self.stdout, 'isatty') and self.stdout.isatty():
            self.stdout.write('\r')
        else:
            self.stdout.write('\n')
        self.stdout.write(str(self))
        self.stdout.flush()


class ProgressWithEvents(AnimatedProgressBar):
    """Extends AnimatedProgressBar to allow you to track a set of events that
       cause the progress to move. For instance, in a deletion progress bar, you
       can track files that were nuked and files that the user doesn't have access to
    """

    def __init__(self,
                 start=0,
                 end=10,
                 width=12,
                 fill=six.unichr(0x25C9).encode("utf-8"),
                 blank=six.unichr(0x25CC).encode("utf-8"),
                 marker=six.unichr(0x25CE).encode("utf-8"),
                 format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
                 incremental=True,
                 stdout=sys.stdout):
        super(
            ProgressWithEvents,
            self).__init__(
            start,
            end,
            width,
            fill,
            blank,
            marker,
            format,
            incremental,
            stdout)
        self.events = {}

    def add_event(self, event):
        if event in self.events:
            self.events[event] += 1
        else:
            self.events[event] = 1

    def show_progress(self):
        isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty()
        if isatty:
            self.stdout.write('\r')
        else:
            self.stdout.write('\n')
        self.stdout.write(str(self))
        if len(self.events) == 0:
            return
        self.stdout.write('\n')
        for key in list(self.events.keys()):
            self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ')
        if isatty:
            self.stdout.write('\033[1A')
        self.stdout.flush()


if __name__ == '__main__':
    p = AnimatedProgressBar(end=200, width=200)

    while True:
        p + 5
        p.show_progress()
        time.sleep(0.3)
        if p.progress == 100:
            break
    print()  # new line
