import logging

from .pipe import Pipe
from .ui_frame import Frame

_logger = logging.getLogger('RPi.UIServer')  # type: logging.Logger


class UI:
    IS_VERTICAL = False

    FONT_SIZE = 12
    PADDING = 2

    COLOR_DISABLE = 'gray'
    COLOR_GND = 'black'
    COLOR_3V3 = 'dark orange'
    COLOR_5V = 'red'

    # W_TYPE_GPIO >= 0
    W_TYPE_GND = -1
    W_TYPE_3V3 = -2
    W_TYPE_5V = -3
    W_TYPE_ID_SC = -4

    def __init__(self, pipe, frame, plugins):
        # type: (Pipe, Frame) -> None
        self.__pipe = pipe
        self.__frame = frame
        self.__plugins = plugins

    def close(self):
        self.__frame.close()
        self.__pipe.write_bytes([Pipe.CMD_EXIT])
        self.__pipe.close()

    def run(self):
        self.__frame.run(self.__update, self.__toggle, self.close)

    def __toggle(self, channel):
        # type: (int) -> None
        self.__pipe.write_bytes([Pipe.CMD_CHANGE_GPIO_IN, channel])

    def __handle_buffer(self, buf):
        # type: (bytearray) -> None
        cmd = buf.pop(0)
        if cmd == Pipe.CMD_CLEANUP:
            channel = buf.pop(0)
            # TODO: if channel can't get, push back to buffer.
            _logger.debug("cleanup(%d)" % channel)
            self.__frame.cleanup(channel)
            for p in self.__plugins:
                p.cleanup(channel)
        else:
            channel = buf.pop(0)
            is_high = buf.pop(0)
            # TODO: if channel or is_high can't get, push back to buffer.
            if cmd == Pipe.CMD_CHANGE_GPIO_OUT:
                _logger.debug("change_gpio_out(%d,%d)" % (channel, is_high))
                self.__frame.change_gpio_out(channel, is_high == 1)
                for p in self.__plugins:
                    p.change_gpio_out(channel, is_high)
            elif cmd == Pipe.CMD_BIND_GPIO_IN:
                _logger.debug("bind_gpio_in(%d,%d)" % (channel, is_high))
                self.__frame.bind_gpio_in(channel, is_high == 1)
                for p in self.__plugins:
                    p.bind_gpio_in(channel, is_high)
            elif cmd == Pipe.CMD_CHANGE_GPIO_IN:
                _logger.debug("change_gpio_in(%d,%d)" % (channel, is_high))
                self.__frame.change_gpio_in(channel, is_high == 1)
                for p in self.__plugins:
                    p.change_gpio_in(channel, is_high)
            else:
                raise AssertionError('Illegal command value (%d)' % cmd)

    def __update(self):
        try:
            self.__frame.update()

            buf = bytearray()
            while True:
                data = self.__pipe.read_bytes()
                if not data:
                    break
                buf.extend(data)
                while len(buf) > 0:
                    self.__handle_buffer(buf)
        except Exception as ex:
            self.close()
            raise ex

@@ -145,277 +145,8 @@
 UI:%0A
-    IS_VERTICAL = False%0A%0A    FONT_SIZE = 12%0A    PADDING = 2%0A%0A    COLOR_DISABLE = 'gray'%0A    COLOR_GND = 'black'%0A    COLOR_3V3 = 'dark orange'%0A    COLOR_5V = 'red'%0A%0A    # W_TYPE_GPIO %3E= 0%0A    W_TYPE_GND = -1%0A    W_TYPE_3V3 = -2%0A    W_TYPE_5V = -3%0A    W_TYPE_ID_SC = -4%0A%0A
     

remove constants