From 7cbba48fbc8456d3242b78f1c6c2da4f85407b64 Mon Sep 17 00:00:00 2001
From: Matthew Maring <56924612+hayden2000@users.noreply.github.com>
Date: Mon, 30 Mar 2020 17:11:32 -0400
Subject: [PATCH] Clean-up PROG page, add CRZ functionality

---
 Models/Instruments/MCDU/MCDU.nas     | 49 +++++++++++++++++++-------
 Models/Instruments/MCDU/res/mcdu.svg | 51 +++++++++++++++++++++++-----
 Nasal/MCDU/INITA.nas                 |  1 +
 Nasal/MCDU/MCDU.nas                  |  9 +++++
 Nasal/MCDU/PROGCLB.nas               | 17 ++++++++--
 Nasal/MCDU/PROGCRZ.nas               | 17 ++++++++--
 Nasal/MCDU/PROGTO.nas                | 19 +++++++++--
 7 files changed, 137 insertions(+), 26 deletions(-)

diff --git a/Models/Instruments/MCDU/MCDU.nas b/Models/Instruments/MCDU/MCDU.nas
index 4b0cd88d..0cbb0e6a 100644
--- a/Models/Instruments/MCDU/MCDU.nas
+++ b/Models/Instruments/MCDU/MCDU.nas
@@ -120,6 +120,9 @@ var fob = props.globals.getNode("FMGC/internal/fob", 1);
 var gw = props.globals.getNode("FMGC/internal/gw", 1);
 var cg = props.globals.getNode("FMGC/internal/cg", 1);
 
+# PROG
+var cruiseFL_prog = props.globals.getNode("FMGC/internal/cruise-fl-prog", 1);
+
 # PERF
 var altitude = props.globals.getNode("instrumentation/altimeter/indicated-altitude-ft", 1);
 var vs1g = props.globals.getNode("FMGC/internal/vs1g", 1);
