# Autogenerated file. Do not edit.
from jacdac.bus import Bus, Client
from .constants import *
from typing import Optional


class IndexedScreenClient(Client):
    """
    A screen with indexed colors.
     * 
     * This is often run over an SPI connection, not regular single-wire Jacdac.
    Implements a client for the `Indexed screen <https://microsoft.github.io/jacdac-docs/services/indexedscreen>`_ service.

    """

    def __init__(self, bus: Bus, role: str) -> None:
        super().__init__(bus, JD_SERVICE_CLASS_INDEXED_SCREEN, JD_INDEXED_SCREEN_PACK_FORMATS, role)


    @property
    def brightness(self) -> Optional[float]:
        """
        Set backlight brightness.
        If set to `0` the display may go to sleep., _: /
        """
        return self.register(JD_INDEXED_SCREEN_REG_BRIGHTNESS).float_value(100)

    @brightness.setter
    def brightness(self, value: float) -> None:
        self.register(JD_INDEXED_SCREEN_REG_BRIGHTNESS).set_values(value / 100)


    @property
    def bits_per_pixel(self) -> Optional[int]:
        """
        Determines the number of palette entries.
        Typical values are 1, 2, 4, or 8., _: bit
        """
        return self.register(JD_INDEXED_SCREEN_REG_BITS_PER_PIXEL).value()

    @property
    def width(self) -> Optional[int]:
        """
        Screen width in "natural" orientation., _: px
        """
        return self.register(JD_INDEXED_SCREEN_REG_WIDTH).value()

    @property
    def height(self) -> Optional[int]:
        """
        Screen height in "natural" orientation., _: px
        """
        return self.register(JD_INDEXED_SCREEN_REG_HEIGHT).value()

    @property
    def width_major(self) -> Optional[bool]:
        """
        If true, consecutive pixels in the "width" direction are sent next to each other (this is typical for graphics cards).
        If false, consecutive pixels in the "height" direction are sent next to each other.
        For embedded screen controllers, this is typically true iff `width < height`
        (in other words, it's only true for portrait orientation screens).
        Some controllers may allow the user to change this (though the refresh order may not be optimal then).
        This is independent of the `rotation` register., 
        """
        return self.register(JD_INDEXED_SCREEN_REG_WIDTH_MAJOR).bool_value()

    @width_major.setter
    def width_major(self, value: bool) -> None:
        self.register(JD_INDEXED_SCREEN_REG_WIDTH_MAJOR).set_values(value)


    @property
    def up_sampling(self) -> Optional[int]:
        """
        Every pixel sent over wire is represented by `up_sampling x up_sampling` square of physical pixels.
        Some displays may allow changing this (which will also result in changes to `width` and `height`).
        Typical values are 1 and 2., _: px
        """
        return self.register(JD_INDEXED_SCREEN_REG_UP_SAMPLING).value()

    @up_sampling.setter
    def up_sampling(self, value: int) -> None:
        self.register(JD_INDEXED_SCREEN_REG_UP_SAMPLING).set_values(value)


    @property
    def rotation(self) -> Optional[int]:
        """
        Possible values are 0, 90, 180 and 270 only.
        Write to this register do not affect `width` and `height` registers,
        and may be ignored by some screens., _: °
        """
        return self.register(JD_INDEXED_SCREEN_REG_ROTATION).value()

    @rotation.setter
    def rotation(self, value: int) -> None:
        self.register(JD_INDEXED_SCREEN_REG_ROTATION).set_values(value)



    def start_update(self, x: int, y: int, width: int, height: int) -> None:
        """
        Sets the update window for subsequent `set_pixels` commands.
        """
        self.send_cmd_packed(JD_INDEXED_SCREEN_CMD_START_UPDATE, x, y, width, height)

    def set_pixels(self, pixels: bytes) -> None:
        """
        Set pixels in current window, according to current palette.
        Each "line" of data is aligned to a byte.
        """
        self.send_cmd_packed(JD_INDEXED_SCREEN_CMD_SET_PIXELS, pixels)
    
