VOID_HUDAdvanced: NaN handling for burntime strvalues.
[VOID.git] / VOID_HUDAdvanced.cs
blob:a/VOID_HUDAdvanced.cs -> blob:b/VOID_HUDAdvanced.cs
--- a/VOID_HUDAdvanced.cs
+++ b/VOID_HUDAdvanced.cs
@@ -26,7 +26,7 @@
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-using Engineer.VesselSimulator;
+using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
 using System.Collections.Generic;
@@ -37,37 +37,33 @@
 
 namespace VOID
 {
-	public class VOID_HUDAdvanced : VOID_Module, IVOID_Module
+	public class VOID_HUDAdvanced : VOID_HUDModule, IVOID_Module
 	{
 		/*
 		 * Fields
 		 * */
 		protected VOID_HUD primaryHUD;
 
-		protected Rect leftHUDdefaultPos;
-		protected Rect rightHUDdefaultPos;
-
-		[AVOID_SaveValue("leftHUDPos")]
-		protected VOID_SaveValue<Rect> leftHUDPos;
-		[AVOID_SaveValue("rightHUDPos")]
-		protected VOID_SaveValue<Rect> rightHUDPos;
-
-		[AVOID_SaveValue("positionsLocked")]
-		protected VOID_SaveValue<bool> positionsLocked;
+		protected HUDWindow leftHUD;
+		protected HUDWindow rightHUD;
 
 		/*
 		 * Properties
 		 * */
-		public int ColorIndex
+		public override int ColorIndex
 		{
 			get
 			{
-				if (this.primaryHUD == null)
-				{
-					return 0;
-				}
-
-				return this.primaryHUD.ColorIndex;
+				if (this.primaryHUD != null)
+				{
+					return this.primaryHUD.ColorIndex;
+				}
+
+				return base.ColorIndex;
+			}
+			set
+			{
+				base.ColorIndex = value;
 			}
 		}
 
@@ -76,23 +72,28 @@
 		 * */
 		public VOID_HUDAdvanced() : base()
 		{
-			this._Name = "Advanced Heads-Up Display";
-
-			this._Active.value = true;
-
-			this.leftHUDdefaultPos = new Rect(
-				Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f,
-				Screen.height - 200f,
-				300f, 90f
-			);
-			this.leftHUDPos = new Rect(this.leftHUDdefaultPos);
-
-			this.rightHUDdefaultPos = new Rect(
-				Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f,
-				Screen.height - 200f,
-				300f, 90f
-			);
-			this.rightHUDPos = new Rect(this.rightHUDdefaultPos);
+			this.Name = "Advanced Heads-Up Display";
+
+			this.toggleActive = true;
+
+			this.leftHUD = new HUDWindow("leftHUD",
+				this.leftHUDWindow,
+				new Rect(
+					Screen.width * .5f - (float)GameSettings.UI_SIZE * .25f - 300f,
+					Screen.height - 200f,
+					300f, 90f)
+			);
+			this.Windows.Add(this.leftHUD);
+
+			this.rightHUD = new HUDWindow(
+				"rightHUD",
+				this.rightHUDWindow,
+				new Rect(
+					Screen.width * .5f + (float)GameSettings.UI_SIZE * .25f,
+					Screen.height - 200f,
+					300f, 90f)
+			);
+			this.Windows.Add(this.rightHUD);
 
 			this.positionsLocked = true;
 
@@ -105,9 +106,9 @@
 
 			leftHUD = new StringBuilder();
 
-			VOID_Core.Instance.LabelStyles["hud"].alignment = TextAnchor.UpperRight;
-
-			if (VOID_Core.Instance.powerAvailable)
+			VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
+
+			if (this.core.powerAvailable)
 			{
 				leftHUD.AppendFormat(
 					string.Intern("Mass: {0}\n"),
@@ -144,11 +145,16 @@
 			}
 			else
 			{
-				VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
+				VOID_Styles.labelHud.normal.textColor = Color.red;
 				leftHUD.Append(string.Intern("-- POWER LOST --"));
 			}
 
-			GUILayout.Label(leftHUD.ToString(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true));
+			GUILayout.Label(
+				leftHUD.ToString(),
+				VOID_Styles.labelHud,
+				GUILayout.ExpandWidth(true),
+				GUILayout.ExpandHeight(true)
+			);
 
 			if (!this.positionsLocked)
 			{
@@ -164,9 +170,9 @@
 
 			rightHUD = new StringBuilder();
 
-			VOID_Core.Instance.LabelStyles["hud"].alignment = TextAnchor.UpperLeft;
-
-			if (VOID_Core.Instance.powerAvailable)
+			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
+
+			if (this.core.powerAvailable)
 			{
 				rightHUD.AppendFormat(
 					"Burn Δv (Rem/Tot): {0} / {1}\n",
@@ -182,8 +188,8 @@
 				}
 
 				rightHUD.AppendFormat("Burn Time (Rem/Total): {0} / {1}\n",
-					VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnRemaining.Value),
-					VOID_Tools.ConvertInterval(VOID_Data.currentNodeBurnDuration.Value)
+					VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnRemaining.Value),
+					VOID_Tools.FormatInterval(VOID_Data.currentNodeBurnDuration.Value)
 				);
 
 				if (VOID_Data.burnTimeDoneAtNode.Value != string.Empty)
@@ -203,11 +209,16 @@
 			}
 			else
 			{
-				VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
+				VOID_Styles.labelHud.normal.textColor = Color.red;
 				rightHUD.Append(string.Intern("-- POWER LOST --"));
 			}
 
-			GUILayout.Label(rightHUD.ToString(), VOID_Core.Instance.LabelStyles["hud"], GUILayout.ExpandWidth(true));
+			GUILayout.Label(
+				rightHUD.ToString(),
+				VOID_Styles.labelHud,
+				GUILayout.ExpandWidth(true),
+				GUILayout.ExpandHeight(true)
+			);
 
 			if (!this.positionsLocked)
 			{
@@ -221,7 +232,7 @@
 		{
 			if (this.primaryHUD == null)
 			{
-				foreach (IVOID_Module module in VOID_Core.Instance.Modules)
+				foreach (IVOID_Module module in this.core.Modules)
 				{
 					if (module is VOID_HUD)
 					{
@@ -229,439 +240,32 @@
 					}
 				}
 			}
-			else
-			{
-				if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate))
-				{
-					SimManager.RequestSimulation();
-				}
-
-				this.leftHUDPos.value = GUI.Window(
-					VOID_Core.Instance.windowID,
-					this.leftHUDPos,
-					VOID_Tools.GetWindowHandler(this.leftHUDWindow),
-					GUIContent.none,
-					GUIStyle.none
-				);
-
-				if (VOID_Data.upcomingManeuverNodes > 0)
-				{
-					this.rightHUDPos.value = GUI.Window(
-						VOID_Core.Instance.windowID,
-						this.rightHUDPos,
-						VOID_Tools.GetWindowHandler(this.rightHUDWindow),
-						GUIContent.none,
-						GUIStyle.none
-					);
-				}
-			}
+
+			if (VOID_Data.upcomingManeuverNodes < 1 && this.Windows.Contains(this.rightHUD))
+			{
+				this.Windows.Remove(this.rightHUD);
+			}
+			else if (VOID_Data.upcomingManeuverNodes > 0 && !this.Windows.Contains(this.rightHUD))
+			{
+				this.Windows.Add(this.rightHUD);
+			}
+
+			base.DrawGUI();
 		}
 
 		public override void DrawConfigurables()
 		{
-			this.positionsLocked = GUILayout.Toggle(this.positionsLocked,
-				string.Intern("Lock Advanced HUD Positions"),
-				GUILayout.ExpandWidth(false));
-		}
-	}
-
-	public static partial class VOID_Data
-	{
-		public static int upcomingManeuverNodes
-		{
-			get
-			{
-				if (core.vessel == null ||
-					core.vessel.patchedConicSolver == null ||
-					core.vessel.patchedConicSolver.maneuverNodes == null
-				)
-				{
-					return 0;
-				}
-
-				return core.vessel.patchedConicSolver.maneuverNodes.Count;
-			}
-		}
-
-		public static readonly VOID_Vector3dValue vesselThrustOffset = new VOID_Vector3dValue(
-			"Thrust Offset",
-			delegate()
-		{
-			if (core.vessel == null)
-			{
-				return Vector3d.zero;
-			}
-
-			List<PartModule> engineModules = core.vessel.getModulesOfType<PartModule>();
-
-			Vector3d thrustPos = Vector3d.zero;
-			Vector3d thrustDir = Vector3d.zero;
-			float thrust = 0;
-
-			foreach (PartModule engine in engineModules)
-			{
-				float moduleThrust = 0;
-
-				switch (engine.moduleName)
-				{
-					case "ModuleEngines":
-					case "ModuleEnginesFX":
-						break;
-					default:
-						continue;
-				}
-
-				if (!engine.isEnabled)
-				{
-					continue;
-				}
-
-				CenterOfThrustQuery cotQuery = new CenterOfThrustQuery();
-
-				if (engine is ModuleEngines)
-				{
-					ModuleEngines engineModule = engine as ModuleEngines;
-
-					moduleThrust = engineModule.finalThrust;
-
-					engineModule.OnCenterOfThrustQuery(cotQuery);
-				}
-				else // engine is ModuleEnginesFX
-				{
-					ModuleEnginesFX engineFXModule = engine as ModuleEnginesFX;
-
-					moduleThrust = engineFXModule.finalThrust;
-
-					engineFXModule.OnCenterOfThrustQuery(cotQuery);
-				}
-
-				if (moduleThrust != 0d)
-				{
-					cotQuery.thrust = moduleThrust;
-				}
-
-				thrustPos += cotQuery.pos * cotQuery.thrust;
-				thrustDir += cotQuery.dir * cotQuery.thrust;
-				thrust += cotQuery.thrust;
-			}
-
-			if (thrust != 0)
-			{
-				thrustPos /= thrust;
-				thrustDir /= thrust;
-			}
-
-			Transform vesselTransform = core.vessel.transform;
-
-			thrustPos = vesselTransform.InverseTransformPoint(thrustPos);
-			thrustDir = vesselTransform.InverseTransformDirection(thrustDir);
-
-			Vector3d thrustOffset = VectorTools.PointDistanceToLine(
-				thrustPos, thrustDir.normalized, core.vessel.findLocalCenterOfMass());
-
-			Tools.PostDebugMessage(typeof(VOID_Data), "vesselThrustOffset:\n" +
-				"\tthrustPos: {0}\n" +
-				"\tthrustDir: {1}\n" +
-				"\tthrustOffset: {2}\n" +
-				"\tvessel.CoM: {3}",
-				thrustPos,
-				thrustDir.normalized,
-				thrustOffset,
-				core.vessel.findWorldCenterOfMass()
-			);
-
-			return thrustOffset;
-		},
-			"m"
-		);
-
-		public static readonly VOID_DoubleValue vesselAccel = new VOID_DoubleValue(
-			"Acceleration",
-			() => geeForce * KerbinGee,
-			"m/s"
-		);
-
-		public static readonly VOID_IntValue vesselCrewCount = new VOID_IntValue(
-			"Crew Onboard",
-			delegate()
-			{
-				if (core.vessel != null)
-				{
-					return core.vessel.GetCrewCount();
-				}
-				else
-				{
-					return 0;
-				}
-			},
-			""
-		);
-
-		public static readonly VOID_IntValue vesselCrewCapacity = new VOID_IntValue(
-			"Crew Capacity",
-			delegate()
-		{
-			if (core.vessel != null)
-			{
-				return core.vessel.GetCrewCapacity();
-			}
-			else
-			{
-				return 0;
-			}
-		},
-			""
-		);
-
-		public static readonly VOID_DoubleValue vesselAngularVelocity = new VOID_DoubleValue(
-			"Angular Velocity",
-			delegate()
-		{
-			if (core.vessel != null)
-			{
-				return core.vessel.angularVelocity.magnitude;
-			}
-			else
-			{
-				return double.NaN;
-			}
-		},
-			"rad/s"
-		);
-
-		public static readonly VOID_DoubleValue stageNominalThrust = new VOID_DoubleValue(
-			"Nominal Stage Thrust",
-			delegate()
-		{
-			if (SimManager.LastStage == null)
-			{
-				return double.NaN;
-			}
-
-			if (SimManager.LastStage.actualThrust == 0d)
-			{
-				return SimManager.LastStage.thrust;
-			}
-			else
-			{
-				return SimManager.LastStage.actualThrust;
-			}
-		},
-			"kN"
-		);
-
-		public static readonly VOID_DoubleValue stageMassFlow = new VOID_DoubleValue(
-			"Stage Mass Flow",
-			delegate()
-			{
-				if (SimManager.LastStage == null)
-				{
-					return double.NaN;
-				}
-
-			double stageIsp = SimManager.LastStage.isp;
-			double stageThrust = stageNominalThrust;
-
-			Tools.PostDebugMessage(typeof(VOID_Data), "calculating stageMassFlow from:\n" +
-				"\tstageIsp: {0}\n" +
-				"\tstageThrust: {1}\n" +
-				"\tKerbinGee: {2}\n",
-				stageIsp,
-				stageThrust,
-				KerbinGee
-			);
-
-				return stageThrust / (stageIsp * KerbinGee);
-			},
-			"Mg/s"
-		);
-
-		public static readonly VOID_DoubleValue currManeuverDeltaV = new VOID_DoubleValue(
-			"Current Maneuver Delta-V",
-			delegate()
-			{
-				if (upcomingManeuverNodes > 0)
-				{
-				return core.vessel.patchedConicSolver.maneuverNodes[0].DeltaV.magnitude;
-				}
-				else
-				{
-					return double.NaN;
-				}
-			},
-			"m/s"
-		);
-
-		public static readonly VOID_DoubleValue currManeuverDVRemaining = new VOID_DoubleValue(
-			"Remaining Maneuver Delta-V",
-			delegate()
-			{
-				if (upcomingManeuverNodes > 0)
-				{
-					return core.vessel.patchedConicSolver.maneuverNodes[0].GetBurnVector(core.vessel.orbit).magnitude;
-				}
-				else
-				{
-					return double.NaN;
-				}
-			},
-			"m/s"
-		);
-
-		public static readonly VOID_DoubleValue nextManeuverDeltaV = new VOID_DoubleValue(
-			"Current Maneuver Delta-V",
-			delegate()
-		{
-			if (upcomingManeuverNodes > 1)
-			{
-				return core.vessel.patchedConicSolver.maneuverNodes[1].DeltaV.magnitude;
-			}
-			else
-			{
-				return double.NaN;
-			}
-		},
-			"m/s"
-		);
-
-		public static readonly VOID_DoubleValue currentNodeBurnDuration = new VOID_DoubleValue(
-			"Total Burn Time",
-			delegate()
-			{
-				if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
-				{
-					return double.NaN;
-				}
-			    
-				double stageThrust = stageNominalThrust;
-
-				return burnTime(currManeuverDeltaV.Value, totalMass, stageMassFlow, stageThrust);
-			},
-			"s"
-		);
-
-		public static readonly VOID_DoubleValue currentNodeBurnRemaining = new VOID_DoubleValue(
-			"Burn Time Remaining",
-			delegate()
-			{
-				if (SimManager.LastStage == null || currManeuverDVRemaining == double.NaN)
-				{
-					return double.NaN;
-				}
-
-				double stageThrust = stageNominalThrust;
-
-				return burnTime(currManeuverDVRemaining, totalMass, stageMassFlow, stageThrust);
-			},
-			"s"
-		);
-
-		public static readonly VOID_DoubleValue currentNodeHalfBurnDuration = new VOID_DoubleValue(
-			"Half Burn Time",
-			delegate()
-		{
-			if (SimManager.LastStage == null || currManeuverDeltaV.Value == double.NaN)
-			{
-				return double.NaN;
-			}
-
-			double stageThrust = stageNominalThrust;
-
-			return burnTime(currManeuverDeltaV.Value / 2d, totalMass, stageMassFlow, stageThrust);
-		},
-			"s"
-		);
-
-		public static readonly VOID_StrValue burnTimeDoneAtNode = new VOID_StrValue(
-			"Full burn time to be half done at node",
-			delegate()
-		{
-			if (SimManager.LastStage == null && upcomingManeuverNodes < 1)
-			{
-				return "N/A";
-			}
-
-			ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0];
-
-			if ((node.UT - Planetarium.GetUniversalTime()) < 0)
-			{
-				return string.Empty;
-			}
-
-			double interval = (node.UT - currentNodeBurnDuration) - Planetarium.GetUniversalTime();
-
-			if (double.IsNaN(interval))
-			{
-				return string.Intern("NaN");
-			}
-
-			int sign = Math.Sign(interval);
-			interval = Math.Abs(interval);
-
-			string format;
-
-			if (sign >= 0)
-			{
-				format = string.Intern("T - {0}");
-			}
-			else
-			{
-				format = string.Intern("T + {0}");
-			}
-
-			return string.Format(format, VOID_Tools.ConvertInterval(interval));
-		}
-		);
-
-		public static readonly VOID_StrValue burnTimeHalfDoneAtNode = new VOID_StrValue(
-			"Full burn time to be half done at node",
-			delegate()
-			{
-			if (SimManager.LastStage == null && upcomingManeuverNodes < 1)
-			{
-				return "N/A";
-			}
-
-			ManeuverNode node = core.vessel.patchedConicSolver.maneuverNodes[0];
-
-			if ((node.UT - Planetarium.GetUniversalTime()) < 0)
-			{
-				return string.Empty;
-			}
-
-			double interval = (node.UT - currentNodeHalfBurnDuration) - Planetarium.GetUniversalTime();
-
-			int sign = Math.Sign(interval);
-			interval = Math.Abs(interval);
-
-			string format;
-
-			if (sign >= 0)
-			{
-				format = string.Intern("T - {0}");
-			}
-			else
-			{
-				format = string.Intern("T + {0}");
-			}
-
-			return string.Format(format, VOID_Tools.ConvertInterval(interval));
-			}
-		);
-
-		private static double burnTime(double deltaV, double initialMass, double massFlow, double thrust)
-		{
-			Tools.PostDebugMessage(typeof(VOID_Data), "calculating burnTime from:\n" +
-				"\tdeltaV: {0}\n" +
-				"\tinitialMass: {1}\n" +
-				"\tmassFlow: {2}\n" +
-				"\tthrust: {3}\n",
-				deltaV,
-				initialMass,
-				massFlow,
-				thrust
-			);
-			return initialMass / massFlow * (Math.Exp(deltaV * massFlow / thrust) - 1d);
+			base.DrawConfigurables();
+
+			if (GUILayout.Button(string.Intern("Reset Advanced HUD Positions"), GUILayout.ExpandWidth(false)))
+			{
+				foreach (HUDWindow window in this.Windows)
+				{
+					window.WindowPos = new Rect(window.defaultWindowPos);
+				}
+			}
+
+			this.positionsLocked = GUITools.Toggle(this.positionsLocked, string.Intern("Lock Advanced HUD Positions"));
 		}
 	}
 }