# Path: sc8pr/util.py
# def nothing(*args): pass
# 
# Path: sc8pr/gui/dialog.py
# class MessageBox(Dialog):
#     "Create simple GUI dialogs"
# 
#     def __init__(self, text, userInput=None, buttons=None, title=None, size=(1,1), inputWidth=None, **kwargs):
#         super().__init__(size)
#         self.command = None
# 
#         # Text options
#         txtConfig = {"font":Font.sans(), "fontSize":15}
#         txtConfig.update(kwargs)
# 
#         # Compose button text
#         if buttons is None:
#             buttons = ["Okay", "Cancel"]
#         elif type(buttons) is str: buttons = buttons,
#         if len(buttons) > 2: buttons = buttons[:2]
# 
#         # Add buttons
#         bSize = None
#         icon = True
#         for t in buttons:
#             t = Text(t).config(**txtConfig)
#             if not bSize: bSize = 0, t.height + 12
#             name = "Button_{}".format(t.data)
#             self[name] = Button(bSize, 2).textIcon(t, icon).config(anchor=BOTTOM)
#             icon = not icon
#         self.buttons = self[:len(buttons)]
#         for b in self.buttons: b.bind(onaction=_btnClick)
# 
#         # Add text label and text input
#         self["Text"] = text = Text(text).config(anchor=TOP, **txtConfig)
#         if userInput is None and isinstance(self, NumInputBox):
#             userInput = ""
#         if userInput is not None:
#             if inputWidth and inputWidth < text.width:
#                 inputWidth = text.width
#             self["Input"] = TextInputCanvas(inputWidth, userInput,
#                 "Click to enter your response", **txtConfig).config(anchor=TOP,
#                 bg="white")
#             self["Input"].ti.config(blurAction=False, mb=self).bind(onaction=_tiAction)
# 
#         # Position controls and add title bar
#         self._arrange().config(bg="#f0f0f0", weight=2, border="blue")
#         if title: self.title(title, **txtConfig)
# 
#     def _arrange(self, padding=12):
#         "Adjust size and position of controls"
# 
#         # Get references to controls
#         try: ti = self["Input"]
#         except: ti = None
#         btns = self.buttons
#         text = self["Text"]
# 
#         # Calculate button width and position button text
#         w = max(b.width for b in btns)
#         for b in btns:
#             t = b[-1]
#             pos = t.pos[0] + (w - b.width) / 2, t.pos[1]
#             t.config(pos=pos)
#             b._size = w, self[0].height
# 
#         # Calculate dialog dimensions
#         w = len(btns) * (w + padding) - padding
#         w = max(w, text.width, ti.width if ti else 0) + 2 * padding
#         h = btns[0].height + text.height + 3 * padding
#         if ti: h += ti.height + padding
#         y = max(h, self._size[1])
#         self._size = max(w, self._size[0]), y
#         
#         # Position text label and text input
#         x = self.center[0]
#         text.config(pos=(x, padding))
#         if ti: ti.config(pos=(x, text.height + 2 * padding))
# 
#         # Position buttons
#         if len(btns) > 1: x -= (btns[0].width + padding) / 2
#         y -= padding
#         for b in btns:
#             b.config(pos=(x,y))
#             x = self._size[0] - x
#         return self
# 
#     @property
#     def data(self):
#         "Get the data from the text input"
#         try: ti = self["Input"].ti.data
#         except: ti = None
#         return ti
# 
#     @property
#     def result(self):
#         cmd = self.command
#         btn = self.buttons
#         if len(btn) > 1 and cmd == btn[1]: # Cancel button
#             return False
#         if cmd is None or not self.valid: # Not finished
#             return None
#         return True if self.data is None else self.data
# 
#     @property
#     def valid(self): return True
# 
#     def onaction(self, ev):
#         "Remove dialog when dismissed"
#         if self.result is None:
#             self.command = None
#         else:
#             self.remove().canvas.bubble("onaction", ev)
# 
#     def ondrag(self, ev):
#         ti = "Input" in self and self["Input"] in ev.hover.path
#         if not ti: ondrag(self, ev)
# 
# class NumInputBox(MessageBox):
# 
#     @property
#     def data(self):
#         try: ti = float(self["Input"].ti.data)
#         except: ti = None
#         return ti
# 
#     @property
#     def valid(self):
#         return self.data is not None


from sc8pr.util import nothing
from sc8pr.gui.dialog import MessageBox, NumInputBox
import sc8pr.robot
#
# You should have received a copy of the GNU General Public License
# along with "sc8pr".  If not, see <http://www.gnu.org/licenses/>.

"GUI methods for robot-user interaction"



class Robot(sc8pr.robot.Robot):

    def _title(self, title):
        if not title:
            name = self.name
            if name is None: name = "Robot"
            title = "{} says...".format(name)
        return title

    def confirm(self, prompt, title=None, response=True):
        "Synchronous input to the robot brain"
        sk = self.sketch
        btns = ["Yes", "No"] if response else ["Okay"]
        mb = MessageBox(prompt, None, btns, self._title(title))
        mb.config(pos=sk.center).setCanvas(sk)
        while mb.result is None: self.updateSensors()
        return mb.result

    def textinput(self, prompt, title=None, allowCancel=False, num=False):
        "Synchronous input to the robot brain"
        sk = self.sketch
        btns = None if allowCancel else ["Okay"]

