// Driving functions for Canal Game.
//  nib - 2004-04-11

var links = new Array();
var dests = new Array();
var totm, totlocks, mingauge;
 
// Reset totalisers.
function startagain()
{
	totm = 0;
	totlocks = 0;
	mingauge = 10;
}

// Start from a given OS. Used to make start buttons independent of database
//  numbering.
function startOS(ref)
{
	var xy = new node();
	xy.txt = ref;
	OS2xy(xy);
	startfrom(findnearest(xy));
}

// Return the node nearest to given node. No proper error checking.
function findnearest(n)
{
	var i, d2, p, x, min;

	min = 1e20;
	p = 0;
	for (i=0; i<nodelist.length; i++)
	{
		x = nodelist[i];
		d2 = (x.east-n.east)*(x.east-n.east) +
			(x.north-n.north)*(x.north-n.north);
		if (d2 < min)
		{
			min = d2;
			p = i;
		}
	}
	return p;
}

// Called by various starting buttons. Initialises totals and builds new
//  chooser. Parameter is a node number.
function startfrom(start)
{
	startagain();
	buildchooser(start);
}

// Called by clicking the choice buttons. Updates the totals and builds
//  new chooser. Takes an index into possible destinations array.
function chosen(n)
{
	if (dests[n] >= 0)
	{
		totm += seglist[links[n]].len;
		totlocks += Math.abs(seglist[links[n]].locks);
		var x = Math.abs(seglist[links[n]].gauge);
		if (x < mingauge) { mingauge = x; }
		buildchooser(dests[n]);
	}
	else
	{
		alert("You can't choose that one!");
	}
}

// Take a node object and put its 2-letter + 6-fig OS in txt field.
function xy2OS(n)
{
	var tmp, buf, letters="VWXYZQRSTULMNOPFGHJKABCDE";
	var E_maj, E_min, N_maj, N_min, E_ref, N_ref;

	n.txt = "";
	var NN = n.north;
	var EE = n.east;
	if (NN < 0 || NN > 2500000)
	{
		alert("illegal N in conv");
		return;
	}
	if (EE < 0 || EE > 2500000)
	{
		alert("illegal E in conv");
		return;
	}
	E_ref = Math. floor(EE/100 + 0.5);
	N_ref = Math. floor(NN/100 + 0.5);
	E_maj = Math.floor(E_ref / 5000);
	N_maj = Math.floor(N_ref / 5000);
	E_ref %= 5000;
	N_ref %= 5000;
	E_min = Math.floor(E_ref / 1000);
	N_min = Math.floor(N_ref / 1000);
	E_ref %= 1000;
	N_ref %= 1000;
	if (E_maj < 0 || E_maj > 4 || N_maj < 0 || N_maj > 4)
	{
		alert("ref out of range in conv");
		return 0;
	}
	n.txt += letters.charAt(E_maj + 5 * N_maj);
	n.txt += letters.charAt(E_min + 5 * N_min);
	tmp = "000" + E_ref.toString();
	n.txt += tmp.substr(tmp.length-3, 3);
	tmp = "000" + N_ref.toString();
	n.txt += tmp.substr(tmp.length-3, 3);
}

// Take a node object, convert OS in txt field, fill in easting and northing.
function OS2xy(n)
{
	var tmp, letters="VWXYZQRSTULMNOPFGHJKABCDE", nums="0123456789";
	var i, E_maj, E_min, N_maj, N_min, maj, min;

	n.east = 0;
	n.north = 0;
	tmp = n.txt.toUpperCase();
	if (tmp.length != 8)
	{
		alert("wrong string len in conv");
		return;
	}
	maj = letters.indexOf(tmp.charAt(0));
	if (maj == -1)
	{
		alert("wrong 1st letter in conv");
		return;
	}
	E_maj = maj % 5;
	N_maj = Math.floor(maj / 5);
	min = letters.indexOf(tmp.charAt(1));
	if (min == -1)
	{
		alert("wrong 2nd letter in conv");
		return;
	}
	E_min = min % 5;
	N_min = Math.floor(min / 5);
	for (i=0; i<6; i++)
	{
		if (nums.indexOf(tmp.charAt(2+i)) == -1)
		{
			alert("non-numeric tail in conv");
			return;
		}
	}
	n.east = 500000 * E_maj + 100000 * E_min + tmp.substr(2, 3) * 100;
	n.north = 500000 * N_maj + 100000 * N_min + tmp.substr(5, 3) * 100;
}

// Find out where you can go from here and put data into choice form.
//  Parameter is a node number.
function buildchooser(here)
{
	buildlinks(here, links);
	buildform(here, links);
	document.totals.km.value = totm / 1000;
	document.totals.locks.value = totlocks;
	document.totals.gauge.value = mingauge;
}

// Find out where you can go from here.
function buildlinks(here, links)
{
	var i, n=0;

	links.length = 0;
	for (i=0; i<seglist.length; i++)
	{
		if (seglist[i].from == here || seglist[i].to == here)
		{
			if (n >= maxways)
			{
				alert("Didn't allow for that many ways!");
				break;
			}
			links[n++] = i;
		}
	}
}

// Fill in form data for where you can get to from here.
function buildform(here, links)
{
	var i, disp, butt, dir, dest, seg;
	var txt;
	var xy = new node();

	txt = nodelist[here].txt;
	txt += ' (';
	xy.east = nodelist[here].east;
	xy.north = nodelist[here].north;
	xy2OS(xy);
	txt += xy.txt;
	txt += ')';
	document.chooser.here.value = txt;

	// the buttons that go somewhere
	for (i=0; i<links.length; i++)
	{
		seg = links[i];
		if (seglist[seg].from == here)
		{
			dest = seglist[seg].to;
			dir = 1;
		}
		else
		{
			dest = seglist[seg].from;
			dir = -1;
		}
		disp = "disp" + i;
		butt = "butt" + i;
		txt = nodelist[dest].txt;
		txt += '\nvia ';
		txt += seglist[seg].txt;
		if (dir == 1)
		{
			txt += ' ->\n';
		}
		else
		{
			txt += ' <-\n';
		}
		txt += seglist[seg].len / 1000;
		txt += 'km and ';
		txt += Math.abs(seglist[seg].locks);
		if (seglist[seg].locks * dir > 0)
		{
			txt += ' locks (up)';
		}
		else if (seglist[seg].locks * dir < 0)
		{
			txt += ' locks (down)';
		}
		else
		{
			txt += ' locks';
		}
		document.chooser[disp].value = txt;
		document.chooser[butt].value ="Go" 
		dests[i] = dest;
	}
	// and the spare buttons
	for (;i<maxways; i++)
	{
		disp = "disp" + i;
		butt = "butt" + i;
		document.chooser[disp].value = "";
		document.chooser[butt].value ="[]" 
		dests[i] = -1;
	}
}
