function getnumber (type, stepnum){
 return steps[stepnum].val[type];
}

function checkall(stepnum){
 if (steps[stepnum].val[dur] < 0.5){
  steps[stepnum].dig[dur][ones] = 0;
  steps[stepnum].dig[dur][tenths] = 5;
  steps[stepnum].dig[dur][hundredths] = 0;
  steps[stepnum].val[dur] = 0.5;
 }
 if (steps[stepnum].val[thrust] < -3){
  steps[stepnum].sign[thrust] = neg;
  steps[stepnum].dig[thrust][ones] = 3;
  steps[stepnum].dig[thrust][tenths] = 0;
  steps[stepnum].dig[thrust][hundredths] = 0;
  steps[stepnum].val[thrust] = -3;
 }
}

function setalldigs(stepnum, name){
 var n;
 for (n=ones; n<=hundredths; n++)
  setspantext ('dig' + name + '-' + n + '-' + stepnum, steps[stepnum].dig[name][n]);
 if (steps[stepnum].sign[name] != posonly){
  if (steps[stepnum].sign[name] == pos)
   setspantext ('sign' + name + '-' + stepnum, '+');
  else
   setspancontent ('sign' + name + '-' + stepnum, '&#150;');
 }
}

function updateval(name, stepnum){
 steps[stepnum].val[name] = convertsignednumarray(new Array(steps[stepnum].sign[name], steps[stepnum].dig[name][ones], steps[stepnum].dig[name][tenths], steps[stepnum].dig[name][hundredths]));
}

function increase (name, place, stepnum){
 if (!mousedown) return;
 if (steps[stepnum].dig[name][place] < 9){
  steps[stepnum].dig[name][place] = (steps[stepnum].dig[name][place]+1);
  updateval(name, stepnum);
  checkall(stepnum);
  setalldigs(stepnum, name);
  setspantext ('val' + name + '-' + stepnum, rnd(steps[stepnum].val[name]));
  updatestats();
  setTimeout ('increase('+ name +', '+place+', '+stepnum+');', 200);
 }
}

function decrease (name, place, stepnum){
 if (!mousedown) return;
 if (steps[stepnum].dig[name][place] > 0){
  steps[stepnum].dig[name][place] = (steps[stepnum].dig[name][place]-1);
  updateval(name, stepnum);
  checkall(stepnum);
  setalldigs(stepnum, name);
  setspantext ('val' + name + '-' + stepnum, rnd(steps[stepnum].val[name]));
  updatestats();
  setTimeout ('decrease('+ name +', '+place+', '+stepnum+');', 200);
 }
}

function startincrease (name, place, stepnum){
 stop();
 mousedown = true;
 increase(name, place, stepnum);
}

function startdecrease (name, place, stepnum){
 stop();
 mousedown = true;
 decrease(name, place, stepnum);
}

function setdig (name, place, stepnum, digit){
 stop();
 window.focus();
 steps[stepnum].dig[name][place] = digit;
 updateval(name, stepnum);
 checkall(stepnum);
 setalldigs(stepnum, name);
 setspantext ('val' + name + '-' + stepnum, rnd(steps[stepnum].val[name]));
 updatestats();
}

function createdigitcontrol (name, place, stepnum){
 var n, output="";
 output += '<table bgcolor="#668899"><tr><td>';
 output += '<span class="blackbighead" id="dig'+ name +'-'+ place +'-'+stepnum+'">'+ steps[stepnum].dig[name][place] +'</span>';
 if (place == ones)
  output += '<span class="blackbighead">.</span>';
 output += '<br><span class="blackhead"><a href="javascript://" onMouseDown="startincrease('+name+', '+place+', '+stepnum+');">+</a> <a href="javascript://" onMouseDown="javascript:startdecrease('+name+', '+place+', '+stepnum+');">&#150;</a><br>';
 output += '<a href="javascript:setdig('+name+', '+place+', '+stepnum+', 9);">9</a> ';
 output += '<a href="javascript:setdig('+name+', '+place+', '+stepnum+', 0);">0</a><br>';
 output += '</span></td></tr></table>';
 return output;
}

