# Path: uchroma/log.py
# LOG_TRACE = 5
# 
# Path: uchroma/util.py
# def clamp(value, min_, max_):
#     """
#     Constrain a value to the specified range
# 
#     :param value: Input value
#     :param min_: Range minimum
#     :param max_: Range maximum
# 
#     :return: The constrained value
#     """
#     return max(min_, min(value, max_))


import asyncio
import time
from typing import NamedTuple
from uchroma.log import LOG_TRACE
from uchroma.util import clamp

_KeyInputEvent = NamedTuple('KeyInputEvent', \
    [('timestamp', float),
     ('expire_time', float),
     ('keycode', str),
     ('scancode', str),
     ('keystate', int),
     ('coords', list),
     ('data', dict)])


class KeyInputEvent(_KeyInputEvent, object):
    """
    Container of all values of a keyboard input event
    with optional expiration time.
    """

    @property
    def time_remaining(self) -> float:
        """
        The number of seconds until this event expires
        """
        return max(0.0, self.expire_time - time.time())

    @property
    def percent_complete(self) -> float:
        """
        Percentage of elapsed time until this event expires
        """
        duration = self.expire_time - self.timestamp

# Path: uchroma/log.py
# LOG_TRACE = 5
# 
# Path: uchroma/util.py
# def clamp(value, min_, max_):
#     """
#     Constrain a value to the specified range
# 
#     :param value: Input value
#     :param min_: Range minimum
#     :param max_: Range maximum
# 
#     :return: The constrained value
#     """
#     return max(min_, min(value, max_))


# Path: uchroma/input_queue.py
import asyncio
import time
from typing import NamedTuple
from uchroma.log import LOG_TRACE
from uchroma.util import clamp


_KeyInputEvent = NamedTuple('KeyInputEvent', \
    [('timestamp', float),
     ('expire_time', float),
     ('keycode', str),
     ('scancode', str),
     ('keystate', int),
     ('coords', list),
     ('data', dict)])


class KeyInputEvent(_KeyInputEvent, object):
    """
    Container of all values of a keyboard input event
    with optional expiration time.
    """

    @property
    def time_remaining(self) -> float:
        """
        The number of seconds until this event expires
        """
        return max(0.0, self.expire_time - time.time())

    @property
    def percent_complete(self) -> float:
        """
        Percentage of elapsed time until this event expires
        """
        duration = self.expire_time - self.timestamp

        return clamp(self.time_remaining / duration, 0.0, 1.0)