/* Functions: event-driven functions: - onLoadBody () when html-body is loaded - onChangeTabCalculation () when activating the calculation bar - onChangeCalculationItem () when changing the item to be calculated in sink-rate-dialog - onChangeItem () when changing editable items in sink-rate-dialog - onChangeUnits () when changing editable units in ?-dialog - onChangeProperties () when changing properties in ?-dialog - onChangeShowAircraftInfos () when selecting an other aircraft to show its infos internal functions: - setObjectVariables () set the calculation input-object-variables - setCalculationDefault () determine option-group-field that should be calculated - setConnotationHeadline () display connotation h2 as sub navigation - setConnotationHeadlineLinks () set connotation headline links (only called, when they have been conversted into html links) - setFocusToCalculationElement () set focus to most edited field - clearCssClassOfInputFields () removes css-class from all input fields except the one to be calculated - clearCssClassOfInputField () removes css-class from the given input field - calculateDefaultItem () calculate default item - calculateItem () calculate given item - convertTimeToHMM () converts numeric value to time in h:mm-format calculation functions: - calculateDistance () calculate distance in nm - calculateHeight () calculate height in hundreds of feet - calculateSpeed () calculate speed in kts - calculateRate () calculate rate in ft / min - calculateDegrees () calculate slope in degrees - calculateTime () calculate time in h:mm */ // CONSTANTS const NUMBER_OF_MINUTES_IN_HOUR = 60; const NAUTIC_MILE_IN_FEET = 6076.12; const METER_IN_FEET = 3.28; const METER_PER_SECOND_IN_KNOTS = 1.94; const KILOMETER_IN_KNOTS = 0.54; const KILOMETER_IN_MILES_PER_HOUR = 0.62; const MILES_PER_HOUR_IN_KNOTS = 0.87; // VARIABLES // html-input-field-objects var objHorizontalDistanceInNauticMiles; var objVerticalDistanceInFeet; var objGroundSpeedInKts; var objRateInFtPerMinute; var objRateInDegrees; var objAmountOfTime; // EVENT-DRIVEN FUNCTIONS function onLoadBody () { setCalculationDefault (); setObjectVariables (); setConnotationHeadline (); } function onChangeTabCalculation () { setFocusToCalculationElement (); calculateDefaultItem (); } function onChangeCalculationItem (item) { var currentCalculationItem = item.value; clearCssClassOfInputFields (currentCalculationItem); document.getElementById(currentCalculationItem).className = "disabled"; document.getElementById(currentCalculationItem).disabled = true; } function onChangeItem (item) { calculateItem (document.calculation_form.calculation_group.value); } function onChangeUnits (item) { var val = 0; var objUnits = document.getElementById("units"); var objInputLeft = document.getElementById("input_left"); var objInputRight = document.getElementById("input_right"); var objLabelLeft = document.getElementById("label_input_left"); var objLabelRight = document.getElementById("label_input_right"); switch (objUnits.value) { case 'm_ft': if (item.id == "input_left") { val = item.value * METER_IN_FEET; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / METER_IN_FEET; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "m"; objInputLeft.value = 0; objInputLeft.step = 100; objLabelRight.innerHTML = "ft"; objInputRight.value = 0; objInputRight.step = 500; } break; case 'm/s_kts': if (item.id == "input_left") { val = item.value * METER_PER_SECOND_IN_KNOTS; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / METER_PER_SECOND_IN_KNOTS; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "m/s"; objInputLeft.value = 0; objInputLeft.step = 1; objLabelRight.innerHTML = "kts"; objInputRight.value = 0; objInputRight.step = 1; } break; case 'kmh_kts': if (item.id == "input_left") { val = item.value * KILOMETER_IN_KNOTS; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / KILOMETER_IN_KNOTS; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "km/h"; objInputLeft.value = 0; objInputLeft.step = 10; objLabelRight.innerHTML = "kts"; objInputRight.value = 0; objInputRight.step = 10; } break; case 'kmh_mph': if (item.id == "input_left") { val = item.value * KILOMETER_IN_MILES_PER_HOUR; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / KILOMETER_IN_MILES_PER_HOUR; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "km/h"; objInputLeft.value = 0; objInputLeft.step = 10; objLabelRight.innerHTML = "mph"; objInputRight.value = 0; objInputRight.step = 10; } break; case 'mph_kts': if (item.id == "input_left") { val = item.value * MILES_PER_HOUR_IN_KNOTS; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / MILES_PER_HOUR_IN_KNOTS; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "mph"; objInputLeft.value = 0; objInputLeft.step = 10; objLabelRight.innerHTML = "kts"; objInputRight.value = 0; objInputRight.step = 10; } break; case 'km_nm': if (item.id == "input_left") { val = item.value * KILOMETER_IN_KNOTS; objInputRight.value = val.toFixed(0); } else if (item.id == "input_right") { val = item.value / KILOMETER_IN_KNOTS; objInputLeft.value = val.toFixed(0); } else if (item.id == "units") { objLabelLeft.innerHTML = "km"; objInputLeft.value = 0; objInputLeft.step = 10; objLabelRight.innerHTML = "nm"; objInputRight.value = 0; objInputRight.step = 10; } break; } } function onChangeProperties (item) { var objTableDiv = document.getElementById("property_table"); switch (item.value) { case 'default': objTableDiv.innerHTML = ""; break; case 'rw_departure': objTableDiv.innerHTML = "
Volocopter Volocityno dataft
Wright Flyerno dataft
ft
Zlin Savage Carbon200
100
ft
ft
Zlin Savage Shock Ultra200
100
ft
ft
Zlin Savage Cub400
250
ft
ft
Pitts Special500ft
DHC-2 Beaver560ft
Icon A5590
450
ft
ft
Cub Crafters XCub600
280
ft
ft
Cub Crafters NXCub600
150
ft
ft
JMB VL-3 915600
420
ft
ft
Extra 330 LT1000
700
ft
ft
Whittaker MW61000
700
ft
ft
Pipistrel Virus SW 1211050
525
ft
ft
Diamond Aircraft DV201100ft
Diamond Aircraft DA40 TDI1200
950
ft
ft
Diamond Aircraft DA40 NG1300
990
ft
ft
Cessna 1521385
750
ft
ft
Ryan Spirit Of St. Louis NYP1500ft
Curtiss JN-4D1500ft
Cessna 172 Skyhawk1525
865
ft
ft
Cirrus SR221593
1082
ft
ft
Douglas DC-3 S1600
900
ft
ft
Robin Regent DR400-1802000
1034
ft
ft
Cessna 208B Grand Caravan EX2160
1400
ft
ft
Beechcraft Bonanza G362180
1300
ft
ft
Beechcraft Baron G582345
1373
ft
ft
Daher TBM 9302380
1800
ft
ft
Diamond Aircraft DA622897
1574
ft
ft
Rutan Boomerang3000ft
Beechcraft King Air 350i3300ft
Cessna CJ4 Citation4000
5000
ft
ft
Cessna Citation Longitude4810ft
"; break; case 'rw_approach': objTableDiv.innerHTML = "
Volocopter Volocityno dataft
Wright Flyerno dataft
ft
Zlin Savage Carbon200
15
15
ft
ft
kts
Zlin Savage Shock Ultra200
58
16
ft
ft
kts
Zlin Savage Cub400
200
15
ft
ft
kts
DHC-2 Beaver500
10
ft
kts
Cub Crafters XCub500
170
11
ft
ft
kts
Cub Crafters NXCub500
150
11
ft
ft
kts
Icon A5530
450
12
ft
ft
kts
JMB VL-3 915600
420
10
ft
ft
kts
Diamond Aircraft DV20750
15
ft
kts
Whittaker MW6800
300
ft
ft
Diamond Aircraft DA40 TDI942
850
20
ft
ft
kts
Extra 330 LT1000
500
15
ft
ft
kts
Diamond Aircraft DA40 NG1040
890
20
ft
ft
kts
Pipistrel Virus SW 1211050
525
18
ft
ft
kts
Cessna 1521075
500
15
ft
ft
kts
Cessna 172 Skyhawk1250
520
17
ft
ft
kts
Pitts Special1500
17
ft
kts
Curtiss JN-4D1500
10
ft
kts
Douglas DC-3 S1600
15
ft
kts
Beechcraft Bonanza G361700
920
17
ft
ft
kts
Robin Regent DR400-1801740
820
22
ft
ft
kts
Cessna 208B Grand Caravan EX1850
1000
20
ft
ft
kts
Ryan Spirit Of St. Louis NYP2000ft
Cirrus SR222343
1178
21
ft
ft
kts
Daher TBM 9302430
1300
20
ft
ft
kts
Beechcraft Baron G582490
1440
22
ft
ft
kts
Diamond Aircraft DA622556
1447
25
ft
ft
kts
Beechcraft King Air 350i2700
20
ft
kts
Cessna CJ4 Citation3000
19
ft
kts
Cessna Citation Longitude3170
25
ft
kts
Rutan Boomerang3200
1500
25
ft
ft
kts
"; break; case 'cruise_speed': objTableDiv.innerHTML = "
Cessna CJ4 Citationno dataKIAS
Beechcraft King Air 350ino dataKIAS
Cessna Citation Longitudeno dataKIAS
Wright Flyer22mph
Curtiss JN-4D52kts
Volocopter Volocity54kts
Whittaker MW655mph
Icon A584KTAS
Ryan Spirit Of St. Louis NYP100mph
Cessna 152107KIAS
Zlin Savage Carbon110kts
Diamond Aircraft DV20117KIAS
Pipistrel Virus SW 121120KIAS
Cessna 172 Skyhawk122KIAS
Diamond Aircraft DA40 NG125KIAS
Cub Crafters NXCub126KIAS
Cub Crafters XCub126KIAS
Diamond Aircraft DA40 TDI129KIAS
Pitts Special137mph
Zlin Savage Shock Ultra140IAS
JMB VL-3 915153KIAS
DHC-2 Beaver156mph
Beechcraft Baron G58163KIAS
Cessna 208B Grand Caravan EX164KIAS
Zlin Savage Cub165IAS
Cirrus SR22170KIAS
Diamond Aircraft DA62171KIAS
Extra 330 LT173KIAS
Beechcraft Bonanza G36174KIAS
Douglas DC-3 S204mph
Rutan Boomerang220KIAS
Daher TBM 930252KIAS
Robin Regent DR400-180254km/h
"; break; case 'service_ceiling': objTableDiv.innerHTML = "
Whittaker MW6no dataft
Wright Flyer30ft
Volocopter Volocity6500ft
Curtiss JN-4D6500ft
Diamond Aircraft DV2013120ft
Cessna 172 Skyhawk13500ft
Cub Crafters XCub14000ft
Cub Crafters NXCub14000ft
Zlin Savage Cub14400ft
Cessna 15214700ft
Icon A515000ft
Robin Regent DR400-18015500ft
Zlin Savage Shock Ultra15750ft
Extra 330 LT16000ft
Ryan Spirit Of St. Louis NYP16400ft
Diamond Aircraft DA40 NG16400ft
Diamond Aircraft DA40 TDI16400ft
Cirrus SR2217500ft
Pipistrel Virus SW 12118000ft
Zlin Savage Carbon18000ft
DHC-2 Beaver18000ft
Beechcraft Bonanza G3618500ft
JMB VL-3 91520000ft
Diamond Aircraft DA6220000ft
Pitts Special20000ft
Beechcraft Baron G5820000ft
Cessna 208B Grand Caravan EX20000ft
Douglas DC-3 S20800ft
Rutan Boomerang22000ft
Daher TBM 93031000ft
Beechcraft King Air 350i35000ft
Cessna Citation Longitude45000ft
Cessna CJ4 Citation45000
28000
ft
ft
"; break; case 'range': objTableDiv.innerHTML = "
Wright Flyerno datanm
Whittaker MW6no datanm
Volocopter Volocity20nm
Curtiss JN-4D135nm
Pitts Special277nm
Extra 330 LT350nm
DHC-2 Beaver395nm
Zlin Savage Carbon400nm
Cessna 152415nm
Icon A5427nm
Zlin Savage Shock Ultra598km
Diamond Aircraft DV20629nm
Pipistrel Virus SW 121642nm
Cirrus SR22659nm
Diamond Aircraft DA40 NG675nm
Cessna 172 Skyhawk696nm
Cub Crafters NXCub700nm
Zlin Savage Cub700km
Cub Crafters XCub700nm
Diamond Aircraft DA40 TDI741nm
Robin Regent DR400-180790nm
JMB VL-3 915800nm
Beechcraft Bonanza G36820nm
Beechcraft Baron G58942nm
Cessna 208B Grand Caravan EX1052nm
Diamond Aircraft DA621290nm
Daher TBM 9301440
1730
nm
nm
Beechcraft King Air 350i1500
1800
nm
nm
Rutan Boomerang2053nm
Cessna CJ4 Citation2140nm
Douglas DC-3 S2500
3000
nm
nm
Cessna Citation Longitude3500nm
Ryan Spirit Of St. Louis NYP3600nm
"; break; default: objTableDiv.innerHTML = "