function createfivezerocontrol (name, place, stepnum){
 var n, output="";
 output += '<table bgcolor="#668899"><tr><td>';
 output += '<span class="blackbighead" id="dig'+ name +'-'+ place +'-'+stepnum+'">'+ steps[stepnum].dig[name][place] +'</span>';
 if (place == ones)
  output += '<span class="blackbighead">.</span>';
 output += '<br><span class="blackhead"><a href="javascript:setdig('+name+', '+place+', '+stepnum+', 5);">5</a> ';
 output += '<a href="javascript:setdig('+name+', '+place+', '+stepnum+', 0);">0</a><br>&nbsp;';
 output += '</span></td></tr></table>';
 return output;
}

function makenegative (name, stepnum){
 stop();
 steps[stepnum].sign[name] = neg;
 updateval(name, stepnum);
 checkall(stepnum);
 setalldigs(stepnum, name);
 setspantext ('val' + name + '-' + stepnum, rnd(steps[stepnum].val[name]));
 updatestats();
}

function makepositive (name, stepnum){
 stop();
 steps[stepnum].sign[name] = pos;
 updateval(name, stepnum);
 checkall(stepnum);
 setalldigs(stepnum, name);
 setspantext ('val' + name + '-' + stepnum, rnd(steps[stepnum].val[name]));
 updatestats();
}

function createsigncontrol (name, stepnum){
 var output="";
 output += '<table bgcolor="#668899"><tr><td>';
 output += '<span class="blackbighead" id="sign'+ name +'-'+ stepnum +'">';
 if (steps[stepnum].sign[name] == pos)
  output += '+';
 else
  output += '&#150;';
 output += '</span><br><span class="blackhead"><a href="javascript:makepositive('+name+', '+stepnum+');";>POS</a><br>';
 output += '<a href="javascript:makenegative('+name+', '+stepnum+');";>NEG</a></span>';

 output += '</td></tr></table>';
 return output;
}

function getarray(stepnum, name){
 return new Array(steps[stepnum].sign[name], steps[stepnum].dig[name][ones], steps[stepnum].dig[name][tenths], steps[stepnum].dig[name][hundredths]);
}

function addafter(num){
 stop();
 var tempsteps = new Array(steps.length+1);
 var n;
 for (n=0; n<=num; n++)
  tempsteps[n] = new step(getarray(n,thrust), getarray(n,rotate), getarray(n,dur));
 tempsteps[num+1] = new step(defaultthrust, defaultrotate, defaultdur);
 for (n=num+2; n<=steps.length; n++)
  tempsteps[n] = new step(getarray(n-1,thrust), getarray(n-1,rotate), getarray(n-1,dur));
 steps = tempsteps;
 writestepsinterface();
}

function delstep(num){
 stop();
 var tempsteps = new Array(steps.length-1);
 var outn=0, n;
 for (n=0; n<steps.length; n++){
  if (n != num){
   tempsteps[outn] = steps[n];
   outn++;
  }
 }
 steps = tempsteps;
 writestepsinterface();
}

function introduce(inob){
 stop();
 var oldlen = obs.length;
 var spanname;
 obs[obs.length]= new cloneObject(inob);
 obs.length = oldlen+1;
 addobstacles();
 spanname = 'obs-'+(obs.length-1);
 document.all[spanname].style.border = 'solid red 1px';
 setpos(spanname, obs[obs.length-1].x-(obs[obs.length-1].width/2)-1, obs[obs.length-1].y-(obs[obs.length-1].height/2)-1);
 setTimeout ("document.all['obs-"+(obs.length-1)+"'].style.border = '0px'; setpos('"+ spanname +"',"+ (obs[obs.length-1].x-(obs[obs.length-1].width/2)) +","+ (obs[obs.length-1].y-(obs[obs.length-1].height/2)) +");", 200);
}

function startdrift(dir,amt){
 stop();
 mousedown = true;
 drift(dir,amt);
}

function drift(dir,amt){
 if (!mousedown) return;
 eval("state.d" +dir+ "+=" +amt+ ";");
 eval("if (state.d" +dir+ " < -10) state.d" +dir+ "=-10;");
 eval("if (state.d" +dir+ " > 10) state.d" +dir+ "=10;");
 reset();
 updatestats();
 setTimeout ('drift("'+ dir +'", '+amt+');', 200);
}

