/// <summary>
        /// Applies the new layer name to all items, and updates internals.
        /// </summary>
        /// <param name="element">Renamed layer tree element</param>
        /// <param name="newName">Validated name</param>
        internal void OnLayerRenamed(LayerTreeElement element, string newName)
        {
            if (element.LayerName == newName)
            {
                return;
            }

            // Check if there is not already a layers with the same name
            if (_layers.ContainsKey(newName))
            {
                EditorUtility.DisplayDialog("Visual Pinball", $"There is already a layer named {newName}.\nFind another layer name.", "Close");
                return;
            }

            // Rename in _layers
            if (_layers.TryGetValue(element.LayerName, out var items))
            {
                _layers.Remove(element.LayerName);
                _layers[newName] = items;
            }
            element.LayerName = newName;

            // Update layer name for all items within this layer
            if (element.HasChildren)
            {
                ApplyLayerNameToItems(element.GetChildren <LayerTreeElement>(), newName);
            }
            RebuildTree();
        }
        private void AssignToLayer(LayerTreeElement[] elements, LayerTreeElement layer)
        {
            if (layer.Type != LayerTreeViewElementType.Layer)
            {
                return;
            }

            foreach (var element in elements)
            {
                if (element.Type == LayerTreeViewElementType.Item)
                {
                    element.ReParent(layer);
                }
            }
            Rebuild();
        }
        /// <summary>
        /// Callback when a TreeViewItem is double clicked
        /// </summary>
        /// <param name="element">the TreeElement attached to the TreeViewItem</param>
        internal static void OnItemDoubleClicked(LayerTreeElement element)
        {
            switch (element.Type)
            {
            case LayerTreeViewElementType.Table:
            case LayerTreeViewElementType.Layer: {
                LayerTreeElement[] items = element.GetChildren <LayerTreeElement>(child => child.Type == LayerTreeViewElementType.Item);
                Selection.objects = items.Select(item => EditorUtility.InstanceIDToObject(item.Id)).ToArray();
                break;
            }

            case LayerTreeViewElementType.Item: {
                Selection.activeObject = EditorUtility.InstanceIDToObject(element.Id);
                break;
            }
            }
        }
        private void RebuildTree()
        {
            TreeRoot.Children.Clear();

            // init with root element
            if (_tableBehavior != null && _tableBehavior.Table != null)
            {
                // table node
                var tableItem = new LayerTreeElement(_tableBehavior.Table)
                {
                    Id = 0
                };
                TreeRoot.AddChild(tableItem);

                var layerCount = 1;
                foreach (var pair in _layers.OrderBy(key => key.Key))
                {
                    // layer node
                    var layerItem = new LayerTreeElement(pair.Key)
                    {
                        Id = layerCount++
                    };
                    tableItem.AddChild(layerItem);

                    foreach (var item in pair.Value.OrderBy(behaviour => behaviour.name))
                    {
                        if (item is ILayerableItemBehavior layeredItem)
                        {
                            layerItem.AddChild(new LayerTreeElement(layeredItem)
                            {
                                Id = item.gameObject.GetInstanceID()
                            });
                        }
                    }
                }
            }

            TreeRebuilt?.Invoke();
        }
 internal void OnItemsDropped(LayerTreeElement[] droppedElements, LayerTreeElement newParent)
 {
     AssignToLayer(droppedElements, newParent);
 }