var floys = new Array(100)
var ntypes = 2;
var newnum = 0;
var timerid;
var nf = 0;
var cycleDelay = 10;
var initialEnergy = 20;
var bonusEnergy = 3;
var floysActivated = false;
var gof_floy_version = 1;

var nf_def = new Array(ntypes);	
var revdist_def = new Array(ntypes);
var acc_def =  new Array(ntypes);
var maxspeed_def =  new Array(ntypes);
var acctomid_def =  new Array(ntypes);
var color_def =  new Array(ntypes);
var size_def =  new Array(ntypes);
var shape_def =  new Array(ntypes);
var revapproach_def =  new Array(ntypes);
var revbackoff_def =  new Array(ntypes);
var revchase_def =  new Array(ntypes);
var revavoid_def =  new Array(ntypes);
var revattack_def =  new Array(ntypes);
var revflee_def =  new Array(ntypes);

nf_def[0] = 10;	
revdist_def[0] = 30;
acc_def[0] = 3;
maxspeed_def[0] = 10;
acctomid_def[0] = 1;
color_def[0] = "Yellow";
size_def[0] = 10;
shape_def[0] = "oval";
revapproach_def[0] = 1;
revbackoff_def[0] = 1;
revchase_def[0] = 20;
revavoid_def[0] = 20;
revattack_def[0] = 30;
revflee_def[0] = 30;

nf_def[1] = 1;	
revdist_def[1] = 50;
acc_def[1] = 5;
maxspeed_def[1] = 10;
acctomid_def[1] = 20;
color_def[1] = "Red";
size_def[1] = 10;
shape_def[1] = "oval";
revapproach_def[1] = 1;
revbackoff_def[1] = 1;
revchase_def[1] = 3;
revavoid_def[1] = 3;
revattack_def[1] = 5;
revflee_def[1] = 5;