function startturn (degrees){
 stop();
 mousedown = true;
 turnstate(degrees);
}

function turnstate(degrees){
 if (!mousedown) return;
 state.ang = state.ang + ((360+degrees)*Math.PI/180);
 state.ang %= (Math.PI*2);
 reset();
 updatestats();
 setTimeout ('turnstate('+ degrees +');', 50);
}

function writestepsinterface(){
 var output="", n;
 output += '<table border=0 cellspacing=1 cellpadding=1 bgcolor="black">';
 for (n=0; n<steps.length; n++){
  output += '<tr><td valign=top bgcolor="#77CCAA">';
  output += '<table border=0><tr><td bgcolor="black"><span class="whitehead">step</span></td></tr>';
  output += '<tr><td><span class="blackbighead" id="step'+n+'">&nbsp;'+(n+1)+'&nbsp;</span></td></tr></table></td><td valign=top bgcolor="#77AACC">';
  output += '<table border=0><tr><td colspan=4 bgcolor="black"><span class="whitehead">forward thrust: </span><span class="whitehead" id="val'+thrust+'-'+n+'">'+ rnd(steps[n].val[thrust]) +'</span></td></tr>';
  output += '<tr><td valign=top>' + createsigncontrol (thrust, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (thrust, ones, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (thrust, tenths, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (thrust, hundredths, n) + '</td></tr></table>';
  output += '</td><td valign=top bgcolor="#77CCAA">';
  output += '<table border=0><tr><td colspan=4 bgcolor="black"><span class="whitehead">rotation speed: </span><span class="whitehead" id="val'+rotate+'-'+n+'">'+ rnd(steps[n].val[rotate]) +'</span></td></tr>';
  output += '<tr><td valign=top>' + createsigncontrol (rotate, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (rotate, ones, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (rotate, tenths, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (rotate, hundredths, n) + '</td></tr></table>';
  output += '</td><td valign=top bgcolor="#77AACC">';
  output += '<table border=0><tr><td colspan=3 bgcolor="black"><span class="whitehead">duration: </span><span class="whitehead" id="val'+dur+'-'+n+'">'+ rnd(steps[n].val[dur]) +'</span></td></tr>';
  output += '<tr><td valign=top>' + createdigitcontrol (dur, ones, n) + '</td>';
  output += '<td valign=top>' + createdigitcontrol (dur, tenths, n) + '</td>';
  output += '<td valign=top>' + createfivezerocontrol (dur, hundredths, n) + '</td></tr></table>';
  output += '</td><td valign=top bgcolor="#77CCAA"><table border=0>';
  if (steps.length > 1)
   output += '<tr><td colspan=4 bgcolor="black"><span class="whitehead"><a href="javascript:delstep('+n+');">delete step</a></td></tr>';
  output += '<tr><td colspan=4 bgcolor="black"><span class="whitehead"><a href="javascript:addafter('+n+');">add step here</a></td></tr>';
  output += '</table>';
  output += '</td></tr>';
 }
 output += '<tr><td bgcolor="white"></td><td bgcolor="white"><span class="blackhead">max negative<br>thrust: -3</span></td><td bgcolor="white"></td>';
 output += '<td bgcolor="white"><span class="blackhead">min duration:<br>0.5</span></td><td bgcolor="white"></td></tr><tr><td colspan=5 bgcolor="#99BBCC" align=right>';
 output += '<table border=0 cellspacing=5 cellpadding=3><tr><td valign=top bgcolor="#88AABB" width="100%"><span class="blackhead"><b>initial ship state:</b><br><br><img width=200 height=1 src="blank.gif"><br>x-axis drift speed: </span><span class="blackhead" id="dx"></span><br><span class="blackhead">y-axis drift speed: </span><span class="blackhead" id="dy"></span><br><span class="blackhead">ship angle: </span><span class="blackhead" id="ang"></span><span class="blackhead">&deg;</span></td><td valign=top bgcolor="#88AABB" width="100%">';
 output += '<span class="blackhead"><b>statistics:</b><br><br><img width=200 height=1 src="blank.gif"><br>total fuel used: </span><span class="blackhead" id="fuelused"></span><br><span class="blackhead">total sequence time: </span><span class="blackhead" id="totaltime"></span><br><span class="blackhead">total positive mass: </span><span class="blackhead" id="totalposmass"></span><br><span class="blackhead">total negative mass: </span><span class="blackhead" id="totalnegmass"></span></td></tr></table></td></tr></table>';
 setspancontent ('interface', output);
 updatestats();
 updatemass();
}

function updatemass(){
 var n;
 var posmass=0;
 var negmass=0;
 for (n=0; n<obs.length; n++){
  if (obs[n].mass < 0)
   negmass += obs[n].mass;
  else
   posmass += obs[n].mass;
 }
 setspantext ('totalposmass', rnd(posmass));
 setspantext ('totalnegmass', rnd(negmass));
}

function updatestats(){
 var n;
 var fuel=0;
 var time=0;
 for (n=0; n<steps.length; n++){
  updateval (thrust,n); 
  updateval (rotate,n);
  updateval (dur,n);
  fuel += Math.abs(steps[n].val[thrust]) * steps[n].val[dur];
  time += steps[n].val[dur];
 }
 setspantext ('fuelused', rnd(fuel));
 setspantext ('totaltime', rnd(time));
 setspantext ('dx', rnd(state.dx));
 setspantext ('dy', rnd(state.dy));
 if (!locked){
  setspantext ('toolboxdx', rnd(state.dx));
  setspantext ('toolboxdy', rnd(state.dy));
 }
 setspantext ('ang', rnd(state.ang*(180/Math.PI)));
}

function updateradar(){
 var absl, absr, totalw;
 var abst, absb, totalh;
 var avgx, avgy;
 var factor;

 absl = (x<0 ? x : 0);
 absr = (x>arenaw ? x : arenaw);
 abst = (y<0 ? y : 0);
 absb = (y>arenah ? y : arenah); 
 totalw = absr-absl;
 totalh = absb-abst;

 var scaledw, scaledh;

 if (totalw > totalh){
  scaledw = (arenaw/totalw)*radarw;
  scaledh = scaledw*(arenah/arenaw);
  factor = radarsize/totalw;
 } else {
  scaledh = (arenah/totalh)*radarh;
  scaledw = scaledh*(arenaw/arenah);
  factor = radarsize/totalh;
 }
 document.all['radaruni'].style.width = Math.round(scaledw)+"px";
 document.all['radaruni'].style.height = Math.round(scaledh)+"px";

 var top = gettop('radar');
 var left = getleft('radar');
 var right = getleft('radar')+radarsize-Math.round(scaledw);
 var bottom = gettop('radar')+radarsize-Math.round(scaledh);
 var unix, uniy;

 var centerradar = Math.round(radarsize/2);
 var centerx, centery;

 centery = Math.round((arenah+y)/3);
 uniy = (centerradar)-(factor*centery);
 if (uniy+scaledh > radarsize)
  uniy = radarsize-scaledh;
 if (uniy < 0)
  uniy = 0;
 
 centerx = Math.round((arenaw+x)/3);
 unix = (centerradar)-(factor*centerx);
 if (unix+scaledw > radarsize)
  unix = radarsize-scaledw;
 if (unix < 0)
  unix = 0;

 if (y > (arenah/2 + arenaw/2) && Math.abs(y) > Math.abs(x))
  uniy = 0;
 if (y < 0 && Math.abs(y)+arenah > Math.abs(x)+arenaw)
  uniy = radarsize-scaledh;

 if (x > arenaw && Math.abs(x) > Math.abs(y))
  unix = 0;
 if (x < 0 && Math.abs(x)+arenaw > Math.abs(y)+arenah)
  unix = radarsize-scaledw;

 var absunix = unix+getleft('radar');
 var absuniy = uniy+gettop('radar');

 setposabs('radaruni', absunix, absuniy);

 var n;
 for (n=0; n<obs.length; n++)
  setposabs('radar-'+n, absunix+(factor*obs[n].x), absuniy+(factor*obs[n].y));
 setposabs('radarship', absunix+(factor*x)-1, absuniy+(factor*y)-1);
}


function makeradar(){
 var output;
 output = '<img id="radar" style="background-color:#999999;" width='+(radarsize)+' height='+(radarsize)+' src="blank.gif">';
 document.writeln (output);
}

function makeradaruni(){
 var output;
 output = '<img id="radaruni" style="position:absolute; background-color:#BBBBBB; width:1px; height:1px;" src="blank.gif">';
 document.writeln (output);
 updateradar();
}

function unlock(){
 var output = "";
 output += '<table bgcolor="black" border=0 cellpadding=0 cellspacing=1 width=752><tr><td align=center><span class="whitemedhead">TOOLBOX</span></td>';
 output += '<td valign=top><span class="whitehead">introduce: (S)mall (M)edium (L)arge<br><table bgcolor="black" border=0 cellpadding=2 cellspacing=2><tr>';
 output += '<td bgcolor="#666666"><span class="whitehead"><a href="javascript:introduce(new obstacle(\'planet.gif\', 94, 94, circle, 40, 300, 200, 1));">large planet</a></span></td>';
 output += '<td bgcolor="#666666"><span class="whitehead">vertical wall <span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 10, 100, square, 40, 300, 200, 0));">&nbsp;S&nbsp;</a></span> ';
 output += '<span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 10, 200, square, 40, 300, 200, 0));">&nbsp;M&nbsp;</a></span> ';
 output += '<span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 10, 300, square, 40, 300, 200, 0));">&nbsp;L&nbsp;</a></span> ';
 output += '</span></td></tr><tr>';
 output += '<td bgcolor="#666666"><span class="whitehead"><a href="javascript:introduce(new obstacle(\'repel-sm.gif\', 30, 30, circle, 12, 300, 200, -1));">small repeller</a></span></td>';
 output += '<td bgcolor="#666666"><span class="whitehead">horizontal wall <span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 100, 10, square, 40, 300, 200, 0));">&nbsp;S&nbsp;</a></span> ';
 output += '<span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 200, 10, square, 40, 300, 200, 0));">&nbsp;M&nbsp;</a></span> ';
 output += '<span style="background-color:#333333;"><a href="javascript:introduce(new obstacle(\'black.gif\', 300, 10, square, 40, 300, 200, 0));">&nbsp;L&nbsp;</a></span>';
 output += '</span></td></tr></table></span></td><td valign=top><span class="whitehead">orbiter state:<br><table bgcolor="black" border=0 cellpadding=2 cellspacing=2><tr><td bgcolor="#666666"><span class="whitehead"><a href="javascript://" onMouseDown="startturn(-15);">turn left 15&deg;</a></span></td>';
 output += '<td bgcolor="#666666"><span class="whitehead">x-drift: <span id="toolboxdx" style="background-color:#333333; width:20px;"></span>&nbsp;<a href="javascript://" onMouseDown="startdrift(\'x\',-1);">left</a> <a href="javascript://" onMouseDown="startdrift(\'x\',1);">right</a></span></td>';
 output += '</tr><tr><td bgcolor="#666666"><span class="whitehead"><a href="javascript://" onMouseDown="startturn(15);">turn right 15&deg;</a></span></td>';
 output += '<td bgcolor="#666666"><span class="whitehead">y-drift: <span id="toolboxdy" style="background-color:#333333; width:20px;"></span>&nbsp;<a href="javascript://" onMouseDown="startdrift(\'y\',-1);">up</a> <a href="javascript://" onMouseDown="startdrift(\'y\',1);">down</a></span></td>';
 output += '</tr></table></span></td></tr></table>';
 setspancontent ('toolbox', output);
 setspancontent ('lockbutton', '<a href="javascript:lock();">lock universe</a>');
 setspancontent ('demoinfo', '');
 loadeddemo = null;
 locked = false;
 updatestats();
}

function lock(){
 setspancontent ('toolbox', '');
 setspancontent ('lockbutton', '<a href="javascript:unlock();">unlock universe</a>');
 locked = true;
}

