#!/usr/bin/env python

from evennia.utils import delay

from typeclasses.objects import Object


# -------------------------------------------------------------
# LightSource
#
# This object emits light. Once it has been turned on it
# cannot be turned off. When it burns out it will delete
# itself.
#
# This could be implemented using a single-repeat Script or by
# registering with the TickerHandler. We do it simpler by
# using the delay() utility function. This is very simple
# to use but does not survive a server @reload. Because of
# where the light matters (in the Dark Room where you can
# find new light sources easily), this is okay here.
# -------------------------------------------------------------

class LightSource(Object):
    """
    This implements a light source object.

    When burned out, the object will be deleted.
    """

    def at_init(self):
        """
        If this is called with the Attribute is_giving_light already
        set, we know that the timer got killed by a server
        reload/reboot before it had time to finish. So we kill it here
        instead. This is the price we pay for the simplicity of the
        non-persistent delay() method.
        """
        if self.db.is_giving_light:
            self.delete()

    def at_object_creation(self):
        """Called when object is first created."""
        super().at_object_creation()

        self.db.is_giving_light = False
        self.db.burntime = 60 * 3  # 3 minutes
        # this is the default desc, it can of course be customized
        # when created.
        self.db.desc = "A resin-covered splinter of wood."
        # add the Light command
        # self.cmdset.add_default(CmdSetLight, persistent=True)

    def _burnout(self):
        """
        This is called when this light source burns out. We make no
        use of the return value.
        """
        # delete ourselves from the database
        self.db.is_giving_light = False
        try:
            owner = self.location
            if self.db.desc_end:
                owner.announce_action(self.db.desc_end)
            else:
                owner.announce_action(f"$Your() {self.key} flickers and dies.")
            self.location.location.check_light_state()
        except AttributeError:
            try:
                self.location.msg_contents(f"A {self.key} on the floor flickers and dies.")
                self.location.location.check_light_state()
            except AttributeError:
                # Mainly happens if we happen to be in a None location
                pass
        self.delete()

    def do_light(self, owner):
        """
        Light this object - this is called by Light command.
        """
        if self.db.is_giving_light:
            owner.msg(f"The {self.key} is already lit.")
            return False

        owner.announce_action(f"$You() $conj(light) $pron(your) {self.key}.")

        self.db.is_giving_light = True
        if self.db.desc_lit:
            self.db.desc = self.db.desc_lit
        if owner.location.db.desc_lit:
            owner.location.msg_contents(owner.location.db.desc_lit)

        # if we are in a dark room, trigger its light check
        try:
            owner.location.check_light_state()
        except AttributeError:
            try:
                # maybe we are directly in the room
                owner.check_light_state()
            except AttributeError:
                # we are in a None location
                pass
        finally:
            # start the burn timer. When it runs out, self._burnout
            # will be called. We store the deferred so it can be
            # killed in unittesting.
            self.deferred = delay(self.db.burntime, self._burnout)
        return True


class Torch(LightSource):
    """
    A LightSource that lasts longer than the default.
    """
    def at_object_creation(self):
        """Called when object is first created."""
        super().at_object_creation()

        self.db.is_giving_light = False
        self.db.burntime = 60 * 20  # 20 minutes
        self.db.desc = "Crafted from twisted branches."
        self.db.desc_lit = "Burns with a green flame."
        self.db.desc_end = "$Your() torch burns down to the nub and goes out."


class Candle(LightSource):
    """
    A LightSource that lasts longer than the default.
    """
    def at_object_creation(self):
        """Called when object is first created."""
        super().at_object_creation()

        self.db.is_giving_light = True
        self.db.burntime = 60 * 60  # An hour
        self.db.desc = "Tapered and made from shimmering blue wax."
        self.db.desc_end = "$Your() candle pops and explodes into a burst of octarine sparks."
