// MonoBehaviour that allows attachment to a game object.
// This file should be attached to a GameObject with a UIDocument component and a UXML document assigned
// the UXML can be blank for this demonstration
// All examples use the same basic layout and logic and in pratice would be combined into create a proper UI
public class TextFieldBindingExample : MonoBehaviour
{
    private MyDataModel dataModel;
    private TextField textField;
    private InputAction spaceAction;
    void Awake()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;

        dataModel = new MyDataModel();
        textField = new TextField();

        // Setting the data source of an element will automatically apply to its children
        // UNLESS specifically changed at a later time.
        root.dataSource = dataModel;

        // Bind the text field to the data model using SetBinding
        // Set Binding needs the items destination container, here it is the VALUE for the Textfield element
        // and a binding that contains the datasourcepath within the datasource container
        // Here it is using a new PropertyPath with the name of the datasource and the field within.
        textField.SetBinding("value", new DataBinding
        {
            dataSourcePath = new PropertyPath(nameof(dataModel.MyText))
            
        });
        // Thats it, any data that changes to the value of datamodel.MyText will be populated into the UI element
        // Further options can be set that allow for two way data exchange and can be set when setting the datasource
        // like so: bindingMode = BindingMode.TwoWay
        // See: https://docs.unity3d.com/Manual/UIE-runtime-binding-mode-update.html

        // Add the text field to the UI so it can be displayed
        root.Add(textField);

        // Update the data model to see changes in the UI
        dataModel.MyText = "Hello, World!";

        // Create an action to listen for a space bar press
        spaceAction = new InputAction(binding: "<Keyboard>/space");
    }
    private void OnEnable()
    {
        spaceAction.Enable();
        spaceAction.performed += ChangeData;
    }

    private void OnDisable()
    {
        spaceAction.Disable();
        spaceAction.performed -= ChangeData;
    }


    private void ChangeData(InputAction.CallbackContext callbackContext)
    {
        // Change the data in the DataModel and see it update the UI
        dataModel.MyText = $"Hello, World! {Random.Range(0, 1000)} ";
    }
}