/// <summary>
 /// A manager for a quadtree data structure.
 /// </summary>
 /// <param name="x">The x position of the top-left corner of the root node bounding box.</param>
 /// <param name="y">The y position of the top-left corner of the root node bounding box.</param>
 /// <param name="width">The width of the root node bounding box.</param>
 /// <param name="height">The height of the root node bounding box.</param>
 public GenQuadtree(float x, float y, float width, float height)
 {
     MaxObjects = 5;
     MaxLevels = 5;
     _rootNode = new GenQuadtreeNode(x, y, width, height, this, null, 0);
     Objects = new List<GenObject>();
     _activeObjects = new List<GenObject>();
     _updateObjects = false;
     _objectLocations = new Dictionary<GenObject, GenQuadtreeNode>();
 }
 /// <summary>
 /// A single node within a quadtree data structure.
 /// Used as a container for objects or other nodes.
 /// </summary>
 /// <param name="x">The x position of the top-left corner of the node bounding box.</param>
 /// <param name="y">The y position of the top-left corner of the node bounding box.</param>
 /// <param name="width">The width of the node bounding box.</param>
 /// <param name="height">The height of the node bounding box.</param>
 /// <param name="quadtree">A reference to the quadtree manager of this node.</param>
 /// <param name="parentNode">The quadtree node that this node is a leaf of. Use null if this is a root node.</param>
 /// <param name="level">The split level of the node.</param>
 public GenQuadtreeNode(float x, float y, float width, float height, GenQuadtree quadtree, GenQuadtreeNode parentNode, int level)
     : base(x, y, width, height)
 {
     _quadtree = quadtree;
     _parentNode = parentNode;
     _level = level;
     _objects = new List<GenObject>();
     _objectCount = 0;
     _nodes = new GenQuadtreeNode[4];
 }
        internal void Add(GenObject gameObject)
        {
            if (_nodes[0] == null)
            {
                Insert(gameObject);

                // If the node is full, attempt to add each of its objects into a leaf node.
                if ((_objects.Count >= _quadtree.MaxObjects) && (_level < _quadtree.MaxLevels))
                {
                    int nextLevel = _level + 1;

                    // Create the leaf nodes.
                    _nodes[0] = new GenQuadtreeNode(_minX, _minY, _halfWidth, _halfHeight, _quadtree, this, nextLevel);
                    _nodes[1] = new GenQuadtreeNode(_midpointX, _minY, _halfWidth, _halfHeight, _quadtree, this, nextLevel);
                    _nodes[2] = new GenQuadtreeNode(_minX, _midpointY, _halfWidth, _halfHeight, _quadtree, this, nextLevel);
                    _nodes[3] = new GenQuadtreeNode(_midpointX, _midpointY, _halfWidth, _halfHeight, _quadtree, this, nextLevel);

                    // Iterate through the objects list in reverse, attempting to add each object into a leaf node.
                    // Otherwise, leave the object in this node.
                    for (int i = _objects.Count - 1; i >= 0; i--)
                    {
                        int index = GetIndex(_objects[i].MoveBounds);

                        if (index != -1)
                        {
                            _nodes[index].Add(_objects[i]);
                            _objects.Remove(_objects[i]);
                        }
                    }
                }
            }
            else
            {
                // Since leaf nodes have already been created, attempt to add the object into a leaf node.
                // Otherwise, add the object to this node.
                int index = GetIndex(gameObject.MoveBounds);

                if (index != -1)
                    _nodes[index].Add(gameObject);
                else
                    Insert(gameObject);
            }

            _objectCount++;
        }
        /// <summary>
        /// Decrements the object cound in a given node.
        /// Clears each leaf node within the given node if the object count is 0.
        /// Walks up the tree from the first given node, repeating the process for each parent node.
        /// </summary>
        /// <param name="node">The node to check for its object count.</param>
        protected void CheckObjects(GenQuadtreeNode node)
        {
            if (node != null)
            {
                if (--node._objectCount <= 0)
                    node.ClearLeaves();

                CheckObjects(node._parentNode);
            }
        }