""" timers, repeaters. """

import obj
import threading
import time

s = "obj.clock.Timers"

class Cfg(obj.Object):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.latest = 0

class Timers(obj.Object):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._stopped = False
        self.cfg = Cfg()
        self.timers = obj.Object()

    def loop(self):
        while not self._stopped:
            time.sleep(1.0)
            remove = []
            for t, event in self.timers.items():
                if time.time() > t:
                    self.cfg.latest = time.time()
                    self.cfg.save()
                    event.raw(event.txt)
                    remove.append(t)
            for r in remove:
                del self.timers[r]

    def start(self, type=None):
        for e in obj.store.all(s):
            if "done" in e and e.done:
                continue
            if "time" not in e:
                continue
            if time.time() < int(e.time):
                self.timers[e.time] = e
        return obj.launch(self.loop)

    def stop(self):
        self._stopped = True

class Timer(obj.Object):

    def __init__(self, sleep, func, *args, **kwargs):
        super().__init__()
        self._func = func
        self._name = kwargs.get("name", obj.utils.get_name(func))
        self.sleep = sleep
        self.args = args
        self.kwargs = kwargs
        self.state = obj.Object()

    def start(self):
        timer = threading.Timer(self.sleep, self.run, self.args, self.kwargs)
        timer.setName(self._name)
        timer.sleep = self.sleep
        timer.state = self.state
        timer.state.starttime = time.time()
        timer.state.latest = time.time()
        timer._func = self._func
        timer.start()
        return timer

    def run(self, *args, **kwargs):
        self.state.latest = time.time()
        obj.launch(self._func, *args, **kwargs)

    def exit(self):
        self.cancel()

class Repeater(Timer):

    def run(self, *args, **kwargs):
        self._func(*args, **kwargs)
        return obj.launch(self.start)
