# -*- coding: utf-8 -*-
"""
"""

import regex as re
from prettyqt import core, widgets, custom_widgets, custom_validators


class RegexInput(widgets.Widget):

    value_changed = core.Signal()

    def __init__(self, show_flags=True, show_error=True, parent=None):
        super().__init__(parent=parent)
        self.set_layout("grid")
        self.lineedit = custom_widgets.SingleLineTextEdit()
        self.tb_flags = custom_widgets.BoolDictToolButton("Flags",
                                                          icon="mdi.flag-variant-outline")
        self.label_error = widgets.Label()
        self.label_error.setStyleSheet("color: #FF0000;")
        self.box[0, 0:1] = self.lineedit
        if show_flags:
            self.box[0, 2] = self.tb_flags
        if show_error:
            self.box[1, 0:2] = self.label_error
        self.tb_flags.triggered.connect(self._on_value_change)
        self.lineedit.textChanged.connect(self._on_value_change)
        val = custom_validators.RegexPatternValidator()
        self.lineedit.set_validator(val)
        dct = {"multiline": "MultiLine",
               "ignorecase": "Ignore case",
               "ascii": "ASCII-only matching",
               "dotall": "Dot matches newline",
               "verbose": "Ignore whitespace"}
        self._mapping = {"ignorecase": re.IGNORECASE,
                         "multiline": re.MULTILINE,
                         "ascii": re.ASCII,
                         "dotall": re.DOTALL,
                         "verbose": re.VERBOSE}
        self.tb_flags.set_dict(dct)

    def _on_value_change(self):
        self.value_changed.emit()
        if self.lineedit.is_valid():
            self.label_error.set_text("")
        else:
            message = self.lineedit.validator.error_message
            self.label_error.set_text(message)

    @property
    def pattern(self):
        return self.lineedit.text()

    @pattern.setter
    def pattern(self, value):
        self.lineedit.set_text(value)

    @property
    def compile_flags(self):
        ret_val = 0
        for identifier, flag in self._mapping.items():
            if self.tb_flags[identifier]:
                ret_val |= flag
        return ret_val

    @compile_flags.setter
    def compile_flags(self, value):
        for identifier, flag in self._mapping.items():
            self.tb_flags[identifier] = bool(value & flag)

    def set_value(self, value):
        if value is None:
            self.pattern = ""
            self.flags = 0
        if isinstance(value, str):
            self.pattern = value
            self.flags = 0
        else:
            self.pattern = value.pattern
            self.compile_flags = value.flags

    def get_value(self):
        return re.compile(self.pattern, self.compile_flags)

    def is_valid(self):
        return self.lineedit.is_valid()


if __name__ == "__main__":
    app = widgets.app()
    widget = RegexInput(show_flags=False, show_error=False)
    widget.show()
    app.exec_()