@@ -245,7 +248,7 @@ var canvas_MCDU_base = {
 		"Simple_L1_Arrow","Simple_L2_Arrow","Simple_L3_Arrow","Simple_L4_Arrow","Simple_L5_Arrow","Simple_L6_Arrow","Simple_R1","Simple_R2","Simple_R3","Simple_R4","Simple_R5","Simple_R6","Simple_R1S","Simple_R2S","Simple_R3S","Simple_R4S","Simple_R5S",
 		"Simple_R6S","Simple_R1_Arrow","Simple_R2_Arrow","Simple_R3_Arrow","Simple_R4_Arrow","Simple_R5_Arrow","Simple_R6_Arrow","Simple_C1","Simple_C2","Simple_C3","Simple_C4","Simple_C5","Simple_C6","Simple_C1S","Simple_C2S","Simple_C3S","Simple_C4S",
 		"Simple_C5S","Simple_C6S","INITA","INITA_CoRoute","INITA_FltNbr","INITA_CostIndex","INITA_CruiseFLTemp","INITA_FromTo","INITA_InitRequest","INITA_AlignIRS","INITB","INITB_ZFWCG","INITB_ZFW","INITB_ZFW_S","INITB_Block","FUELPRED","FUELPRED_ZFW","FUELPRED_ZFWCG","FUELPRED_ZFW_S",
-		"PERFTO","PERFTO_V1","PERFTO_VR","PERFTO_V2","PERFTO_FE","PERFTO_SE","PERFTO_OE","PERFAPPR","PERFAPPR_FE","PERFAPPR_SE","PERFAPPR_OE","PERFAPPR_LDG_3","PERFAPPR_LDG_F","PERFGA","PERFGA_FE","PERFGA_SE","PERFGA_OE"];
+		"PROG","PROG_UPDATE","PERFTO","PERFTO_V1","PERFTO_VR","PERFTO_V2","PERFTO_FE","PERFTO_SE","PERFTO_OE","PERFAPPR","PERFAPPR_FE","PERFAPPR_SE","PERFAPPR_OE","PERFAPPR_LDG_3","PERFAPPR_LDG_F","PERFGA","PERFGA_FE","PERFGA_SE","PERFGA_OE"];
 	},
 	update: func() {
 		if (ac1.getValue() >= 110 and mcdu1_lgt.getValue() > 0.01) {
@@ -270,6 +273,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -327,6 +331,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -383,6 +388,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -437,6 +443,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -496,6 +503,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -557,6 +565,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -670,6 +679,7 @@ var canvas_MCDU_base = {
 				me["INITA"].show();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -814,6 +824,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -957,6 +968,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -1006,6 +1018,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].show();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -1135,6 +1148,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].show();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -1279,6 +1293,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].show();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -1329,7 +1344,7 @@ var canvas_MCDU_base = {
 				if (page == "PROGCRZ") {
 					me.showLeftS(0, 0, -1, 0, 0, 0);
 					me.showCenterS(0, 0, 1, 0, 0, 0);
-					me.showRight(0, 0, 1, 0, 0, 0);
+					#me.showRight(0, 0, 1, 0, 0, 0); #Add when implement cruise phase
 					me.fontLeft(0, 0, default, 0, 0, 0);
 				} else if (page == "PROGDES") {
 					me.showRight(0, 1, 0, 0, 0, 0);
@@ -1355,36 +1370,42 @@ var canvas_MCDU_base = {
 			}
 			
 			if (cruiseSet.getValue() == 1 and page != "PROGDES") {
-				me["Simple_L1"].setText(sprintf("%s", "FL" ~ cruiseFL.getValue()));
+				if (getprop("it-autoflight/input/alt") > cruiseFL_prog.getValue() * 100) {
+					me["Simple_L1"].setText(sprintf("%s", "FL" ~ getprop("it-autoflight/input/alt") / 100));
+				} else {
+					me["Simple_L1"].setText(sprintf("%s", "FL" ~ cruiseFL_prog.getValue()));
+				}
 			} else {
 				me["Simple_L1"].setText("----");
 			}
 			me["Simple_L2"].setText(" REPORT");
 			if (page == "PROGCRZ") {
-				me["Simple_L3"].setText("-----.--/-----.--");
-				me["Simple_R3"].setText("AGN *");
+				me["Simple_L3"].setText(" -----.--/-----.--");
+				#me["Simple_R3"].setText("AGN *"); #Add when implement cruise phase
+				me["PROG_UPDATE"].hide();
 			} else {
+				me["PROG_UPDATE"].show();
 				me["Simple_L3"].setText("  [    ]");
 			}
-			me["Simple_L4"].setText("---g/----");
+			me["Simple_L4"].setText(" ---g /----.-");
 			me["Simple_L5"].setText(" GPS");
 			me["Simple_L6"].setText("----");
-			me["Simple_L1S"].setText("CRZ");
-			me["Simple_L3S"].setText("UPDATE AT");
-			me["Simple_L4S"].setText("BRG/DIST");
-			me["Simple_L5S"].setText("PREDICTIVE");
+			me["Simple_L1S"].setText(" CRZ");
+			me["Simple_L3S"].setText(" UPDATE AT");
+			me["Simple_L4S"].setText("  BRG /DIST");
+			me["Simple_L5S"].setText(" PREDICTIVE");
 			me["Simple_L6S"].setText("REQUIRED");
 			me["Simple_R1"].setText("FL398");
 			me["Simple_R2"].setText("VDEV = + 750 FT");
 			me["Simple_R4"].setText("[    ]");
 			me["Simple_R5"].setText("GPS PRIMARY");
 			me["Simple_R6"].setText("----");
-			me["Simple_R1S"].setText("REC MAX");
+			me["Simple_R1S"].setText("REC MAX ");
 			me["Simple_R6S"].setText("ESTIMATED");
 			me["Simple_C1"].setText("----");
 			me["Simple_C1S"].setText("OPT");
 			me["Simple_C3S"].setText("CONFIRM UPDATE AT");
-			me["Simple_C4"].setText("TO");
+			me["Simple_C4"].setText("   TO");
 			me["Simple_C6S"].setText("ACCUR");
 			me["Simple_C6"].setText("HIGH");
 			
@@ -1395,6 +1416,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].show();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
@@ -1569,6 +1591,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].show();
 				me["PERFGA"].hide();
