var asis=false
var ltud=true

// Translate Horizontal to Equatorial coordinates
function HzToEq(flag,DTF,Az,al,Lo,la)
{   var L,l,A,a,r,d,H

    L=rdAngle(Lo)
    l=rdAngle(la)
    A=rdAngle(Az)
    a=rdAngle(al)
    d=aSind(Sind(a)*Sind(l)+Cosd(a)*Cosd(l)*Cosd(A))
    H=aCosd((Sind(a)-Sind(l)*Sind(d))/(Cosd(l)*Cosd(d)))
    if (Sind(A)>0) {H=360-H}
    r=LST(DTF,L)-H
    if (r<0) {r=r+360}
    alert('Right Ascension=' + fmtAngle(flag,asis,r)+
        '\nDeclination='     + fmtAngle(flag,ltud,d) )
}

// Translate Equatorial to as Horizontal coordinates
function EqToHz(flag,DTF,ra,dc,Lo,la)
{   var L,l,A,a,r,d,H

    L=rdAngle(Lo)
    l=rdAngle(la)
    r=rdAngle(ra)
    d=rdAngle(dc)
    H=LST(DTF,L)-r
    a=aSind(Sind(d)*Sind(l)+Cosd(d)*Cosd(l)*Cosd(H))
    A=aCosd((Sind(d)-Sind(l)*Sind(a))/(Cosd(l)*Cosd(a)))
    if (Sind(H)>0) {A=360-A}
    alert('Azimuth=' + fmtAngle(flag,asis,A)+
        '\nAltitude='+ fmtAngle(flag,ltud,a) )
}

// Translate Ecliptic to Equatorial coordinates
function EcToEq(flag,l,b)
{   var e,a,d,L,B

    e=23.439168
    L=rdAngle(l)
    B=rdAngle(b)
    a=aTand(Tand(L)*Cosd(e) - Tand(B)*Sind(e)/Cosd(L))
    d=aSind(Sind(B)*Cosd(e) + Cosd(B)*Sind(e)*Sind(L))
    a=SameSide(a,L)
    alert('Right Ascension=' + fmtAngle(flag,asis,a)+
        '\nDeclination='     + fmtAngle(flag,ltud,d) )
}

// Translate Equatorial to Ecliptic coordinates
function EqToEc(flag,A,D)
{   var e,a,d,L,B

    e=23.439168
    a=rdAngle(A)
    d=rdAngle(D)
    L=aTand(Tand(a)*Cosd(e) + Tand(d)*Sind(e)/Cosd(a))
    B=aSind(Sind(d)*Cosd(e) - Cosd(d)*Sind(e)*Sind(a))
    L=SameSide(L,a);
    alert('Longitude='+ fmtAngle(flag,asis,L)+
        '\nLatitude=' + fmtAngle(flag,ltud,B) )
}

// Compute the elongation between two bodies
function elong(flag,SA,SD,PA,PD)
{   var Sa,Sd,Pa,Pd,el

    Sa=rdAngle(SA)
    Sd=rdAngle(SD)
    Pa=rdAngle(PA)
    Pd=rdAngle(PD)
    el=aCosd( Sind(Pd)*Sind(Sd)+Cosd(Sa-Pa)*Cosd(Pd)*Cosd(Sd) )
    alert('Elongation=' + fmtAngle(flag,asis,el) )
}

// Compute the Great Circle Distance between two points on a globe
function GCD(flag,RD,SA,SD,PA,PD)
{   var Sa,Sd,Pa,Pd,el,R,U,SP

    Sa=rdAngle(SA)
    Sd=rdAngle(SD)
    Pa=rdAngle(PA)
    Pd=rdAngle(PD)
    el=aCosd( Sind(Pd)*Sind(Sd)+Cosd(Sa-Pa)*Cosd(Pd)*Cosd(Sd) )
    rd=rdDecml(RD)
    U=rdUnits(RD)
    SP=(Pi*rd)*(el/180)
    alert('Great Circle Distance='+ fmtDecml(SP)+U)
}

// Translate Cartesian to Spherical coordinates
function tospherical(flag,X,Y,Z)
{   var U,x,y,z,L,B,R,r

    U=rdUnits(X)
    x=cvtDists(X,U)
    y=cvtDists(Y,U)
    z=cvtDists(Z,U)
    r=Sqrt((x*x)+(y*y))
    R=Sqrt((x*x)+(y*y)+(z*z))
    L=aSind(y/r)
    B=aSind(z/R)
    alert('Lambda='  +fmtAngle(flag,asis,L)+
        '\nBeta='    +fmtAngle(flag,asis,B)+
        '\nRho=\n   '+fmtDecml(R)+U )
}

// Translate Spherical to Cartesian coordinates
function tocartesian(Lm,Bt,Ro)
{   var U,x,y,z,L,B,R,r

    L=rdAngle(Lm)
    B=rdAngle(Bt)
    R=rdDecml(Ro)
    U=rdUnits(Ro)
    r=R*Cosd(B)
    z=R*Sind(B)
    y=r*Sind(L)
    x=r*Cosd(L)
    alert('X='+fmtDecml(x)+U+
        '\nY='+fmtDecml(y)+U+
        '\nZ='+fmtDecml(z)+U)
}

   // Display an angle in whatever formats the user desires
