1import asyncio
2import weakref
3from math import ceil
4
5from pychess.Utils.lutils.ldata import MATE_VALUE, MATE_DEPTH
6
7
8def formatTime(seconds, clk2pgn=False):
9    minus = ""
10    if seconds <= -10 or seconds >= 10:
11        seconds = ceil(seconds)
12    if seconds < 0:
13        minus = "-"
14        seconds = -seconds
15    hours, remainder = divmod(seconds, 3600)
16    minutes, seconds = divmod(remainder, 60)
17    if hours or clk2pgn:
18        return minus + "%d:%02d:%02d" % (hours, minutes, seconds)
19    elif not minutes and seconds < 10:
20        return minus + "%.1f" % seconds
21    else:
22        return minus + "%d:%02d" % (minutes, seconds)
23
24
25def prettyPrintScore(s, depth, format_mate=False):
26    """The score parameter is an eval value from White point of view"""
27
28    # Particular values
29    if s is None:
30        return "?"
31    if s == -MATE_VALUE:
32        return _("Illegal")
33    if s == 0:
34        return "0.00/%s" % depth
35
36    # Preparation
37    if s > 0:
38        pp = "+"
39        mp = ""
40    else:
41        pp = "-"
42        mp = "-"
43        s = -s
44    if depth:
45        depth = "/" + depth
46    else:
47        depth = ""
48
49    # Rendering
50    if s < MATE_VALUE - MATE_DEPTH:
51        return "%s%0.2f%s" % (pp, s / 100.0, depth)
52    else:
53        mate_in = int(MATE_VALUE - s)
54        if format_mate:
55            if mate_in == 0:
56                return _("Mate")
57            return "%s #%s%d" % (_("Mate"), mp, mate_in)
58        else:
59            return "%s#%.0f" % (pp, s)  # Sign before sharp to be parsed in PGN
60
61
62def createStoryTextAppEvent(text):
63    try:
64        import storytext
65        storytext.applicationEvent(text)
66    except AttributeError:
67        pass
68    except ImportError:
69        pass
70
71
72class wait_signal(asyncio.Future):
73    """A future for waiting for a given signal to occur."""
74
75    def __init__(self, obj, name, *, loop=None):
76        super().__init__(loop=loop)
77        self._obj = weakref.ref(obj, lambda s: self.cancel())
78        self._hnd = obj.connect(name, self._signal_callback)
79
80    def _signal_callback(self, *k):
81        obj = self._obj()
82        if obj is not None:
83            obj.disconnect(self._hnd)
84        self.set_result(k)
85
86    def cancel(self):
87        if self.cancelled():
88            return False
89        try:
90            super().cancel()
91        except AttributeError:
92            pass
93        try:
94            obj = self._obj()
95            if obj is not None:
96                obj.disconnect(self._hnd)
97        except AttributeError:
98            pass
99        return True
100