function floyParams() {

	this.nf = new Array(ntypes);
	this.revdist = new Array(ntypes);
	this.acc = new Array(ntypes);
	this.maxspeed = new Array(ntypes);
	this.acctomid = new Array(ntypes);
	this.color = new Array(ntypes);
	this.size = new Array(ntypes);
	this.shape = new Array(ntypes);
	this.revapproach = new Array(ntypes);
	this.revbackoff = new Array(ntypes);
	this.revchase = new Array(ntypes);
	this.revavoid = new Array(ntypes);
	this.revattack = new Array(ntypes);
	this.revflee = new Array(ntypes);
	
	this.getParams = getParams;
	this.saveParams = saveParams;
	this.defaultParams = defaultParams;
	
	
	function getParams(n) {
	var nf;
	
		per = readCookie("paramper_"+n);
		if ((per == null) || (per == "")) {
			nf = nf_def[n];
			maxspeed = maxspeed_def[n];
			acc = acc_def[n];
			acctomid = acctomid_def[n];
			size = size_def[n];
			color = color_def[n];
			shape = shape_def[n];				
		}
		else {
			nf = parseInt(getCookieValue(per,"nf"));
			maxspeed = parseInt(getCookieValue(per,"maxspeed"));
			acc = parseInt(getCookieValue(per,"acc"));
			acctomid = parseInt(getCookieValue(per,"acctomid"));
			size = parseInt(getCookieValue(per,"size"));
			color = getCookieValue(per,"color");
			shape = getCookieValue(per,"shape");
			
			if ((nf == null) || (nf == 0)) nf = nf_def[n];
			if ((maxspeed == null) ||(maxspeed == 0)) maxspeed = maxspeed_def[n];
			if ((acc == null) || (acc == 0)) acc = acc_def[n];
			if ((acctomid == null) || (acctomid == 0)) acctomid = acctomid_def[n];
			if ((size == null) || (size == 0)) size = size_def[n];
			if ((color == null) || (color == "")) color = color_def[n];
			if ((shape == null) || (shape == "")) shape = shape_def[n];			
		}
		
		rel = readCookie("paramrel_"+n);
		if ((rel == null) || (rel == "")) {
			revdist = revdist_def[n];
			revapproach = revapproach_def[n];
			revbackoff = revbackoff_def[n];
			revchase = revchase_def[n];
			revavoid = revavoid_def[n];
			revattack = revattack_def[n];
			revflee = revflee_def[n];				
		}
		else{
			revdist = parseInt(getCookieValue(rel,"revdist"));
			revapproach = parseInt(getCookieValue(rel,"revapproach"));
			revbackoff = parseInt(getCookieValue(rel,"revbackoff"));
			revchase = parseInt(getCookieValue(rel,"revchase"));
			revavoid = parseInt(getCookieValue(rel,"revavoid"));
			revattack = parseInt(getCookieValue(rel,"revattack"));
			revflee = parseInt(getCookieValue(rel,"revflee"));
			
			if ((revdist == null) || (revdist == 0)) revdist = revdist_def[n];
			if ((revapproach == null) || (revapproach == 0)) revapproach = revapproach_def[n];
			if ((revbackoff == null) || (revbackoff == 0)) revbackoff = revbackoff_def[n];
			if ((revchase == null) || (revchase == 0)) revchase = revchase_def[n];
			if ((revavoid == null) || (revavoid == 0)) revavoid = revavoid_def[n];
			if ((revattack == null) || (revattack == 0)) revattack = revattack_def[n];
			if ((revflee == null) || (revflee == 0)) revflee = revflee_def[n];				
		}

		params.nf[n] = nf;
		params.maxspeed[n] = maxspeed;
		params.acc[n] = acc;
		params.revdist[n] = revdist;
		params.acctomid[n] = acctomid;
		params.size[n] = size;
		params.color[n] = color;
		params.shape[n] = shape;
		params.revapproach[n] = revapproach;
		params.revbackoff[n] = revbackoff;
		params.revchase[n] = revchase;
		params.revavoid[n] = revavoid;
		params.revattack[n] = revattack;
		params.revflee[n] = revflee;	

	}
	
	function saveParams(n) {
	
	}
	
	function defaultParams() {
	
		for (i=0;i<ntypes;i++) {
			nf = nf_def[i];
			maxspeed = maxspeed_def[i];
			acc = acc_def[i];
			acctomid = acctomid_def[i];
			size = size_def[i];
			color = color_def[i];
			shape = shape_def[i];		
			revdist = revdist_def[i];
			revapproach = revapproach_def[i];
			revbackoff = revbackoff_def[i];
			revchase = revchase_def[i];
			revavoid = revavoid_def[i];
			revattack = revattack_def[i];
			revflee = revflee_def[i];
			
			txt = "nf="+nf+"&maxspeed="+maxspeed+"&acc="+acc;
			txt += "&acctomid="+acctomid+"&size="+size+"&color="+color+"&shape="+shape;
			saveCookie("paramper_"+i,txt,365);	
			
			txt = "revdist="+revdist+"&revapproach="+revapproach+"&revbackoff="+revbackoff;
			txt += "&revchase="+revchase+"&revavoid="+revavoid+"&revattack="+revattack+"&revflee=" +revflee;
			saveCookie("paramrel_"+i,txt,365);			
		}
	}					

}