unknown value '" + item.value + "'.

"; break; } } function onChangeShowAircraftInfos (item) { window.location.href = "?aircraft=" + item.value; } // INTERNAL FUNCTIONS function setObjectVariables () { objHorizontalDistanceInNauticMiles = document.getElementById('distance-in-nm'); objVerticalDistanceInFeet = document.getElementById('height-difference-in-ft'); objGroundSpeedInKts = document.getElementById('speed-in-kts'); objRateInFtPerMinute = document.getElementById('rate-in-ft-per-min'); objRateInDegrees = document.getElementById('rate-in-degrees'); objAmountOfTime = document.getElementById('time-in-hmm'); } function setCalculationDefault () { calculationDefaultItem = 'distance-in-nm'; // option-group-value of the element that should be calculated by default document.calculation_form.calculation_group.value = calculationDefaultItem; // set input-field properties via css-class: border and background-color document.getElementById(calculationDefaultItem).className = "disabled"; document.getElementById(calculationDefaultItem).disabled = true; } function setConnotationHeadline () { var s = ''; var sHeadline = document.getElementById('connotations').innerHTML; var objCommonSpecialsPreparings = document.getElementById('common-specials-preparings'); var objCommonSpecialsBeforeTakeOff = document.getElementById('common-specials-before-take-off'); var objCommonSpecialsAfterTakeOff = document.getElementById('common-specials-after-take-off'); var objCommonSpecialsAutopilot = document.getElementById('common-specials-autopilot'); var objCommonSpecialsCutOff = document.getElementById('common-specials-cut-off'); // check additional common-specials for transforming the connotation-headline into a html-link if (objCommonSpecialsPreparings || objCommonSpecialsBeforeTakeOff || objCommonSpecialsAfterTakeOff || objCommonSpecialsAutopilot || objCommonSpecialsCutOff) sHeadline = '' + sHeadline + ''; // check additional common-specials for extending the connotations-headline if (objCommonSpecialsPreparings) s = s + ' / preparings'; if (objCommonSpecialsBeforeTakeOff) s = s + ' / < take-off'; if (objCommonSpecialsAfterTakeOff) s = s + ' / > take-off'; if (objCommonSpecialsAutopilot) s = s + ' / autopilot'; if (objCommonSpecialsCutOff) s = s + ' / cut-off'; // returning connotations-headline with html links if (s) document.getElementById('connotations').innerHTML = sHeadline + s; } function setConnotationHeadlineLinks (obj) { var clickedLinkText = obj.innerHTML; var connotations = document.getElementById('connotations'); for (var link=connotations.firstChild; link; link=link.nextSibling) { // loop through the html links inside the extended connotation headline, setting headline links and hiding/displaying according content if (link.tagName == 'A') { if (clickedLinkText == link.innerHTML) { link.style.color = 'black'; document.getElementById(link.name).style.display = 'block'; } else { link.style.color = 'grey'; document.getElementById(link.name).style.display = 'none'; } } } } function setFocusToCalculationElement () { // set focus to the calculation element as given in the ini-file document.getElementById('height-difference-in-ft').focus(); } function clearCssClassOfInputFields (currentCalculationItem) { clearCssClassOfInputField (currentCalculationItem, 'distance-in-nm'); clearCssClassOfInputField (currentCalculationItem, 'height-difference-in-ft'); clearCssClassOfInputField (currentCalculationItem, 'speed-in-kts'); clearCssClassOfInputField (currentCalculationItem, 'rate-in-ft-per-min'); } function clearCssClassOfInputField (currentCalculationItem, item) { if (currentCalculationItem != item) { document.getElementById (item).className = ''; document.getElementById (item).disabled = false; } } function calculateDefaultItem () { calculateItem ('distance-in-nm'); } function calculateItem (itemHtmlId) { switch (itemHtmlId) { case 'distance-in-nm': calculateDistance (); break; case 'height-difference-in-ft': calculateHeight (); break; case 'speed-in-kts': calculateSpeed (); break; case 'rate-in-ft-per-min': calculateRate (); break; default: calculateItem ('distance-in-nm'); } calculateDegrees (); calculateTime (); } function convertTimeToHMM (num) { num = parseInt (num); var hours = Math.floor (num / NUMBER_OF_MINUTES_IN_HOUR); var minutes = num % NUMBER_OF_MINUTES_IN_HOUR; minutes = minutes.toString (); return hours + ":" + minutes.padStart (2, '0'); } // CALCULATION FUNCTIONS function calculateDistance () { var distance = parseInt (objGroundSpeedInKts.value) * parseInt (objVerticalDistanceInFeet.value) / parseInt (objRateInFtPerMinute.value) / NUMBER_OF_MINUTES_IN_HOUR; if (Number.isInteger(distance)) objHorizontalDistanceInNauticMiles.value = distance; else { distance = distance.toFixed(1); objHorizontalDistanceInNauticMiles.value = distance; } } function calculateHeight () { var height = parseFloat (objHorizontalDistanceInNauticMiles.value) / parseInt (objGroundSpeedInKts.value) * parseInt (objRateInFtPerMinute.value) * NUMBER_OF_MINUTES_IN_HOUR; var heightInHundreds = height / 100; heightInHundreds = heightInHundreds.toFixed(0); height = heightInHundreds * 100; objVerticalDistanceInFeet.value = height; } function calculateSpeed () { var speed = parseFloat (objHorizontalDistanceInNauticMiles.value) / parseInt (objVerticalDistanceInFeet.value) * parseInt (objRateInFtPerMinute.value) * NUMBER_OF_MINUTES_IN_HOUR; objGroundSpeedInKts.value = speed.toFixed(0); } function calculateRate () { var rate = parseInt (objGroundSpeedInKts.value) / NUMBER_OF_MINUTES_IN_HOUR / parseFloat (objHorizontalDistanceInNauticMiles.value) * parseInt (objVerticalDistanceInFeet.value); objRateInFtPerMinute.value = rate.toFixed(0); } function calculateDegrees () { var horizontalDistance = parseFloat (objHorizontalDistanceInNauticMiles.value) * NAUTIC_MILE_IN_FEET; var verticalDistance = parseInt (objVerticalDistanceInFeet.value); var gradientInPercent = verticalDistance / horizontalDistance; var gradientInDegree = Math.atan (gradientInPercent) * 180 / Math.PI; objRateInDegrees.value = gradientInDegree.toFixed(1); } function calculateTime () { var horizontalDistance = parseFloat (objHorizontalDistanceInNauticMiles.value); var groundSpeed = parseInt (objGroundSpeedInKts.value); objAmountOfTime.value = convertTimeToHMM (horizontalDistance / groundSpeed * NUMBER_OF_MINUTES_IN_HOUR); }