#!/usr/bin/env 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