function floy(num,typ) {

	this.num = num; 	
	this.type = typ;

	if (typ == 1) {
		this.id = "stranger-" + num;
		this.group = "Strangers";
	}
	else {				
		this.id = "local-" + num;
		this.group = "Locals";
	}
	this.name = this.id;

	this.nf = params.nf[typ];
	this.acc = params.acc[typ];
	this.acctomid = params.acctomid[typ];
	this.maxspeed = params.maxspeed[typ];
	this.color = params.color[typ];
	this.size = params.size[typ];
	this.shape = params.shape[typ];

	this.revdist = params.revdist[typ];
	this.revapproach = params.revapproach[typ];
	this.revbackoff = params.revbackoff[typ];
	this.revchase = params.revchase[typ];
	this.revavoid = params.revavoid[typ];
	this.revattack = params.revattack[typ];
	this.revflee = params.revflee[typ];

	this.father = Math.round(Math.random()*(this.nf-1));	
	this.mother = Math.round(Math.random()*(this.nf-1));	
	this.x = Math.round(Math.random()*v_mainwidth);	
	this.y = Math.round(Math.random()*v_mainheight);	
	this.vx = Math.round(Math.random()*this.maxspeed*2) - this.maxspeed;
	this.vy = Math.round(Math.random()*this.maxspeed*2) - this.maxspeed;
	this.energy = initialEnergy;
	this.bonusEnergy = bonusEnergy;
	this.numnb = 2;

	this.icon = new Object();
	this.tooltip = new Object();
	this.neighbors = new Array(this.numnb);
	
}

floy.prototype.dist = dist;
floy.prototype.getParents = getParents;
floy.prototype.getNeighbors = getNeighbors;
floy.prototype.processInteraction = processInteraction;
floy.prototype.process = process;
floy.prototype.create = create;
floy.prototype.update = update;
floy.prototype.getTitle = getTitle;
floy.prototype.getData = getData;
floy.prototype.createTooltip = createTooltip;
floy.prototype.getProperties = getProperties;
floy.prototype.blink = blink;
floy.prototype.unblink = unblink;
	
function dist(fl,x2,y2) {
var d,d1,d2;

d1 = (fl.x-x2);
d2 = (fl.y-y2);
d = d1*d1 + d2*d2;
d = parseInt(Math.sqrt(d));
//addToLog(getLogText(this,4,"dist. x= "+fl.x+" x2= "+x2+" y= "+fl.y+" y2= "+y2+" d1= "+d1+" d2= "+d2+" d= "+d) ,20);

return d;
}		

function getNeighbors()	{
var i,j,k;

for (i=0;i<this.numnb;i++) {
	ng = this.neighbors[i];
	for (j=0;j<this.numnb;j++) {
		if (floys[ng].neighbors[j].type != floys[ng].type)
			this.neighbors[i]=floys[ng].neighbors[j];				
		else
		if (dist(this,floys[floys[ng].neighbors[j]].x,floys[floys[ng].neighbors[j]].y) < dist(this,floys[ng].x,floys[ng].y))
			this.neighbors[i]=floys[ng].neighbors[j];
	}
}

for (k=0;k<this.numnb;k++) {
	if (this.neighbors[k] == this.num) {
		nn = parseInt(Math.random()*nf);
		this.neighbors[k] = nn;
	}
}

}


function getParents()	{
var daddy, mammy, grandpa1, grandma1, grandpa2, grandma2;

daddy=floys[this.father];
grandpa1 = daddy.father;
grandma1 = daddy.mother;
if ((dist(this,grandpa1.x,grandpa1.y) < dist(this,this.father.x,this.father.y)) && (grandpa1 != this.num))
	this.father = grandpa1;
if ((dist(this,grandma1.x,grandma1.y) < dist(this,this.father.x,this.father.y)) && (grandma1 != this.num))
	this.father = grandma1;				

mammy=floys[this.mother];
grandpa2 = mammy.father;
grandma2 = mammy.mother;
if ((dist(this,grandpa2.x,grandpa2.y) < dist(this,this.mother.x,this.mother.y)) && (grandma1 != this.num))
	this.mother = grandpa2;
if ((dist(this,grandma2.x,grandma2.y) < dist(this,this.mother.x,this.mother.y)) && (grandma1 != this.num))
	this.mother = grandma2;			

}	


