"""Global objects — always-visible entities and root containers."""

from h2g2.engine.game_object import GameObject, Flag
from h2g2.engine.world import World
from h2g2.engine.state import GameState


def hangover_action(state: GameState) -> bool:
    out = state.output
    if state.prsa == "examine" or state.prsa == "diagnose":
        if state.flags.get("headache"):
            out.tell("You have a big blinding throbber.\n")
        else:
            out.tell("You don't have a headache.\n")
        return True
    return False


def light_action(state: GameState) -> bool:
    out = state.output
    if state.prsa == "turn on":
        if state.here and state.here.fset_q(Flag.ONBIT):
            out.tell("It is.\n")
        else:
            if state.here:
                state.here.fset(Flag.ONBIT)
            state.update_lit()
            out.tell("Good start to the day. Pity it's going to be the worst "
                     "one of your life. The light is now on.\n\n")
            # Show room description now that light is on
            from h2g2.engine.loop import GameLoop
            GameLoop._describe_room_static(state)
        return True
    if state.prsa == "turn off":
        if state.here:
            state.here.fclear(Flag.ONBIT)
        state.update_lit()
        out.tell("It is now pitch dark in here. If you proceed you will "
                 "likely fall into a pit.\n")
        return True
    return False


def walls_action(state: GameState) -> bool:
    if state.prsa == "examine":
        state.output.tell("They look like walls.\n")
        return True
    return False


def me_action(state: GameState) -> bool:
    out = state.output
    if state.prsa == "examine":
        if state.flags.get("headache"):
            out.tell("You look about as ill as you feel.\n")
        else:
            out.tell("You look pretty normal.\n")
        return True
    return False


def ground_action(state: GameState) -> bool:
    out = state.output
    if state.prsa == "lie down":
        state.lying_down = True
        if state.here and state.here.id == "FRONT-OF-HOUSE":
            state.flags["in_front_of_bulldozer"] = True
            out.tell("You lie down in the path of the advancing bulldozer.\n")
        else:
            out.tell("You lie down.\n")
        return True
    if state.prsa == "examine":
        out.tell("It looks like ground.\n")
        return True
    return False


def register(world: World) -> None:
    """Create all global objects and root containers."""

    # Root containers
    global_objects = world.register(GameObject(
        "GLOBAL-OBJECTS", desc="global objects",
        flags={Flag.INVISIBLE},
    ))
    world.global_objects = global_objects

    local_globals = world.register(GameObject(
        "LOCAL-GLOBALS", desc="local globals",
        flags={Flag.INVISIBLE},
    ))
    local_globals.move_to(global_objects)
    world.local_globals = local_globals

    protagonist = world.register(GameObject(
        "PROTAGONIST", desc="you",
        flags={Flag.INVISIBLE, Flag.ACTORBIT},
        capacity=100,
    ))
    world.protagonist = protagonist

    # Globally visible objects
    world.register(GameObject(
        "LIGHT", desc="light",
        synonyms=["light", "lights", "lamp"],
        flags={Flag.LIGHTBIT},
        action=light_action,
    )).move_to(global_objects)

    world.register(GameObject(
        "WALLS", desc="wall",
        synonyms=["wall", "walls", "ceiling", "floor"],
        flags={Flag.NDESCBIT, Flag.TOUCHBIT},
        action=walls_action,
    )).move_to(global_objects)

    world.register(GameObject(
        "ME", desc="yourself",
        synonyms=["me", "myself", "self", "yourself"],
        flags={Flag.NDESCBIT, Flag.NARTICLEBIT, Flag.ACTORBIT},
        action=me_action,
    )).move_to(global_objects)

    world.register(GameObject(
        "HANGOVER", desc="splitting headache",
        synonyms=["headache", "hangover", "throbber"],
        adjectives=["splitting", "big", "blinding"],
        action=hangover_action,
    )).move_to(global_objects)

    world.register(GameObject(
        "GROUND", desc="ground",
        synonyms=["ground", "mud", "dirt", "floor", "earth"],
        flags={Flag.NDESCBIT},
        action=ground_action,
    )).move_to(global_objects)

    world.register(GameObject(
        "HANDS", desc="your hands",
        synonyms=["hands", "hand"],
        adjectives=["my", "your"],
        flags={Flag.NDESCBIT, Flag.NARTICLEBIT},
    )).move_to(global_objects)