@@ -1737,6 +1760,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].show();
@@ -1830,6 +1854,7 @@ var canvas_MCDU_base = {
 				me["INITA"].hide();
 				me["INITB"].hide();
 				me["FUELPRED"].hide();
+				me["PROG"].hide();
 				me["PERFTO"].hide();
 				me["PERFAPPR"].hide();
 				me["PERFGA"].hide();
diff --git a/Models/Instruments/MCDU/res/mcdu.svg b/Models/Instruments/MCDU/res/mcdu.svg
index 1b0dc910..bd05ae25 100644
--- a/Models/Instruments/MCDU/res/mcdu.svg
+++ b/Models/Instruments/MCDU/res/mcdu.svg
@@ -33,17 +33,17 @@
      units="px"
      inkscape:snap-global="false"
      showguides="false"
-     inkscape:current-layer="PERFTO"
-     inkscape:window-maximized="1"
+     inkscape:current-layer="PROG"
+     inkscape:window-maximized="0"
      inkscape:window-y="23"
-     inkscape:window-x="0"
-     inkscape:cy="754.80546"
-     inkscape:cx="382.60729"
-     inkscape:zoom="0.34305232"
+     inkscape:window-x="59"
+     inkscape:cy="508.76833"
+     inkscape:cx="72.164029"
+     inkscape:zoom="8.0885693"
      showgrid="true"
      id="namedview371"
-     inkscape:window-height="730"
-     inkscape:window-width="1280"
+     inkscape:window-height="1035"
+     inkscape:window-width="1920"
      inkscape:pageshadow="2"
      inkscape:pageopacity="1"
      guidetolerance="20"
@@ -1855,6 +1855,41 @@
          sodipodi:nodetypes="cc" />
     </g>
   </g>
+  <g
+     inkscape:label="PROG"
+     id="PROG"
+     inkscape:groupmode="layer">
+    <g
+       style="stroke:#179ab7;stroke-opacity:1"
+       id="PROG_UPDATE"
+       inkscape:label="#g4324"
+       transform="matrix(1.0807111,0,0,1.0807111,-1029.7034,94.94738)">
+      <path
+         sodipodi:nodetypes="cc"
+         inkscape:connector-curvature="0"
+         id="path4376-0-3"
+         d="M 998.71909,284.70793 H 970.18944"
+         style="fill:none;stroke:#179ab7;stroke-width:4.08;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="fill:none;stroke:#179ab7;stroke-width:4.08;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 994.54102,294.79468 -20.17351,-20.1735"
+         id="path4378-3-8"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+      <path
+         sodipodi:nodetypes="cc"
+         inkscape:connector-curvature="0"
+         id="path4380-9-0"
+         d="m 984.45427,298.97275 -10e-6,-28.52964"
+         style="fill:none;stroke:#179ab7;stroke-width:4.08;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         style="fill:none;stroke:#179ab7;stroke-width:4.08;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 974.36752,294.79468 20.17349,-20.1735"
+         id="path4382-8-2"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cc" />
+    </g>
+  </g>
   <g
      inkscape:label="PERFGA"
      id="PERFGA"
diff --git a/Nasal/MCDU/INITA.nas b/Nasal/MCDU/INITA.nas
index d0d38114..644d8643 100644
--- a/Nasal/MCDU/INITA.nas
+++ b/Nasal/MCDU/INITA.nas
@@ -84,6 +84,7 @@ var initInputA = func(key, i) {
 				} else if (crz > 0 and crz <= 430 and temp >= -100 and temp < 100) {
 					setprop("FMGC/internal/cruise-ft", crz * 100);
 					setprop("FMGC/internal/cruise-fl", crz);
+					setprop("FMGC/internal/cruise-fl-prog", crz);
 					setprop("FMGC/internal/cruise-lvl-set", 1);
 					setprop("FMGC/internal/cruise-temp", temp);
 					setprop("MCDU[" ~ i ~ "]/scratchpad", "");
diff --git a/Nasal/MCDU/MCDU.nas b/Nasal/MCDU/MCDU.nas
index bd507e61..d3680e50 100644
--- a/Nasal/MCDU/MCDU.nas
+++ b/Nasal/MCDU/MCDU.nas
@@ -105,6 +105,9 @@ var MCDU_reset = func(i) {
 	setprop("FMGC/internal/gw", 0);
 	setprop("FMGC/internal/cg", 0);
 	
+	# PROG
+	setprop("FMGC/internal/cruise-fl-prog", 100);
+	
 	# PERF
 	setprop("FMGC/internal/vs1g", 0);
 	
@@ -186,6 +189,12 @@ var lskbutton = func(btn, i) {
 			}
 		} else if (getprop("MCDU[" ~ i ~ "]/page") == "INITB") {
 			initInputB("L1",i);
+		} else if (getprop("MCDU[" ~ i ~ "]/page") == "PROGTO") {
+			progTOInput("L1",i);
+		} else if (getprop("MCDU[" ~ i ~ "]/page") == "PROGCLB") {
+			progCLBInput("L1",i);
+		} else if (getprop("MCDU[" ~ i ~ "]/page") == "PROGCRZ") {
+			progCRZInput("L1",i);
 		} else if (getprop("MCDU[" ~ i ~ "]/page") == "PERFTO") {
 			perfTOInput("L1",i);
 		} else if (getprop("MCDU[" ~ i ~ "]/page") == "PERFAPPR") {
diff --git a/Nasal/MCDU/PROGCLB.nas b/Nasal/MCDU/PROGCLB.nas
index 5bba0af7..0ceb1042 100644
--- a/Nasal/MCDU/PROGCLB.nas
+++ b/Nasal/MCDU/PROGCLB.nas
@@ -1,7 +1,20 @@
 # Copyright (c) 2020 Matthew Maring (hayden2000)
 
 var progCLBInput = func(key, i) {
-	if (key == "L6") {
-		setprop("MCDU[" ~ i ~ "]/page", "INITA");
+	var scratchpad = getprop("MCDU[" ~ i ~ "]/scratchpad");
+	if (key == "L1") {
+		if (scratchpad == "CLR") {
+			setprop("FMGC/internal/cruise-fl-prog", getprop("FMGC/internal/cruise-fl"));
+		} else if (int(scratchpad) != nil) {
+			var crzs = size(scratchpad);
+			if (crzs >= 1 and crzs <= 3 and scratchpad > 0 and scratchpad <= 430 and altSet.getValue() <= scratchpad * 100) {
+				setprop("FMGC/internal/cruise-fl-prog", scratchpad);
+				setprop("MCDU[" ~ i ~ "]/scratchpad", "");
+			} else {
+				notAllowed(i);
+			}
+		} else {
+			notAllowed(i);
+		}
 	}
 }
diff --git a/Nasal/MCDU/PROGCRZ.nas b/Nasal/MCDU/PROGCRZ.nas
index 0f3c535e..a357a1b9 100644
--- a/Nasal/MCDU/PROGCRZ.nas
+++ b/Nasal/MCDU/PROGCRZ.nas
@@ -1,7 +1,20 @@
 # Copyright (c) 2020 Matthew Maring (hayden2000)
 
 var progCRZInput = func(key, i) {
-	if (key == "L6") {
-		setprop("MCDU[" ~ i ~ "]/page", "INITA");
+	var scratchpad = getprop("MCDU[" ~ i ~ "]/scratchpad");
+	if (key == "L1") {
+		if (scratchpad == "CLR") {
+			setprop("FMGC/internal/cruise-fl-prog", getprop("FMGC/internal/cruise-fl"));
+		} else if (int(scratchpad) != nil) {
+			var crzs = size(scratchpad);
+			if (crzs >= 1 and crzs <= 3 and scratchpad > 0 and scratchpad <= 430 and altSet.getValue() <= scratchpad * 100) {
+				setprop("FMGC/internal/cruise-fl-prog", scratchpad);
+				setprop("MCDU[" ~ i ~ "]/scratchpad", "");
+			} else {
+				notAllowed(i);
+			}
+		} else {
+			notAllowed(i);
+		}
 	}
 }
diff --git a/Nasal/MCDU/PROGTO.nas b/Nasal/MCDU/PROGTO.nas
index 1c730966..e00e38fa 100644
--- a/Nasal/MCDU/PROGTO.nas
+++ b/Nasal/MCDU/PROGTO.nas
@@ -1,7 +1,22 @@
 # Copyright (c) 2020 Matthew Maring (hayden2000)
 
+var altSet = props.globals.getNode("it-autoflight/input/alt", 1);
+
 var progTOInput = func(key, i) {
-	if (key == "L6") {
-		setprop("MCDU[" ~ i ~ "]/page", "INITA");
+	var scratchpad = getprop("MCDU[" ~ i ~ "]/scratchpad");
+	if (key == "L1") {
+		if (scratchpad == "CLR") {
+			setprop("FMGC/internal/cruise-fl-prog", getprop("FMGC/internal/cruise-fl"));
+		} else if (int(scratchpad) != nil) {
+			var crzs = size(scratchpad);
+			if (crzs >= 1 and crzs <= 3 and scratchpad > 0 and scratchpad <= 430 and altSet.getValue() <= scratchpad * 100) {
+				setprop("FMGC/internal/cruise-fl-prog", scratchpad);
+				setprop("MCDU[" ~ i ~ "]/scratchpad", "");
+			} else {
+				notAllowed(i);
+			}
+		} else {
+			notAllowed(i);
+		}
 	}
 }