function processInteraction(fl,n) {
var floyref, d, rev;

floyref = floys[n];

d = dist(fl,floyref.x,floyref.y);
//addToLog(getLogText(this,3,"num= "+fl.num+" ref= "+floyref.num+" n= "+n+" fl.x= "+fl.x+" floyref.x= "+floyref.x+" fl.y= "+fl.y+" floyref.y= "+floyref.y+" d= "+d+" d&lt;fl.revdist= "+(d<fl.revdist) ) ,20);
//addToLog(getLogText(this,3,"processInteractions n= "+n+" type= "+fl.type+" other type: "+floyref.type+" d= "+d+" d&lt;fl.revdist= "+(d<fl.revdist) ) ,20);

if (d == 0) {
	rev = 0;
}
else if (d < fl.revdist) {
	//addToLog(getLogText(this,3,"Close d: "+d+" Personal distance: "+fl.revdist) ,20);
	if (floyref.type != fl.type) {
		if (fl.type == 1) {
			fl.energy--;
			rev = -fl.revflee;
			addToLog(getLogText(this,3,"Cycle: "+newnum+": " +fl.name + " got bitten by "+floyref.name+ ", lost 1 unit, Current Energy= "+fl.energy) ,20);
		}
		else {
			fl.energy++;
			rev = fl.revattack;
			addToLog(getLogText(this,3,"Cycle: "+newnum+": " +fl.name + " hit stranger " + floyref.name + ", earned 1 unit, Current Energy= "+fl.energy) ,20);					
		}
	}
	else {
	   rev = -fl.revbackoff;
	   //addToLog(getLogText(this,3,"Same types, Local: Energy= "+fl.energy+" rev= "+rev) ,20);
	}

}
else  {
	//addToLog(getLogText(this,3,"Far d: "+d+" Personal distance: "+fl.revdist) ,20);
	if (fl.type == 1) {
		rev = -fl.revavoid;
		//addToLog(getLogText(this,3,"Stranger rev=revavoid rev= "+rev) ,20);
	}
	else if (floyref.type == 1) {
		rev = fl.revchase;
		//addToLog(getLogText(this,3,"Other is stranger rev=revchase rev= "+rev) ,20);
	}
	else {
		rev = fl.revapproach;
		//addToLog(getLogText(this,3,"Both of us local rev=revapproach rev= "+rev) ,20);
	}

}

//dv = Math.round(fl.acc/10*rev);
dv = fl.acc/10*rev;
//addToLog(getLogText(this,3,"acc= "+fl.acc+" rev= "+rev+" dv= "+dv) ,20);

if (fl.x < floyref.x) {
	fl.vx += dv;
	//addToLog(getLogText(this,3,"fl.x < floyref.x fl.x= "+fl.x+" floyref.x= "+floyref.x+" dv= "+dv+" vx= "+fl.vx) ,20);
}
else {
	fl.vx -= dv;
	//addToLog(getLogText(this,3,"fl.x > floyref.x fl.x= "+fl.x+" floyref.x= "+floyref.x+" dv= "+dv+" vx= "+fl.vx) ,20);				
}

if (fl.y < floyref.y) {
	fl.vy += dv;
	//addToLog(getLogText(this,3,"fl.y < floyref.y fl.y= "+fl.y+" floyref.y= "+floyref.y+" dv= "+dv+" vy= "+fl.vy) ,20);
}
else {
	fl.vy -= dv;
	//addToLog(getLogText(this,3,"fl.y > floyref.y fl.y= "+fl.y+" floyref.y= "+floyref.y+" dv= "+dv+" vy= "+fl.vy) ,20);
}
	
}


