# -*- python -*-
# -*- coding: utf-8 -*-
#
#  This file is part of the easydev software
#
#  Copyright (c) 2011-2017
#
#  File author(s): Thomas Cokelaer <cokelaer@gmail.com>
#
#  Distributed under the GPLv3 License.
#  See accompanying file LICENSE.txt or copy at
#      http://www.gnu.org/licenses/gpl-3.0.html
#
#  Website: https://github.com/cokelaer/easydev
#  Documentation: http://easydev-python.readthedocs.io
#
##############################################################################
"""A progress bar copied and adapted from pyMC code (dec 2014)"""
from __future__ import print_function

import sys
import time
import uuid


try:
    from IPython.core.display import HTML, Javascript, display
except ImportError: #pragma: no cover
    pass


__all__ = ['progress_bar', 'TextProgressBar', 'Progress']


class ProgressBar(object):
    def __init__(self, iterations, interval=None):
        self.iterations = iterations
        # if no interval provided, set it to 1%
        if interval is None:
            if iterations <= 100:
                interval = 1  # everything % of the data
            else:
                interval = int(iterations/100)
        self.interval = interval
        self.start = time.time()
        self.last = 0

    def _percentage(self, i):
        if self.iterations !=0:
            return 100 * i / float(self.iterations)
        else: #pragma: no cover
            # could be 100 ?
            return 100

    def _get_elapsed(self):
        return time.time() - self.start
    elapsed = property(_get_elapsed)


class TextProgressBar(ProgressBar):
    """Use :class:`Progress`"""
    def __init__(self, iterations, printer, width=40, interval=None):
        self.fill_char = '-'
        self.width = width
        self.printer = printer
        ProgressBar.__init__(self, iterations, interval=interval)

    def animate(self, i, dummy=None):
        # dummy=None is for back-compatibility
        if dummy is not None: #pragma: no cover
            print("second argument in easydev.progress_bar.animate is deprecated. Update your code")
        # +1 if i starts at 0 and finishes at N-1
        if divmod(i, self.interval)[1] != 0 and i != self.iterations:
            pass
        else:
            self.printer(self.progbar(i))

    def progbar(self, i):
        # +1 if i starts at 0 and finishes at N-1
        bar = self.bar(self._percentage(i))
        return "[%s] %i of %i complete in %.1f sec" % (
            bar, (i), self.iterations, round(self.elapsed, 1))

    def bar(self, percent):
        all_full = self.width - 2
        num_hashes = int(percent / 100 * all_full)

        bar = self.fill_char * num_hashes + ' ' * (all_full - num_hashes)

        info = '%d%%' % percent
        loc = (len(bar) - len(info)) // 2
        return replace_at(bar, info, loc, loc + len(info))


def replace_at(str, new, start, stop):
    return str[:start] + new + str[stop:]


def consoleprint(s):
    if sys.platform.lower().startswith('win'):
        print(s, '\r', end='')
    else:
        print('\r', s, end='')
        sys.stdout.flush()


def ipythonprint(s): #pragma no cover
    print('\r', s, end='')
    sys.stdout.flush()


class IPythonNotebookPB(ProgressBar): #pragma: no cover
    """Use :class:`Progress`"""
    def __init__(self, iterations, interval=None):
        self.divid = str(uuid.uuid4())
        self.sec_id = str(uuid.uuid4())

        pb = HTML(
            """
            <div style="float: left; border: 1px solid black; width:500px">
              <div id="%s" style="background-color:blue; width:0%%">&nbsp;</div>
            </div>
            <label id="%s" style="padding-left: 10px;" text = ""/>
            """ % (self.divid, self.sec_id))
        display(pb)

        ProgressBar.__init__(self, iterations, interval=interval)

    def animate(self, i, dummy=None):
        if dummy is not None:
            print("second argument in easydev.progress_bar.animate is deprecated. Update your code")

        # +1 if i starts at 0 and finishes at N-1
        if divmod(i, self.interval)[1] != 0 and i != self.iterations :
            pass
        else:
            percentage = self._percentage(i)
            fraction = percentage
            display(
                Javascript("$('div#%s').width('%i%%')" %
                       (self.divid, percentage)))
            display(
                Javascript("$('label#%s').text('%i%% in %.1f sec')" %
                           (self.sec_id, fraction, round(self.elapsed, 1))))


def _run_from_ipython():
    try:
        __IPYTHON__
        return True
    except NameError:
        return False


def progress_bar(iters, interval=None):
    """A progress bar for Python/IPython/IPython notebook

    :param int iters: number of iterations (steps in the loop)
    :param interval: number of intervals to use to update the progress bar (20
        by default)


    ::

        from easydev import progress_bar
        pb = progress_bar(10)
        for i in range(1,10):
            import time
            time.sleep(0.1)
            pb.animate(i)

    """
    if _run_from_ipython(): #pragma: no cover
        from easydev.misc import in_ipynb
        if in_ipynb() is True:
            return IPythonNotebookPB(iters, interval=interval)
        else:
            return TextProgressBar(iters, printer=ipythonprint,
                    interval=interval)
    else:
        return TextProgressBar(iters, printer=consoleprint, 
                interval=interval)


class Progress(object):
    """Generic progress bar for python, IPython, IPython notebook

    ::

        from easydev import Progress
        pb = Progress(100, interval=1)
        pb.animate(10)
    """
    def __init__(self, iters, interval=None):
        self.pb = progress_bar(iters, interval=interval)

    def animate(self, i):
        self.pb.animate(i)

    def _get_elapsed(self):
        return self.pb.elapsed
    elapsed = property(_get_elapsed)