# Path: sc8pr/util.py
# def nothing(*args): pass
# 
# Path: sc8pr/gui/dialog.py
# class MessageBox(Dialog):
#     "Create simple GUI dialogs"
# 
#     def __init__(self, text, userInput=None, buttons=None, title=None, size=(1,1), inputWidth=None, **kwargs):
#         super().__init__(size)
#         self.command = None
# 
#         # Text options
#         txtConfig = {"font":Font.sans(), "fontSize":15}
#         txtConfig.update(kwargs)
# 
#         # Compose button text
#         if buttons is None:
#             buttons = ["Okay", "Cancel"]
#         elif type(buttons) is str: buttons = buttons,
#         if len(buttons) > 2: buttons = buttons[:2]
# 
#         # Add buttons
#         bSize = None
#         icon = True
#         for t in buttons:
#             t = Text(t).config(**txtConfig)
#             if not bSize: bSize = 0, t.height + 12
#             name = "Button_{}".format(t.data)
#             self[name] = Button(bSize, 2).textIcon(t, icon).config(anchor=BOTTOM)
#             icon = not icon
#         self.buttons = self[:len(buttons)]
#         for b in self.buttons: b.bind(onaction=_btnClick)
# 
#         # Add text label and text input
#         self["Text"] = text = Text(text).config(anchor=TOP, **txtConfig)
#         if userInput is None and isinstance(self, NumInputBox):
#             userInput = ""
#         if userInput is not None:
#             if inputWidth and inputWidth < text.width:
#                 inputWidth = text.width
#             self["Input"] = TextInputCanvas(inputWidth, userInput,
#                 "Click to enter your response", **txtConfig).config(anchor=TOP,
#                 bg="white")
#             self["Input"].ti.config(blurAction=False, mb=self).bind(onaction=_tiAction)
# 
#         # Position controls and add title bar
#         self._arrange().config(bg="#f0f0f0", weight=2, border="blue")
#         if title: self.title(title, **txtConfig)
# 
#     def _arrange(self, padding=12):
#         "Adjust size and position of controls"
# 
#         # Get references to controls
#         try: ti = self["Input"]
#         except: ti = None
#         btns = self.buttons
#         text = self["Text"]
# 
#         # Calculate button width and position button text
#         w = max(b.width for b in btns)
#         for b in btns:
#             t = b[-1]
#             pos = t.pos[0] + (w - b.width) / 2, t.pos[1]
#             t.config(pos=pos)
#             b._size = w, self[0].height
# 
#         # Calculate dialog dimensions
#         w = len(btns) * (w + padding) - padding
#         w = max(w, text.width, ti.width if ti else 0) + 2 * padding
#         h = btns[0].height + text.height + 3 * padding
#         if ti: h += ti.height + padding
#         y = max(h, self._size[1])
#         self._size = max(w, self._size[0]), y
#         
#         # Position text label and text input
#         x = self.center[0]
#         text.config(pos=(x, padding))
#         if ti: ti.config(pos=(x, text.height + 2 * padding))
# 
#         # Position buttons
#         if len(btns) > 1: x -= (btns[0].width + padding) / 2
#         y -= padding
#         for b in btns:
#             b.config(pos=(x,y))
#             x = self._size[0] - x
#         return self
# 
#     @property
#     def data(self):
#         "Get the data from the text input"
#         try: ti = self["Input"].ti.data
#         except: ti = None
#         return ti
# 
#     @property
#     def result(self):
#         cmd = self.command
#         btn = self.buttons
#         if len(btn) > 1 and cmd == btn[1]: # Cancel button
#             return False
#         if cmd is None or not self.valid: # Not finished
#             return None
#         return True if self.data is None else self.data
# 
#     @property
#     def valid(self): return True
# 
#     def onaction(self, ev):
#         "Remove dialog when dismissed"
#         if self.result is None:
#             self.command = None
#         else:
#             self.remove().canvas.bubble("onaction", ev)
# 
#     def ondrag(self, ev):
#         ti = "Input" in self and self["Input"] in ev.hover.path
#         if not ti: ondrag(self, ev)
# 
# class NumInputBox(MessageBox):
# 
#     @property
#     def data(self):
#         try: ti = float(self["Input"].ti.data)
#         except: ti = None
#         return ti
# 
#     @property
#     def valid(self):
#         return self.data is not None


# Path: sc8pr/robot/gui.py
from sc8pr.util import nothing
from sc8pr.gui.dialog import MessageBox, NumInputBox
import sc8pr.robot

#
# You should have received a copy of the GNU General Public License
# along with "sc8pr".  If not, see <http://www.gnu.org/licenses/>.

"GUI methods for robot-user interaction"



class Robot(sc8pr.robot.Robot):

    def _title(self, title):
        if not title:
            name = self.name
            if name is None: name = "Robot"
            title = "{} says...".format(name)
        return title

    def confirm(self, prompt, title=None, response=True):
        "Synchronous input to the robot brain"
        sk = self.sketch
        btns = ["Yes", "No"] if response else ["Okay"]
        mb = MessageBox(prompt, None, btns, self._title(title))
        mb.config(pos=sk.center).setCanvas(sk)
        while mb.result is None: self.updateSensors()
        return mb.result

    def textinput(self, prompt, title=None, allowCancel=False, num=False):
        "Synchronous input to the robot brain"
        sk = self.sketch
        btns = None if allowCancel else ["Okay"]

        cls = NumInputBox if num else MessageBox