function process() {

rev = -1;
//addToLog(getLogText(this,1,"") ,20);
//addToLog(getLogText(this,2,"Start Processing") ,20);

for (i=0;i<this.numnb;i++) {
	processInteraction(this,this.neighbors[i]);
}
//addToLog(getLogText(this,2,"After relational operations") ,20);

if (this.vx > this.maxspeed) this.vx = this.maxspeed;
if (this.vx < -this.maxspeed) this.vx = -this.maxspeed;
if (this.vy > this.maxspeed) this.vy = this.maxspeed;
if (this.vy < -this.maxspeed) this.vy = -this.maxspeed;

if (this.x <= 30) {
	this.x = 30;
	this.vx = Math.abs(this.vx);
	this.vy = parseInt(Math.random()*this.maxspeed);
}
if (this.x > (v_mainwidth-30)) {
	this.x = (v_mainwidth-30);
	this.vx = -Math.abs(this.vx);
	this.vy = parseInt(Math.random()*this.maxspeed);
}
if (this.y <= 30) {
	this.y = 30;
	this.vy = Math.abs(this.vy);
	this.vx = parseInt(Math.random()*this.maxspeed);
}
if (this.y > (v_mainheight-30)) {
	this.y = (v_mainheight-30);
	this.vy = -Math.abs(this.vy);
	this.vx = parseInt(Math.random()*this.maxspeed);
}

//addToLog(getLogText(this,3,"Before sensing target x= "+this.x+" targetx= "+targetX+" y= "+this.y+" targety= "+targetY+" acctomid= "+this.acctomid+" vx= "+this.vx+" vy= "+this.vy) ,20);

amid = this.acctomid/10;
if (this.x < targetX) this.vx += amid;
if (this.x > targetX) this.vx -= amid;
if (this.y < targetY) this.vy += amid;
if (this.y > targetY) this.vy -= amid;

//addToLog(getLogText(this,3,"After sensing target vx= "+this.vx+" vy= "+this.vy) ,20);

this.x += parseInt(this.vx);
this.y += parseInt(this.vy);

d = dist(this,targetX,targetY);
if ((d < this.revdist) && (this.type == 1)) {	
	this.energy += this.bonusEnergy;
	addToLog(getLogText(this,3,"Cycle: "+newnum+": " +this.name +" got bonus energy of "+this.bonusEnergy+". Current energy= "+this.energy),20);
}
		
if (this.energy <= 0)	{
	if (withSound == true) {
		document.all.sound.src = "Joy.au";
		addToLog(getLogText(this,3,"Sigh"),20);
	}
	deleteFloy(this.num);
	addToLog(getLogText(this,3,"Cycle: "+newnum+": " +this.name + " removed (energy gone) withSound= "+withSound),20);
}

//addToLog(getLogText(this,2,"End processing") ,20);

update(this);

}


function create() {

if (this.shape == "rect")
	MyRect = document.createElement("vml:Rect");
else
	MyRect = document.createElement("vml:Oval");

R = objects.appendChild(MyRect);
R.id = this.id;
R.style.width = this.size;
R.style.height = this.size;
R.style.top = this.y;
R.style.left = this.x;
R.style.visibility = "visible";
R.fillColor = this.color;
R.alt = this.name;
if (this.shape == "oval") {
	R.style.width = this.size*3;
	try {
		angle = Math.round(Math.atan(this.vy/this.vx)*180/Math.PI);
	}
	catch(e) {
		angle = 0;
	}
	R.Rotation = angle;	
}
R.title = this.getTitle();
R.style.position = "absolute";
R.style.zIndex = 8;

this.icon = R;

}

function update(fl) {

R = fl.icon;
R.id = fl.id;
R.style.width = fl.size;
R.style.height = fl.size;
R.style.top = fl.y;
R.style.left = fl.x;
R.style.visibility = "visible";
if (R.id == followedId)
	R.fillcolor = "fuchsia";
else
	R.fillColor = fl.color;
R.alt = fl.name;
if (fl.shape == "oval") {
	R.style.width = fl.size*3;
	try {
		angle = Math.round(Math.atan(fl.vy/fl.vx)*180/Math.PI);
	}
	catch(e) {
		angle = 0;
	}
	R.Rotation = angle;	
}
R.title = fl.getTitle();
R.style.position = "absolute";
R.style.zIndex = 8;

}


