// Functions for celestial navigation

RAD = (3.1415926535/180)
DEG = (180/3.1415926535)

/**
 * Compute Hc and Azimuth based on latitude, declination, and
 * local hour angle.  Returns [Hc, Z]
 */
function HcAz(lat, dec, lha) {
  var clat, slat, cdec, sdec, clha, Hc, cHc, sHc, Z;
  if( lha < 0 ) lha += 360;
  else if( lha > 360 ) lha -= 360;
  // debug('lat = ' + lat);
  // debug('dec = ' + dec);
  // debug('lha = ' + lha);
  clat=Math.cos(lat*RAD); slat=Math.sin(lat*RAD);
  cdec=Math.cos(dec*RAD); sdec=Math.sin(dec*RAD);
  clha=Math.cos(lha*RAD);
  // debug('clat = ' + clat + ', slat = ' + slat);
  // debug('cdec = ' + cdec + ', sdec = ' + sdec);
  // debug('clha = ' + clha);
  Hc = Math.asin(clat*cdec*clha + slat*sdec);
  // debug('Hc = ' + Hc*DEG);
  cHc = Math.cos(Hc); sHc = Math.sin(Hc);
  // debug('cHc = ' + cHc + ', sHc = ' + sHc);
  Hc *= DEG;
  if( cHc == 0 || clat == 0 )
    Z = 0;
  else {
    Z = (sdec - sHc * slat) / (cHc*clat);
    // debug('cos(Z) = ' + Z);
    if( Z >= 1 ) Z = 0;
    else if( Z <= -1 ) Z = 180;
    else Z = Math.acos(Z) * DEG;
    if( lha <= 180 )
      Z = 360 - Z;
  }
  return [Hc, Z];
}

/**
 * Compute Hc and Azimuth based on latitude, longitude, declination, and
 * Grenwich hour angle.  Returns [Hc, Z]
 */
function HcAz2(lat, lon, dec, gha) {
  return HcAz(lat, dec, gha - lon);
}

/**
 * Utility:  Format a decimal number.  X is the number, n is the field
 * width.  Equivalent to %nd.
 */
function fmtd(x, n) {
  x = x|0;
  rval = '' + x;
  if( rval.length < n )
    rval = "               ".substring(0,n-rval.length) + rval;
  return rval;
}

/**
 * Utility:  Convert degrees to dd°mm
 */
function DM(deg) {
  var d, m;
  deg = Math.round(deg*60);
  d = (deg/60)|0;
  m = deg-d*60;
  return "" + fmtd(d,2) + "°" + (""+(100+m)).substring(1,3);
}


/**
 * Utility:  Append text to the div named "debug"
 */
function debug(str) {
  msg = document.getElementById('debug');
  msg.innerHTML += str + '<br>';
}
