/// <summary>
    /// Creates a new grid of empty EditableGridCell instances. Does not load values from serializedLevel.
    /// </summary>
    void RebuildGrid()
    {
        Debug.Log("rebuild grid");
        grid = new EditableGridCell[gridWidth, gridHeight];

        VisualElement cellContainer = rootVisualElement.Q <VisualElement>("grid");

        cellContainer.Clear();

        for (int j = 0; j < gridHeight; ++j)
        {
            VisualElement row = new VisualElement();
            row.style.flexDirection = FlexDirection.Row;

            for (int i = 0; i < gridWidth; ++i)
            {
                VisualElement cell = new VisualElement();
                cellTemplate.CloneTree(cell);

                // name the cell with its coordinates (important for the MouseDownEvent callback)
                cell.name = i + " " + j;
                row.Add(cell);

                //make new empty grid cell
                grid[i, j] = new EditableGridCell()
                {
                    x = i,
                    y = j,

                    presetContent = false,
                    content       = LevelEditorCellContent.random,
                    hole          = false
                };

                // register callback on the cell
                cell.RegisterCallback <MouseDownEvent>(evt => MouseDownCellCallback(evt, cell));
            }
            cellContainer.Add(row);
        }
    }
    /// <summary>
    /// Loads property values from serializedLevel for gridHeight, gridWidth, name. Creates a new grid of
    /// EditableGridCell structs and fills them with values from serializedLevel's grid.
    /// </summary>
    public void LoadAndSetupGrid()
    {
        name       = serializedLevel.FindProperty("levelName").stringValue;
        gridWidth  = serializedLevel.FindProperty("gridWidth").intValue;
        gridHeight = serializedLevel.FindProperty("gridHeight").intValue;

        SerializedProperty gridProperty = serializedLevel.FindProperty("grid");

        grid = new EditableGridCell[gridWidth, gridHeight];

        VisualElement cellContainer = rootVisualElement.Q <VisualElement>("grid");

        cellContainer.Clear();

        for (int j = 0; j < gridHeight; ++j)
        {
            VisualElement row = new VisualElement();
            row.style.flexDirection = FlexDirection.Row;

            for (int i = 0; i < gridWidth; ++i)
            {
                VisualElement cell = new VisualElement();
                cellTemplate.CloneTree(cell);

                // name the cell with its coordinates (important for the MouseDownEvent callback)
                cell.name = i + " " + j;
                row.Add(cell);

                //make new grid cell
                grid[i, j] = new EditableGridCell();

                //register the callback on the cell
                cell.RegisterCallback <MouseDownEvent>(evt => MouseDownCellCallback(evt, cell));

                // load cell values from SerializedObject
                SerializedProperty serializedCell = gridProperty.GetArrayElementAtIndex(i * gridHeight + j);
                grid[i, j].x             = serializedCell.FindPropertyRelative("x").intValue;
                grid[i, j].y             = serializedCell.FindPropertyRelative("y").intValue;
                grid[i, j].hole          = serializedCell.FindPropertyRelative("hole").boolValue;
                grid[i, j].presetContent = serializedCell.FindPropertyRelative("presetContent").boolValue;
                grid[i, j].content       = (LevelEditorCellContent)serializedCell.FindPropertyRelative("content").intValue;

                // if the cell we loaded is a hole, update its display
                if (grid[i, j].hole)
                {
                    VisualElement bg = cell.Q <VisualElement>("Cell");
                    bg.style.visibility = Visibility.Hidden;
                }

                VisualElement cellBackground = cell.Q <VisualElement>("Cell");

                RemoveCandyClassesFromCell(cellBackground);

                switch (grid[i, j].content)
                {
                case LevelEditorCellContent.random:
                    cellBackground.AddToClassList("empty");
                    break;

                case LevelEditorCellContent.candy_blue:
                    cellBackground.AddToClassList("candy-blue");
                    break;

                case LevelEditorCellContent.candy_red:
                    cellBackground.AddToClassList("candy-red");
                    break;

                case LevelEditorCellContent.candy_green:
                    cellBackground.AddToClassList("candy-green");
                    break;

                case LevelEditorCellContent.candy_orange:
                    cellBackground.AddToClassList("candy-orange");
                    break;

                case LevelEditorCellContent.candy_yellow:
                    cellBackground.AddToClassList("candy-yellow");
                    break;
                }
            }
            cellContainer.Add(row);
        }
    }