function getTitle() {
var t;

t = "Id: " + "\t" + this.id + "\n" + "Group: "  + "\t" + this.group + "\n" + "Power: " + "\t" + this.energy +  "\n" + "x: " + "\t" + this.x + "\n" + "y: " + "\t" + this.y +  "\n" + "vx: " + "\t" + format(this.vx,2) + "\n" + "vy: " + "\t" + format(this.vy,2) + "\n" + "Color: " + "\t" + this.color + "\n" + "Name: " + "\t" + R.alt;

return t;
}


function getData() {
var t;

t = "Id: " + this.id + "<br>" + "Group: "  + this.group + "<br>" + "Power: " + this.energy +  "<br>" + "x: " + this.x + "<br>" + "y: " + this.y +  "<br>" + "vx: " + format(this.vx,2) + "<br>" + "vy: " + format(this.vy,2) + "<br>" + "Color: " + this.color + "<br>" + "Name: " + R.alt;

return t;
}	

function createTooltip() {
var R,curitem,id,typ,xx,yy,action,status,evt,color,size,vis,facx,facy;

try {		
	title = this.icon.Alt;
	wid = parseInt(title.length*10)+2;

	var rectObj = document.createElement("vml:rect");

	rectObj.style.position = "absolute";

	x2 = parseInt(this.x) + parseInt(this.size/2);
	y2 = parseInt(this.y) + parseInt(this.size/2)

	rectObj.style.left = x2; 
	rectObj.style.top = y2;
	rectObj.style.width = wid;
	rectObj.style.height = 17;
	rectObj.style.zIndex = 8;
	//rectObj.id = id;

	var fontObj = document.createElement("font");

	fontObj.face = "Arial";
	fontObj.size = "2px";
	fontObj.color = "black";
	fontObj.weight = "normal";
	fontObj.style.zIndex = 9; 
	fontObj.style.position = "relative";
	fontObj.style.left = 1; 
	fontObj.style.top = 1; 
	//fontObj.id = id;

	//title = lfToHtml(title);
	//title = title.trim();

	fontObj.innerHTML = title;

	rectObj.appendChild(fontObj);

	R = objnames.appendChild(rectObj);
	R.style.visibility = namesVisible;
	//R.id = id;

	this.tooltip = R;
}
catch(e) {
	addToLog("createTooltip <b>Error:</b> "+e.description,10);
}
}	


function getProperties() {
var i,txt;

txt = "";
txt +=  "<img src='images/dot.jpg' width='1' height='15' border='0' alt=''>";
txt +=  "<div align='center' class='header3'>";
txt += "Data for" + " " +this.icon.Alt;   //Data for;
txt += "</div>";
txt += "<img src='images/dot.jpg' width='1' height='1' border='0' alt=''>";

txt +=  "<form name='datascrollform' class='smalltext'>";
	
txt += "Number: " + this.num + "<br>";
if (typ == 2) {
	txt += "Type: " + "Stranger" + "<br>";
}
else {
	txt += "Type: " + "Local" + "<br>";
	txt += "Neighbor #1: " + this.neighbors[0] + "<br>";
	txt += "Neighbor #2: " + this.neighbors[1] + "<br>";
}

txt += "X coordinate: " + this.x + "<br>";
txt += "Y coordinate: " + this.y + "<br>";
txt += "X velocity: " + format(this.vx,2) + "<br>";
txt += "Y velocity: " + format(this.vy,2) + "<br>";
txt += "Energy: " + this.energy + "<br>";
txt += "<p>";
txt += "</form>";

txt += "<center>";
txt += "<input type='button' name='close' value='";
txt += "Close"; //strings[7][1];  
if (currentForm == "getFloyList")
	txt += "' onclick='putLastForm()' class='buttonCSS'>";
else
	txt += "' onclick='putSmallMap()' class='buttonCSS'>";

txt += "</center>";

return txt;

}

