// Copyright 1998-2010  All Rights Reserved Richard Shelquist,  January 1998 - July 2010

// This calculator is the copyrighted intellectual property of Richard Shelquist, Shelquist Engineering.

// This calculator may be freely used for an individual's personal use via my web site,
// or by means of one copy on an individual's own computer for that person's personal use, 
// but may not be copied or republished in any form on any web site, bulletin board or 
// any other means.



// Global Variables for conversions
	var in_per_mb = (1/33.86389);		
	var mb_per_in = 33.86389;
				
	var m_per_ft = 0.304800;
	var ft_per_m = (1/0.304800);
	
	


function e_resetOut()
{
	var inForm=document.e_inputs;
	var outForm=document.e_outputs;

	outForm.densalt.value = "";
	outForm.actpress.value = "";
	outForm.relden.value = "";

	inForm.elevation.focus();
}


function e_resetForm()
{
	var inForm=document.e_inputs;
	var outForm=document.e_outputs;

	inForm.elevation.value = "";
	inForm.temperature.value = "";
	inForm.altset.value = "";
	inForm.rh.value = "";

	outForm.densalt.value = "";
	outForm.actpress.value = "";
	outForm.relden.value = "";

	inForm.elevation.focus();
}



function roundNum(Num, Places)
//  Rounding function by Jason Moon
{
   if (Places > 0) {
      if ((Num.toString().length - Num.toString().lastIndexOf('.')) > (Places + 1)) {
         var Rounder = Math.pow(10, Places);
         return Math.round(Num * Rounder) / Rounder;
      }
      else {return Num;}
   }
   else {return Math.round(Num);}
}




function calcVaporPressure_wobus(t)
// Calculate the saturation vapor pressure given the temperature(celsius)
// Polynomial from Herman Wobus 
{
	var eso=6.1078;
	var es;
	var c0=0.99999683;
	var c1=-0.90826951E-02;
	var c2=0.78736169E-04;
	var c3=-0.61117958E-06;
	var c4=0.43884187E-08;
	var c5=-0.29883885E-10;
	var c6=0.21874425E-12;
	var c7=-0.17892321E-14;
	var c8=0.11112018E-16;
	var c9=-0.30994571E-19;
	
	var pol=c0+t*(c1+t*(c2+t*(c3+t*(c4+t*(c5+t*(c6+t*(c7+t*(c8+t*(c9)))))))));
	
	es=eso/Math.pow(pol,8);

	return (es);
}



function calcAbsPress(pressure, altitude)
// Calculate absolute air pressure given the barometric pressure(mb) and altitude(meters)
{
	var k1=0.190284;
	var k2=8.4288*Math.pow(10,-5);
	var p1=Math.pow(pressure,k1);
	var p2=altitude*k2;
	var p3=0.3+Math.pow( (p1-p2), (1/k1) );
	return (p3);
}


function calcDensity(abspressmb, e, tc)
//  Calculate the air density in kg/m3
{
	var Rv=461.4964;
	var Rd=287.0531;
	
	var tk=tc+273.15;
	var pv=e*100;
	var pd= (abspressmb-e)*100;
	var d= (pv/(Rv*tk)) + (pd/(Rd*tk));
	return(d);
}


function calcAltitude(d)
// Calculate the ISA altitude (meters) for a given density (kg/m3)
{
	var g=9.80665;
	var Po=101325;
	var To=288.15;
	var L=6.5;
	var R=8.314320;
	var M=28.9644;
	
	var D=d*1000;
	
	var p2=( (L*R)/(g*M-L*R) )*Math.log( (R*To*D)/(M*Po) );
	
	var H=-(To/L)*( Math.exp(p2)-1 );
	
	var h=H*1000;

	return(h);
}





function calcZ(h)
// Calculate the Z altitude (meters), given the H altitide (meters)
{
	var r=6369E3;
	
	return ((r*h)/(r-h));

}



function calcH(z)
// Calculate the H altitude (meters), given the Z altitide (meters)
{
	var r=6369E3;
	
	return ((r*z)/(r+z));

}




function calcAs2Press(As, h)
// Calculate the actual pressure (mb)from the altimeter setting (mb) and geopotential altitude (m)
{
	var k1=0.190263;
	var k2=8.417286E-5;

	var p=Math.pow( (Math.pow(As,k1)-(k2*h)),(1/k1) );

	return (p);
}




function validateInput ( InputName, prompt )
// Checks a form input to see that the input is not blank and that it is a number
{
	if (isNaN(InputName.value) || (InputName.value.length===0) || InputName.value.charAt(0)===" " )
	{
			alert (prompt);
			InputName.focus();
			InputName.select();
			return false;
	}
 return true;
}




/////////////////////////////////////////////////////////////////////////////////////////////
///// Calculations for English units ////////////////////////////////////////////////////////

function e_calc()
{
	var inForm=document.e_inputs;
	var outForm=document.e_outputs;

// Validate all the required inputs

	if (!validateInput(inForm.elevation, "Invalid entry for Elevation")) {return;}
	if (!validateInput(inForm.temperature, "Invalid entry for Temperature")) {return;}
	if (!validateInput(inForm.altset, "Invalid entry for Altimeter Setting")) {return;}
	if (!validateInput(inForm.rh, "Invalid entry for Relative Humidity")) {return;}
	
	
// Process the input values

	var tf=1.0*inForm.temperature.value;		// temperature, deg F
	var rh=1.0*inForm.rh.value;			// relative humidity, %
	var altset=1.0*inForm.altset.value;			// altimeter setting, in-Hg
	var z=1.0*inForm.elevation.value;			// geometric elevation, feet
	
// Convert to metric units	

	var tc=(5/9)*(tf-32 );
	var altsetmb=altset*mb_per_in;	
	var zm=z*m_per_ft;	
	

// Calculate the vapor pressures (mb) given the ambient temperature (c) and relative humidity (c)

	var esmb=calcVaporPressure_wobus(tc);
	var emb=esmb*rh/100;

	
// Calculate geopotential altitude H (m) from geometric altitude (m) Z

	var hm=calcH(zm);
	
	
// Calculate the absolute pressure given the altimeter setting(mb) and geopotential elevation(meters)

	var actpressmb=calcAs2Press(altsetmb,hm);	


// Calculate the air density (kg/m3) from absolute pressure (mb) vapor pressure (mb) and temp (c)

	var density=calcDensity(actpressmb, emb, tc);
	var relden=100*(density/1.225);
	
	
// Calculate the geopotential altitude (m) in ISA with that same density (kg/m3)
  
    var densaltm=calcAltitude(density);
    
// Calculate geometric altitude Z (m) from geopotential altitude (m) H

    var densaltzm=calcZ(densaltm);
    
    
// Convert Units for output

	var actpress=actpressmb*in_per_mb;    
	var densalt=densaltzm*ft_per_m;
    
	if ( densalt > 36090 || densalt < -15000 )
	{
		alert ("Out of range for Troposhere Algorithm: Altitude =" + roundNum(densalt,0) + " feet\nPlease check your input values." );
		e_resetOut();
		return;
	}
    
    
// Print the results

	outForm.actpress.value=roundNum(actpress,3);
	outForm.relden.value=roundNum(relden,2);    
	outForm.densalt.value=roundNum(densalt,0);
    
    
}
