import sys
import time
import threading
import wx

from dlg import G2MultiChoiceDialog
import wxsim

dlgResults = {}
def ShowAsNonModal(dlg,callback):
    def handle_dialog_end_ok():
        dlgResults['selected'] = dlg.GetSelections()
        print('Selected:', dlgResults['selected'])
        dlg.Destroy()
        parent.Enable()
        if callback:
            wx.CallLater(500, callback)
    def handle_dialog_end_cancel():
        dlgResults['selected'] = None
        dlg.Destroy()
        parent.Enable()
        raise Exception("Cancel button pressed")

    def on_ok(event):
        event.Skip()
        handle_dialog_end_ok()
    
    def on_cancel(event):
        event.Skip()
        handle_dialog_end_cancel()
    
    def on_close(event):
        event.Skip()
        handle_dialog_end_cancel()
        
    # Bind to both button events and window close
    dlg.Bind(wx.EVT_BUTTON, on_ok, id=wx.ID_OK)
    dlg.Bind(wx.EVT_BUTTON, on_cancel, id=wx.ID_CANCEL)
    dlg.Bind(wx.EVT_CLOSE, on_close)

    parent = dlg.GetParent()
    parent.Disable()  # Disable main window while dialog is open
    dlg.Show()

def openSelThread(event):
    'runs openSelect in a separate thread so it can have delays, etc.'
    threading.Thread(target=openSelect).start()

def openSelect():
    '''launches a dialog and a window to act on that dialog. 

    The routine called here, start_dialog is hard-coded to use 
    G2MultiChoiceDialog and wxsim.pressButtonsInWindow closes the dialog.

    Does this twice, just to prove I can.

    This is run in a thread so it can have delays etc.
    '''
    for i in range(2):
        if i != 0: time.sleep(1.0) # pause for a bit for viewer to see before doing it again
        dlgResults.clear()
        wx.CallAfter(start_dialog,('Select atoms for action',['Set All','OK']))
        count = 0
        while len(dlgResults) == 0:
            time.sleep(0.1)
            count += 1
        print('after wait',dlgResults,count)
        
def start_dialog(action):
    '''Show a dialog and set up its automation. 

    This calls G2MultiChoiceDialog and wxsim.pressButtonsInWindow. 
    The first would normally be a modal window and 
    pressButtonsInWindow simulates pressing two buttons
    in the dialog, where the second closes the dialog.

    This runs inside a CallAfter instance, so it should complete
    with minimal delays so that it does not hold up the event loop
    '''
    # open window
    choices = ['Bi1', 'O1', 'Cl1']
    dlg = G2MultiChoiceDialog(None,'Select atoms',
                'Select atoms for action',choices)
    # Automate actions in window, after delay for the window to render
    # use CallLater so that this routine completes ASAP
    wx.CallLater(200, lambda: threading.Thread(
            target=wxsim.pressButtonsInWindow,
            args=action).start())
    ShowAsNonModal(dlg,None) # this replaces the ShowModal, but does not wait
        
app = wx.App()
frm = wx.Frame(None)
ms = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(frm,wx.ID_ANY,'Open modal window')
btn.Bind(wx.EVT_BUTTON,openSelThread)
ms.Add(btn)
frm.SetSizer(ms)
frm.Show(True)
app.MainLoop()