function getLogText(fl,num,msg) {
var txt;

if (num == 1)
	txt = "Cycle: "+newnum+" Num: "+fl.num+" Name: "+fl.name+ gapHorz(20) + msg;		
	//txt = "Cycle: "+newnum+" Num: "+fl.num+" Name: "+fl.name +" Personal distance: "+ fl.revdist +" Approach: "+fl.revapproach+" Backoff: "+fl.revbackoff+" Chase: "+fl.revchase+" Avoid: "+fl.revavoid+" Attack: "+fl.revattack+" Flee: "+fl.revflee+ gapHorz(20) + msg;
else
if (num == 2)
	txt = gapHorz(num*10) + "x: "+fl.x+" y: "+fl.y+" vx: "+format(fl.vx,2)+" vy: "+format(fl.vy,2)+" Energy: " + fl.energy + gapHorz(20) + msg;	
else
	txt = msg;   //gapHorz(num*10) + msg;		

return txt;

}

function hide() {

this.icon.style.visibility = "hidden";
this.tooltip.style.visibility = "hidden";

}

function show() {

this.icon.style.visibility = "visible";
this.tooltip.style.visibility = "namesVisible";

}

function blink() {

currentColor = this.icon.fillcollor;
this.icon.fillColor = "white";	
this.icon.style.zIndex = 20;	
currentIcon = this.icon;
var interval = setTimeout("unblink()",2000);

}

function unblink() {

currentIcon.style.zIndex = 8;
currentIcon.fillcolor = currentColor;

}	


function createFloys() {
var i;

	newnum = 0;
	nf = 0;

	for (i=0;i<ntypes;i++) {
		params.getParams(i);
	}	

	for (i=0;i<params.nf[0];i++) {
		floys[i] = new floy(i,0);
		floys[i].create();
		floys[i].createTooltip();
		nf++;
	}
	
	ntot = params.nf[0] + params.nf[1];
	for (i=nf;i<ntot;i++) {
		floys[i] = new floy(i,1);
		floys[i].create();
		floys[i].createTooltip();
		nf++;
	}	

	initNeighbors();
	
}


function toggleFloys_new(mode) {

	for (i=0;i<nf;i++) {
		if (mode = "visible")	
			floys[i].show(); 
		else
		if (mode = "hidden")	
			floys[i].hide(); 		
	}
}

function toggleTooltips(mode) {
var flag,i;

	if (mode == "visible")
		namesVisible = "hidden";
	else
	if (mode == "hidden")
		namesVisible = "visible";
	
	if (namesVisible == "visible") {
		namesVisible = "hidden";
		document.all.nalight.src = ballgray[5].src;  //"images/ballgray1.gif";
	}
	else { 
		namesVisible = "visible";
		//document.all.nalight.src = ballred[5].src;  //"images/ballred1.gif";
		resetTooltips();
	}

	try {
		for (i=0;i<nf;i++) {
			floys[i].tooltip.style.visibility = namesVisible; 
		}
	} catch (e) {
		addToLog("toggleTooltips <b>Error:</b> "+e.description,10);
	}	
	
	updateLightButtons();
	buttonToggled = true;

}

function initNeighbors() {
var i,j,k,n;

	for (k=0;k<nf;k++) {
		ng = floys[k];
		for (j=0;j<ng.numnb;j++) {
			n = parseInt(Math.random()*nf);
			ng.neighbors[j] = n;
		}
	}
	
}
	

function playFloys(flag) {
var i;

	if (!floysActivated) resetFloys();
	
	try {
		toggleTooltips("hidden");
		
		for (i=0;i<nf;i++) {
			if ((newnum % 10) == 0) initNeighbors();
			currentId = floys[i].id;
			floys[i].getNeighbors(); 
			floys[i].process();
		}
	
		newnum++;
		//self.status = "cycle #"+newnum; 
		if (flag == 1) {
			timerId = setTimeout("playFloys(1)",cycleDelay);
		}
	}
	catch(e) {
	}		
	
}

