package ae {
import flash.display.Sprite;
import flash.events.MouseEvent;
// quad tree used to delegate mouse events
class CircleNode {
//each Node has an associated Circle sprite
public var parentCircle:Circle = null;
//the tree has 2-way links
protected var parent:CircleNode = null;
//the children
protected var child1:CircleNode = null;
protected var child2:CircleNode = null;
protected var child3:CircleNode = null;
protected var child4:CircleNode = null;
//boundaries used to select children when traversing
public var xThresh:Number;
public var yThresh:Number;
//set up the connections to a Circle
public function CircleNode(pc:Circle)
{
parentCircle = pc;
pc.node = this;
}
// self explanatory
public function addChildren(c1:CircleNode, c2:CircleNode, c3:CircleNode, c4:CircleNode) : void
{
child1 = c1; child2 = c2; child3 = c3; child4 = c4;
c1.parent = this;
c2.parent = this;
c3.parent = this;
c4.parent = this;
}
// recurse through the tree to find the handler for the mouse event
public function findTarget(e:MouseEvent) : void
{
if(child1 == null
&& child2 == null
&& child3 == null
&& child4 == null)
{
//we are at a leaf node, split
if(parentCircle != null)
parentCircle.handleMouseOver(e);
return;
}
//check the stage coords of the mouse event and compare with the
//thresholds to determine which child to recurse down into
//we must check it that child was null, it's possible that part of the
//tree is already at the max depth
if (e.stageX < xThresh && e.stageY < yThresh && child1 != null)
child1.findTarget(e);
else if(e.stageX > xThresh && e.stageY < yThresh && child2 != null)
child2.findTarget(e);
else if(e.stageX < xThresh && e.stageY > yThresh && child3 != null)
child3.findTarget(e);
else if(e.stageX > xThresh && e.stageY > yThresh && child4 != null)
child4.findTarget(e);
}
//null out references to a given child
public function killChild(c:CircleNode) : void
{
if(c == child1)
child1 = null;
if(c == child2)
child2 = null;
if(c == child3)
child3 = null;
if(c == child4)
child4 = null;
if(isEmpty())
//this node is useless, delete it from the parent
deleteMe();
}
public function isEmpty() : Boolean
{
return child1 == null
&& child2 == null
&& child3 == null
&& child4 == null;
}
// "delete" in this case just means to remove all references to the node so it can be GC'ed
public function deleteMe() : void
{
parentCircle = null;
child1 = null;
child2 = null;
child3 = null;
child4 = null;
if(parent != null) // this could be the root node
{
parent.killChild(this);
parent = null;
}
}
}
}