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

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

// 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.densaltz.value = "";
	outForm.actpress.value = "";

	outForm.relden.value = "";
	outForm.relden2.value = "";
	
	outForm.densaltzm.value = "";
	outForm.actpressmb.value = "";	

	outForm.awos.value = "";
	outForm.awosm.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.dewpoint.value = "";

	outForm.densaltz.value = "";
	outForm.actpress.value = "";

	outForm.relden.value = "";
	outForm.relden2.value = "";

	outForm.awos.value = "";
	outForm.awosm.value = "";
	
	outForm.densaltzm.value = "";
	outForm.actpressmb.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;
}




/////////////////////////////////////////////////////////////////////////////////////////////
///// Main program: Calculations for English and/or Metric units /////////////////////////////////////////////////////////////////////////////////////////////

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

	// define variables to be used in inputs
	var z, zm, altset, altsetmb, tf, tc, tdpf, tdpc;


// 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.dewpoint, "Invalid entry for Dew Point")) {return;}
	
	
// Process the input values

	
	if(inForm.in_elev[0].checked=="1")
	{
		z=1.0*inForm.elevation.value;			// geometric elevation, feet
		zm=z*m_per_ft;
	}
	
	if(inForm.in_elev[1].checked=="1")
	{
		zm=1.0*inForm.elevation.value;			// geometric elevation, meters
		z=zm*ft_per_m;
	}	
	



	if(inForm.in_alt_set[0].checked=="1")
	{
		altset=1.0*inForm.altset.value;			// altimeter setting, in-Hg
		altsetmb=altset*mb_per_in;	
	}
	
	if(inForm.in_alt_set[1].checked=="1")
	{
		altsetmb=1.0*inForm.altset.value;		// altimeter setting, mb
		altset=altsetmb*in_per_mb;
	}	
	
	
	

	if(inForm.in_temp[0].checked=="1")
	{
		tf=1.0*inForm.temperature.value;		// temperature, deg F
		tc=(5/9)*(tf-32 );
	}
	
	if(inForm.in_temp[1].checked=="1")
	{
		tc=1.0*inForm.temperature.value;		// temperature, deg C
		tf=((9/5)*tc)+32;
	}	
	



	if(inForm.in_dp[0].checked=="1")
	{
		tdpf=1.0*inForm.dewpoint.value;			// dewpoint, deg F
		tdpc=(5/9)*(tdpf-32);
	}
	
	if(inForm.in_dp[1].checked=="1")
	{
		tdpc=1.0*inForm.dewpoint.value;			// dewpoint, deg C
		tdpf=((9/5)*tdpc)+32;
	}		
	
	
	
		


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

	var emb=calcVaporPressure_wobus(tdpc);

	
// 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 densaltz=densaltzm*ft_per_m;

	if ( densaltz > 36090 || densaltz < -15000 )
	{
		alert ("Out of range for Troposhere Algorithm: Altitude =" + roundNum(densaltz,0) + " feet\nPlease check your input values." );
		e_resetOut();
		return;
		}


// calculate awos report

var nws = 145442.16*(1- Math.pow(((17.326*actpress)/(tf + 459.67)),0.235));
var awos = roundNum(nws/100)*100;
	
    
// Print the results

	outForm.densaltz.value=roundNum(densaltz,0);
	outForm.actpress.value=roundNum(actpress,3);
	outForm.relden.value=roundNum(relden,2);    
    
	outForm.densaltzm.value=roundNum(densaltzm,0);
	outForm.actpressmb.value=roundNum(actpressmb,2); 
	outForm.relden2.value=roundNum(relden,2);
     
	
	outForm.awos.value= awos;
	outForm.awosm.value= roundNum((awos*m_per_ft),0);

   
}
