from eventlet.api import get_hub

class Timer(object):
    __slots__ = ['seconds', 'tpl', 'called', 'cancelled', 'scheduled_time']
    def __init__(self, seconds, cb, *args, **kw):
        """Create a timer.
            seconds: The minimum number of seconds to wait before calling
            cb: The callback to call when the timer has expired
            *args: The arguments to pass to cb
            **kw: The keyword arguments to pass to cb

        This timer will not be run unless it is scheduled in a runloop by
        calling timer.schedule() or runloop.add_timer(timer).
        """
        self.cancelled = False
        self.seconds = seconds
        self.tpl = cb, args, kw
        self.called = False

    def copy(self):
        cb, args, kw = self.tpl
        return self.__class__(self.seconds, cb, *args, **kw)
    
    def schedule(self):
        """Schedule this timer to run in the current runloop.
        """
        self.called = False
        self.scheduled_time = get_hub().runloop.add_timer(self)
        return self
        
    def __call__(self):
        if not self.called:
            self.called = True
            cb, args, kw = self.tpl
            cb(*args, **kw)
        
    def cancel(self):
        """Prevent this timer from being called. If the timer has already
        been called, has no effect.
        """
        self.cancelled = True
        self.called = True
