// constants
var MAX_CHILD = 9;
var classNames; // array of class names
var mouseState; // which classes have mouseover fns
//enum { CURRENT, PARENT, GRANDPARENT, CHILD, GRANDCHILD, SIBLING, AUNT, GREATAUNT, DEFAULT };
var CURRENT		= 0;
var PARENT		= 1;
var GRANDPARENT = 2;
var CHILD		= 3;
var GRANDCHILD	= 4;
var SIBLING		= 5;
var AUNT		= 6;
var GREATAUNT	= 7;
var DEFAULT		= 8 ;

// globals
var curLoOb; // the layout object
var	curImpl; // the implementation object
var curStateList;	
var curTarget;

// this chunk depends on the id system
function getParent(ob)
{
	return curImpl.getEltById(ob.id.substr(0, ob.id.length-1));
}

function isValid(ob)
{
	var fRet;
	try
	{
		fRet = ("n1.1" == ob.id.substr(0, 4) );
	}
	catch (error)
	{
		fRet = false; // not necessary, but why risk the maintainance problems
	}
	return fRet;
}
function makeNewChangeList(csl, nsl, newTargetOb)
{
	var newTargetID = newTargetOb.id;
	var changeList = new Object();
	// anything in the current state list which 
	// is NOT in the new state list will be set to default,
	for (id in csl)
	{
		// if the elt is a later generation than the new target's greatgrandparent
		if (id.length > newTargetID.length - 3)
		{
			changeList[id] = DEFAULT;
		}
		else
		{
			changeList[id] = csl[id];
		}
	}
	for (id in nsl)
	{
		changeList[id] = nsl[id];
	}
	return changeList;	
}

function doChanges(cl)
{
	for (id in cl)
	{
		setAppearance(curImpl.getEltById(id), cl[id]);
	}
}
function setAppearance(obj, level)
{
	var lo = curLoOb.getPosition(obj.id);
	curImpl.setPos(obj, lo, level);
	curImpl.setMouse(obj, mouseState[level]);
}
function addElt(sl, elt, level)
{
	sl[elt.id] = level;
}

function addChildren(sl, elt, level)
{
	var numChildren = getNumChildren(elt);
	var n;
	for (n = 1; n <= numChildren; n++)
	{
		sl[elt.id + n] = level;
	}
	
	

}
function getNumChildren(ob)
{
	var baseNodeName = ob.id;
	var nChildren = -1;
	try 
	{
		nChildren = ob.numChildren;
	}
	catch(error)
	{
		nChildren = -1;
	}
	if (typeof(nChildren) == 'undefined')
	{
		nChildren = 0;
		for (n = 1; true; n++)
		{
			try
			{
				var obj = curImpl.getEltById(baseNodeName + n.toString());
				if ("n1." == obj.id.substr(0, 3)   )
				{
					nChildren++;
				}			
			}
			catch(error)
			{
				break;		
			}		
		}
		ob.numChildren = nChildren;
	}
	return nChildren;
}
// id system independent

// tells node that it has been mouse overed.
function doMover(ob)
{
	var newStateList = makeNewStateList(ob);
	var cl = makeNewChangeList(curStateList, newStateList, ob);
	doChanges(cl);
	curStateList = newStateList;
	curTarget = ob;
}

function makeNewStateList(ob)
{	
	var newStateList = new Object();
	var n;
	var parent = getParent(ob);
	if (isValid(parent))
	{
		var grandParent = getParent(parent);
		if (isValid(grandParent))
		{
			var greatGrandParent = getParent(grandParent);
			if  (isValid(greatGrandParent ))
			{
					// greatAunts
					addChildren(newStateList, greatGrandParent, GREATAUNT);
			}
			// grandparent - do *after* greataunts
			addElt(newStateList, grandParent, GRANDPARENT);
			// aunts
			addChildren(newStateList, grandParent, AUNT);
		}
		// parent - do *after* aunts
		addElt(newStateList, parent, PARENT);
		// siblings
		addChildren(newStateList, parent, SIBLING);
	}
	// self - do *after* sibs
	addElt(newStateList, ob, CURRENT);
	// children
	addChildren(newStateList,ob, CHILD);
	return newStateList;
}

function init(loOb, impl)
{
	curLoOb = loOb;
	curImpl = impl;
	curTarget = curImpl.getEltById("n1.1");
	classNames = new Array ("CURRENT", "PARENT","GRANDPARENT","CHILD","GRANDCHILD","SIBLING","AUNT","GREATAUNT","DEFAULT");
	mouseState = new Array( true, true, true, true, false, true, true, true, false);
	curStateList = new Object();
	doMover(curTarget);
}

function logErr(error)
{
	alert(error);
}

