private void OnEnable()
 {
     Repaint();
     _assemblyTypes = Assembly.Load("Assembly-Csharp").GetTypes();
     _field         = new SearchField();
     _title         = new GuiBox("Class inspector", _titleRect.ApplyPadding(_padding), GuiBox.Style.Title);
 }
        private void UpdateLabels()
        {
            _labels.Clear();
            for (var i = 0; i < _results.Count; i++)
            {
                Rect rect = new Rect(10, 95 + i * 26, 150, 40);
                rect    = _labelsPos.ApplyPadding(_padding);
                rect.y += i * (_labelsPos.height + _labelsMargin);

                GuiBox label;
                if (_results[i] != null)
                {
                    label = new GuiBox(_results[i].FullName, rect, GuiBox.Style.Label);
                    label.SetType(_results[i]);
                }
                else
                {
                    label = new GuiBox("...", rect, GuiBox.Style.Label);
                }

                _labels.Add(label);
            }
        }
        private void OpenTree(Type searchType)
        {
            var assignees      = GetAssignableTypes(searchType);
            var countAssignees = new Dictionary <Type, int>();

            // Put all assignables to dictionary
            foreach (var a in assignees)
            {
                countAssignees.Add(a, 0);
            }

            // Search all assignees for subAssignees
            foreach (var type in assignees)
            {
                foreach (var subType in assignees)
                {
                    if (subType == type)
                    {
                        continue;
                    }
                    if (type.IsAssignableFrom(subType))
                    {
                        countAssignees[subType]++;
                    }
                }
            }

            _nodes.Clear();

            // Count number of nodes in each layer
            var itemsInLayer = new int[countAssignees.Values.Max() + 1];

            foreach (var assignee in countAssignees)
            {
                itemsInLayer[assignee.Value]++;
            }

            // Make nodes
            _nodes.Clear();
            GuiBox[] nodes = new GuiBox[countAssignees.Count + 1];
            int      index = 0;

            foreach (var assignee in countAssignees)
            {
                var node = new GuiBox(assignee.Key.FullName, new Rect(), GuiBox.Style.Node);
                node.SetType(assignee.Key);
                node.SetLayer(assignee.Value);
                nodes[index] = node;
                index++;
            }

            // Add search node
            var sNode = new GuiBox(searchType.FullName, new Rect(), GuiBox.Style.Node);

            sNode.SetLayer(-1);
            sNode.SetType(searchType);
            nodes[nodes.Length - 1] = sNode;

            // Assign in and out nodes
            int layer = countAssignees.Values.Max();

            while (layer > -1)
            {
                if (layer == 0)
                {
                    foreach (var node in nodes)
                    {
                        if (node.Layer == 0)
                        {
                            node.In.Add(sNode);
                        }
                    }
                }
                else
                {
                    foreach (var node in nodes)
                    {
                        if (node.Layer == layer)
                        {
                            foreach (var lowerLayerNode in nodes)
                            {
                                if (lowerLayerNode == node)
                                {
                                    continue;
                                }
                                if (lowerLayerNode.Layer == layer - 1)
                                {
                                    if (lowerLayerNode.Type.IsAssignableFrom(node.Type))
                                    {
                                        node.In.Add(lowerLayerNode);
                                    }
                                }
                            }
                        }
                    }
                }

                layer--;
            }

            // Initialize rects
            var           boxSize                = new Vector2(100, 50);
            var           boxOffset              = new Vector2(120, 60);
            var           possiblePos            = new Vector2(100, 0);
            var           removeInitializedNodes = new List <GuiBox>(nodes);
            var           firstLoop              = true;
            List <GuiBox> nextPossibleNode       = new List <GuiBox>();
            var           breakLoop              = 0;

            while (removeInitializedNodes.Count > 0)
            {
                breakLoop++;
                if (breakLoop > 1000)
                {
                    Debug.LogError("Not working, broke the loop");
                    break;
                }

                GuiBox currentNode, innerNode;
                Rect   rect;
                if (firstLoop)
                {
                    currentNode = GetHighestLayerNode(removeInitializedNodes);
                    if (currentNode == null)
                    {
                        break;
                    }
                    possiblePos.y = boxOffset.y * currentNode.Layer + 300;

                    rect = new Rect(possiblePos, boxSize);
                    currentNode.SetRect(rect);
                    currentNode.IsDrawn = true;
                    possiblePos.y      -= boxOffset.y;
                    removeInitializedNodes.Remove(currentNode);
                    firstLoop = false;
                    CheckNextPossibleNode(currentNode, removeInitializedNodes);
                    innerNode = currentNode.In[0];
                }
                else
                {
                    if (nextPossibleNode.Count > 0)
                    {
                        currentNode = nextPossibleNode[0];
                        nextPossibleNode.Remove(currentNode);
                        innerNode     = currentNode;
                        possiblePos.y = boxOffset.y * currentNode.Layer + 300;
                    }
                    else
                    {
                        currentNode   = GetHighestLayerNode(removeInitializedNodes);
                        innerNode     = currentNode;
                        possiblePos.y = boxOffset.y * currentNode.Layer + 300;
                    }
                }

                while (true)
                {
                    if (innerNode.IsDrawn)
                    {
                        break;
                    }

                    rect = new Rect(possiblePos, boxSize);
                    innerNode.SetRect(rect);
                    innerNode.IsDrawn = true;
                    possiblePos.y    -= boxOffset.y;
                    removeInitializedNodes.Remove(innerNode);

                    CheckNextPossibleNode(innerNode, removeInitializedNodes);
                    if (innerNode.In.Count < 1)
                    {
                        break;
                    }
                    innerNode = innerNode.In[0];
                }

                possiblePos.x += boxOffset.x;

                void CheckNextPossibleNode(GuiBox nodeToCheck, List <GuiBox> myNodes)
                {
                    if (nodeToCheck.In.Count < 1)
                    {
                        return;
                    }
                    foreach (var node1 in myNodes)
                    {
                        if (node1 == nodeToCheck)
                        {
                            continue;
                        }
                        if (nodeToCheck.In[0].Type.IsAssignableFrom(node1.Type))
                        {
                            if (node1.Layer == nodeToCheck.Layer)
                            {
                                nextPossibleNode.Add(node1);
                            }
                        }
                    }
                }

                GuiBox GetHighestLayerNode(List <GuiBox> myNodes)
                {
                    var    highestLayer = -1;
                    GuiBox highestNode  = null;

                    foreach (var node1 in myNodes)
                    {
                        if (node1.Layer > highestLayer)
                        {
                            highestLayer = node1.Layer;
                            highestNode  = node1;
                        }
                    }

                    return(highestNode);
                }
            }


            _nodes = nodes.ToList();
        }