from st3m import logging

log = logging.Log(__name__, level=logging.INFO)
log.info("import")
from . import ui, event, menu

STATE_OFF = 0
STATE_INIT = 10
STATE_BACKGROUND = 200
STATE_FOREGROUND = 300
STATE_ERROR = 500

log.info("setting up application")


class Application:
    def __init__(
        self, title="badge23 app", author="someone@earth", exit_on_menu_enter=True
    ):
        log.info(f"__init__ app '{title}'")
        self.title = title
        self.author = author
        self.state = STATE_OFF
        self.has_background = False
        self.has_foreground = True
        self._events_background = []
        self._events_foreground = []
        self.ui = ui.Viewport()
        self.icon = ui.Icon(label=self.title, size=100)
        self.engine = event.the_engine
        self.menu = None
        if exit_on_menu_enter:
            self.add_event(
                event.Event(
                    name="exit",
                    action=self.exit,
                    condition=lambda e: e["type"] == "button"
                    and e["index"] == 1
                    and e.get("from") == 2
                    and e["change"],
                )
            )

    def __repr__(self):
        return "App " + self.title

    def init(self):
        log.info(f"init app '{self.title}'")
        self.state = STATE_INIT
        self.on_init()
        if self.has_background:
            if self._events_background:
                self._set_events(self._events_background, True)
            engine.register_service_loop(self.main_always, True)

    def run(self):
        log.info(f"run app '{self.title}' from state {self.state}")
        if self.state == STATE_OFF:
            log.info("from STATE_OFF, doing init()")
            self.init()
        if self.has_foreground:
            self._to_foreground()
        elif self.has_background:
            self._to_background()
        else:
            log.warning(
                f"App {self.title} has neither foreground nor background, not doing anything"
            )

        # start the eventloop if it is not already running
        if not event.the_engine.is_running:
            log.info("eventloop not yet running, starting")
            event.the_engine.eventloop()

    def exit(self, data={}):
        log.info(f"exit app '{self.title}' from state {self.state}")
        self.on_exit()
        if self.state == STATE_FOREGROUND:
            self._to_background()

    def kill(self):
        # disable all events
        log.info(f"kill app '{self.title}' from state {self.state}")
        engine.register_service_loop(self.main_always, False)

        engine.foreground_app = None
        self._set_events(self._events_background, False)
        self._set_events(self._events_forground, False)
        self.state = STATE_OFF

    def draw(self, ctx):
        self.ui.draw(ctx)
        self.on_draw(ctx)

    def tick(self):
        self.main_foreground()

    def add_event(self, event, is_background=False):
        if not is_background:
            self._events_foreground.append(event)
        else:
            self._events_background.append(event)

    def is_foreground(self):
        return self.state == STATE_FOREGROUND

    def _to_foreground(self):
        log.info(f"to_foreground app '{self.title}' from state {self.state}")
        if not self.has_foreground:
            log.error(f"app has no foreground!")
            return

        if self._events_background:
            self._set_events(self_events_background, False)
        self.state = STATE_FOREGROUND

        if self._events_foreground:
            self._set_events(self._events_foreground, True)

        # TODO(q3k): make this pending
        # self.ui.ctx.rgb(*ui.BLACK).rectangle(-120,-120,240,240).fill()
        # self.icon.draw()

        self.on_foreground()

        self.engine.foreground_app = self

    def _to_background(self):
        log.info(f"to_background app '{self.title}' from state {self.state}")
        self.state = STATE_BACKGROUND
        if self._events_foreground:
            self._set_events(self._events_foreground, False)

        self.engine.foreground_app = None
        menu.menu_back()
        if self.has_background:
            self.state = STATE_BACKGROUND
        self.on_background()

    def _set_events(self, events, enabled=True):
        for e in events:
            e.set_enabled(enabled)

    def on_init(self):
        log.info(f"app {self.title}: on_init()")

    def on_foreground(self):
        log.info(f"app {self.title}: on_foreground()")

    def on_background(self):
        log.info(f"app {self.title}: on_background()")

    def on_exit(self):
        log.info(f"app {self.title}: on_exit()")

    def on_kill(self):
        log.info(f"app {self.title}: on_kill()")

    def on_draw(self, ctx):
        log.debug(f"app {self.title}: on_draw()")

    def main_foreground(self):
        pass

    def main_always(self):
        pass

    def main(self):
        self.main_foreground()