import pyxel
from pyxel.constants import RENDERER_IMAGE_COUNT, RENDERER_TILEMAP_COUNT
from pyxel.ui import NumberPicker, RadioButton

from .constants import (
    EDITOR_IMAGE_X,
    EDITOR_IMAGE_Y,
    TILEMAP_IMAGE_X,
    TILEMAP_IMAGE_Y,
    TOOL_PENCIL,
)
from .edit_frame import EditFrame
from .editor import Editor
from .image_frame import ImageFrame
from .tilemap_frame import TilemapFrame


class TileMapEditor(Editor):
    def __init__(self, parent):
        super().__init__(parent)

        self._edit_frame = EditFrame(self, is_tilemap_mode=True)
        self._tilemap_frame = TilemapFrame(self)
        self._image_frame = ImageFrame(self, is_tilemap_mode=True)
        self._tilemap_picker = NumberPicker(
            self, 48, 161, 0, RENDERER_TILEMAP_COUNT - 1, 0
        )
        self._tool_button = RadioButton(
            self, 81, 161, 3, EDITOR_IMAGE_X + 63, EDITOR_IMAGE_Y, 7, TOOL_PENCIL
        )
        self._image_picker = NumberPicker(
            self, 192, 161, 0, RENDERER_IMAGE_COUNT - 2, 0
        )

        self.add_event_handler("undo", self.__on_undo)
        self.add_event_handler("redo", self.__on_redo)
        self.add_event_handler("update", self.__on_update)
        self.add_event_handler("draw", self.__on_draw)
        self.add_number_picker_help(self._tilemap_picker)
        self.add_number_picker_help(self._image_picker)
        self.add_tool_button_help(self._tool_button)

    @property
    def tilemap(self):
        return self._tilemap_picker.value

    @tilemap.setter
    def tilemap(self, value):
        self._tilemap_button.value = value

    @property
    def color(self):
        return (self._image_frame.select_y // 8) * 32 + self._image_frame.select_x // 8

    @color.setter
    def color(self, value):
        self._image_frame.select_y = (value // 32) * 8
        self._image_frame.select_x = (value % 32) * 8

    @property
    def tool(self):
        return self._tool_button.value

    @tool.setter
    def tool(self, value):
        self._tool_button.value = value

    @property
    def image(self):
        return self._image_picker.value

    @image.setter
    def image(self, value):
        self._image_button.value = value

    @property
    def edit_x(self):
        return self._edit_frame.viewport_x

    @edit_x.setter
    def edit_x(self, value):
        self._edit_frame.viewport_x = value

    @property
    def edit_y(self):
        return self._edit_frame.viewport_y

    @edit_y.setter
    def edit_y(self, value):
        self._edit_frame.viewport_y = value

    def __on_undo(self, data):
        tm = data["tilemap"]
        x, y = data["pos"]
        dest = pyxel.tilemap(tm).data[y : y + 16, x : x + 16]
        dest[:, :] = data["before"]

        self._edit_frame.edit_x = x
        self._edit_frame.edit_y = y
        self._tilemap_picker.value = tm

    def __on_redo(self, data):
        tm = data["tilemap"]
        x, y = data["pos"]
        dest = pyxel.tilemap(tm).data[y : y + 16, x : x + 16]
        dest[:, :] = data["after"]

        self._edit_frame.edit_x = x
        self._edit_frame.edit_y = y
        self._tilemap_picker.value = tm

    def __on_update(self):
        start_y = (pyxel.frame_count % 8) * 8
        for y in range(start_y, start_y + 8):
            for x in range(64):
                val = pyxel.tilemap(self.tilemap).data[y * 4 + 1, x * 4 + 1]
                col = pyxel.image(self.image).data[
                    (val // 32) * 8 + 3, (val % 32) * 8 + 3
                ]
                pyxel.image(3, system=True).data[
                    TILEMAP_IMAGE_Y + y, TILEMAP_IMAGE_X + x
                ] = col

        self.check_tool_button_shortcuts()

    def __on_draw(self):
        self.draw_frame(11, 156, 136, 17)
        self.draw_frame(157, 156, 72, 17)
        pyxel.text(18, 162, "TILEMAP", 6)
        pyxel.text(18, 162, "TILEMAP", 6)
        pyxel.text(170, 162, "IMAGE", 6)