function sameas(flag,A)
{   var a

    a=rdAngle(A)
    alert('Angle=' + fmtAngle(flag,asis,a) )
}

// Combine multiple stellar magnitudes into a single magnitude. Magnitudes are
// based on the negative fifth root of 100. Hence the mystery numbers.
function combine(Mags)
{   var mags,nbr,M,G,S,i,n,fifthroot

    mags=RetainOnly(Mags,'-.*0123456789')
    nbr=''
    M=G=S=i=n=0
    fifthroot=-5
    while (true)
    {
         nbr=nthword(mags,n+1)
         if (nbr=='') {break}
         i=nbr.indexOf('*')
         if (i>0)
         {
            G=rdDecml(nbr.substring(0,i))
            nbr=nbr.substring(i+1)
         }
         else
           {G=1}
         M=rdDecml(nbr)/fifthroot
         S+=G*Power(100,M)
         ++n
    }
    if (n==0) {alert('Magnitudes are required.'); return}
    M=fifthroot*Log100(S)
    alert('Combined magnitudes are '+fmtDecml(M,2))
}

// Approximate the defraction for any altitude angle H
function refraction(H)
{   var h,r

    h=rdAngle(H)
    r=0
    if (h<0.0) {h=0.0}
    if (h<89.999)
        {r=1.02/Tand(h+(0.3/(h+5.11)))}
    alert('The refraction is '+fmtDecml(r,2)+' arcminutes.')
}

// Determine how long before bodies achieve a similar alignment
// Strictly speaking this only works for circular orbits but it
// reasonably well for ellipses  with an eccentricity less than 0.25
function conjunction(I,O)
{   var U,i,o,z

    U=rdUnits(I)
    i=rdDecml(I)
    o=rdDecml(O)
    z=1/Abs((1/i)-(1/o))
    alert('The bodies will align again in '+fmtDecml(z,3)+U)
}

// Compute the air density from air temperature at sea level and altitude
function airdensity(T,D)
{   var k,d,p,x

    k=cvtTemps(T,'k')
    d=cvtDists(D,'km')
    p=-(k/34.169)
    x=Exp(d/p)
    alert('The air below this altitude is '+fmtDecml((100*(1-x)),2)+
        '% and above is '+fmtDecml(100*x,2)+'%')
}

// Angle/Side/Angle Completion [Note: one angle is implicit right angle]
function AsideA(A,RR,DD)
{   var r,ru,R,d,du,D,A,a,s,f,v,h,af,rf,df,sf,vf,hf

    s=0
    if ( A.indexOf('?')>=0) {++s}
    if (RR.indexOf('?')>=0) {++s}
    if (DD.indexOf('?')>=0) {++s}
    if (s!=1) { alert('Exactly one field must have a "?".'); return }
    ru=rdUnits(RR,'km')
    du=rdUnits(DD,'AU')
    R=nthword(RR,1)+ru
    D=nthword(DD,1)+du
    if (A.indexOf('?')>=0)
    {
        r=cvtDists(R,'km')
        d=cvtDists(D,'km')
        a=aSind(r/(r+d))
    }
    if (R.indexOf('?')>=0)
    {
        d=cvtDists(D,'km')
        a=rdQ1(A)
        s=Sind(a)
        r=d*(s/(1-s))
    }
    if (D.indexOf('?')>=0)
    {
        r=cvtDists(R,'km')
        a=rdQ1(A)
        s=Sind(a)
        d=r*((1-s)/s)
    }
    f=new Array(true,false,false,false,false,true)
    v=(90-a)/180
    h=rdDecml(R)
    s=d+r
    s=Sqrt((s*s)-(r*r))
    af=fmtAngle(f,true,2*a)
    rf=fmtDecml(kmTo(r,ru))+ru
    df=fmtDecml(kmTo(d,du))+du
    sf=fmtDecml(kmTo(s,du))+du
    vf=fmtDecml(200*v,2)+'%'
    hf=fmtDecml((Pi*h*v),1)+ru
    af=af.substring(3)
    alert('Angle='+af+
        '\nVisible='+vf+
        '\nRadius='+rf+
        '\nHorizon='+hf+
        '\nDistance='+df+
        '\nSightline='+sf)
    return

    // Internal function of AsideA - restores desired units after forcing kilometers
    function kmTo(v,vu)
    {   var V,z

        V=String(v)+' km'
        z=cvtDists(V,vu)
        return z
    }

    // Internal function of AsideA - insures half-angles lie between 0 and 90.
    function rdQ1(A)
    {   var a

        a=rdAngle(A)
        if ((a>=0) && (a<=180)) {return a/2}
        alert('Angles must lie between 0 and 180 degrees')
        return 0
    }
}

