# ACT-R tutorial unit 2 demo2 task.
# This experiment opens a window, displays a character,
# waits for a keypress, clears the window after there
# is a keypress, and then reports the key that was pressed.

# Import the actr module for tutorial tasks

import actr

# Load the corresponding tutorial model

actr.load_act_r_model("ACT-R:tutorial;unit2;demo2-model.lisp")


# Create a variable to store the key that was pressed.

response = False


# This is the function which we will have ACT-R call when
# a key is pressed in the experiment window which is signaled
# by the output-key action.

# That action provides two parameters to the function called.
# The first is the name of the model that performed the keypress
# or None if it wasn't generated by a model, and the second
# is a string with the name of the key that was pressed.

  
def respond_to_key_press (model,key):

    # store the key that was pressed in the response variable
    # call the AGI command that clears the window

    global response
    response = key

    actr.clear_exp_window()

  


# This is the function that runs the experiment for either a
# person or a model.  It has one optional parameter which if
# provided as True will run a person.
# If it is not provided or any other value is specified then
# it will run the model.

def experiment (human=False):
  
    # Reset the ACT-R system and any models that are defined to
    # their initial states.
  
    actr.reset()
  
    # Create three variable:
    #   items - a randomized list of letter strings which is randomized
    #           using the ACT-R function permute_list
    #   text1 - the first string from the randomized list which will be the
    #           one presented in the experiment
    #   window - the ACT-R window device list returned by using the ACT-R
    #            function open_exp_window to create a new window for 
    #            displaying the experiment 
  
    
    items = actr.permute_list(["B","C","D","F","G","H","J","K","L",
                               "M","N","P","Q","R","S","T","V","W",
                               "X","Y","Z"])
    text1 = items[0]
    window = actr.open_exp_window("Letter recognition")

    # display the text1 item in the window that was opened
    
    actr.add_text_to_exp_window(window, text1, x=125, y=150)


    # These next two function calls are how we tell ACT-R that it should
    # call our respond_to_key_press function when there is a keypress
    # in the experiment.
    
    # First we need to create a command in ACT-R that corresponds
    # to our function so that ACT-R is able to use the function.

    actr.add_command("demo2-key-press",respond_to_key_press,
                     "Demo2 task output-key monitor")
    
    # Then, we use that command which we created to 'monitor' 
    # the output-key action which is triggered by keypress in the
    # experiment window of ACT-R so that when an output-key happens
    # our function is called.
    
    actr.monitor_command("output-key","demo2-key-press")
    
    # Set the response value to False to remove any value it may
    # have from a previous run of the experiment.
    
    global response
    response = False
    
    # Here is where we actually "run" the experiment.
    # It either waits for a person to press a key or runs ACT-R
    # for up to 10 seconds giving the model a chance to do the
    # experiment.
    
        
    if human == True:

        # If a person is doing the task then for safety 
        # we make sure there is a visible window that they
        # can use to do the task, and if so, loop until the
        # response variable is not False calling the ACT-R
        # process_events function to allow the system a 
        # chance to handle any interactions.

        if actr.visible_virtuals_available():
            while response == False:
                actr.process_events()
      
    else:
      
        # If it is not a human then use install_device so that
        # the features in the window will be seen by the model
        # (that will also automatically provide the model with
        # access to a virtual keyboard and mouse).  Then use
        # the ACT-R run function to run the model for up to 10
        # seconds in real-time mode.
      
        actr.install_device(window)
        actr.run(10,True)
    
    # To avoid any issues with our function for keypresses in this
    # experiment interfering with other experiments we should stop
    # monitoring output-key and then remove our command.

    actr.remove_command_monitor("output-key","demo2-key-press")
    actr.remove_command("demo2-key-press")
    
    # return the result of the keypress

    return response