function startFloys(flag) {

	playFloys(flag);
	
}


function stopFloys() {

	try {
		clearTimeout(timerId);
	}
	catch(e) {
	}

}

function addToLogFloy(fl,msg) {
var txt;

	txt = msg;
	txt += " num= "+fl.num+" x= "+fl.x+" y= "+fl.y+" vx= "+fl.vx+" vy= "+fl.vy;
	addToLog(txt,5);
	
}

function resetFloys() {

	try {
		deleteFloys();
		createFloys();
		floysActivated = true;
	}
	catch(e) {
	}	

}


function resetTooltips() {

	try {
		deleteTooltips();
		createTooltips();
	}
	catch(e) {
	}	

}

function deleteFloy(n) {
var i, length, typ;

	try {
		typ = floys[n].type;
		objects.removeChild(floys[n].icon);
		objnames.removeChild(floys[n].tooltip);
		delete floys[n];
		
		length = floys.length;
		if (n >= length || n<0)
		  return;
			
		for (i=n;i<length-1;i++)
		  floys[i] = floys[i+1];
		floys.length--;
		nf--;
		params.nf[typ]--;
		initNeighbors();
	}
	catch(e) {
	}

}

function deleteFloys() {
var i, R, num;
	
	myobjs = document.getElementById("objects").childNodes;
	nobj = myobjs.length;
	num = nobj;

	for (i=0;i<num;i++) {
		myobjs = document.getElementById("objects").childNodes;
		nobj = myobjs.length;	
		R = myobjs.item(0);
		objects.removeChild(R);
		nf--;
	}
	
	myobjsnames = document.getElementById("objnames").childNodes;
	nobjnames = myobjsnames.length;
	num = nobjnames;

	for (i=0;i<num;i++) {
		myobjsnames = document.getElementById("objnames").childNodes;
		nobjnames = myobjsnames.length;	
		R = myobjsnames.item(0);
		objnames.removeChild(R);
	}	
	
}


function deleteTooltips() {
var i, R, num;

	myobjsnames = document.getElementById("objnames").childNodes;
	nobjnames = myobjsnames.length;
	num = nobjnames;

	for (i=0;i<num;i++) {
		myobjsnames = document.getElementById("objnames").childNodes;
		nobjnames = myobjsnames.length;	
		R = myobjsnames.item(0);
		objnames.removeChild(R);
	}	
	
}

function createTooltips() {
var i;
		
	for (i=0;i<nf;i++) {
		floys[i].createTooltip();
	}
	
}

function removeFloys(flag) {
var i, num;

	myobjs = document.getElementById("objects").childNodes;
	nobj = myobjs.length;
	num = nobj;
	
	for (i=num-1;i>=0;i--) {
		myobjs = document.getElementById("objects").childNodes;
		nobj = myobjs.length;
		num = nobj;	
		id = myobjs.item(num-1).id;
		n = getObjectInumber(id);
		if (flag == 2) {
			deleteFloy(n);
		}
		else
		if ((flag == 0) && (floys[i].type == 0)) {
			deleteFloy(floys[i].num);
		}
		else
		if ((flag == 1) && (floys[i].type == 1)) {
			deleteFloy(floys[i].num);	
		}
	}
	
	initNeighbors();

}

function insertFloy(ntype) {
var i, nfcur;

	nfcur = nf;
	params.nf[ntype]++;
	nf++;
	
	for (i=nfcur;i<nf;i++) {
		floys[i] = new floy(i,ntype);
		floys[i].create();
		floys[i].createTooltip();
	}	

	initNeighbors();
}

function removeLastStranger() {

	if (floys[nf-1].type == 1)
		deleteFloy(nf-1);
		
}

function findFloy(name) {
var i, id;

	id = "";
	for (i=0;i<nf;i++) {
		if (floys[i].name == name) {
			currentId = floys[i].id;
			currentNum = i;
			break;
		}
	}
		
	getFloyControl(name);

}



	






