VOID_Core:
[VOID.git] / VOID_Core.cs
blob:a/VOID_Core.cs -> blob:b/VOID_Core.cs
--- a/VOID_Core.cs
+++ b/VOID_Core.cs
@@ -1,34 +1,44 @@
+// VOID
 //
-//  VOID_Core.cs
+// VOID_Core.cs
 //
-//  Author:
-//       toadicus <>
+// Copyright © 2014, toadicus
+// All rights reserved.
 //
-//  Copyright (c) 2013 toadicus
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
 //
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
+// 1. Redistributions of source code must retain the above copyright notice,
+//    this list of conditions and the following disclaimer.
 //
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation and/or other
+//    materials provided with the distribution.
 //
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+//    to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// 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 KSP;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using KSP;
+using ToadicusTools;
 using UnityEngine;
-using Engineer.VesselSimulator;
 
 namespace VOID
 {
 	public class VOID_Core : VOID_Module, IVOID_Module
 	{
+		#region Singleton Members
 		/*
 		 * Static Members
 		 * */
@@ -60,16 +70,19 @@
 		public static void Reset()
 		{
 			_instance.StopGUI();
+			_instance.Dispose();
 			_instance = null;
 			_initialized = false;
 		}
-
-		public static double Constant_G = 6.674e-11;
+		#endregion
+
+		public static readonly double Constant_G = 6.674e-11;
+
 		/*
 		 * Fields
 		 * */
 		protected string VoidName = "VOID";
-		protected string VoidVersion = "0.9.21";
+		protected string VoidVersion;
 
 		protected bool _factoryReset = false;
 
@@ -127,6 +140,9 @@
 		protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f;
 		protected float _updateTimer = 0f;
 		protected string stringFrequency;
+
+		[AVOID_SaveValue("vesselSimActive")]
+		protected VOID_SaveValue<bool> vesselSimActive;
 
 		// Vessel Type Housekeeping
 		protected List<VesselType> _allVesselTypes = new List<VesselType>();
@@ -160,6 +176,8 @@
 		protected VOID_SaveValue<bool> _UseToolbarManager;
 		internal IButton ToolbarButton;
 
+		internal ApplicationLauncherButton AppLauncherButton;
+
 		/*
 		 * Properties
 		 * */
@@ -266,6 +284,18 @@
 			}
 		}
 
+		public Stage[] Stages
+		{
+			get;
+			protected set;
+		}
+
+		public Stage LastStage
+		{
+			get;
+			protected set;
+		}
+
 		protected IconState powerState
 		{
 			get
@@ -302,7 +332,7 @@
 		{
 			get
 			{
-				return _UseToolbarManager;
+				return _UseToolbarManager & ToolbarManager.ToolbarAvailable;
 			}
 			set
 			{
@@ -318,10 +348,24 @@
 				}
 				if (value == true)
 				{
+					if (this.AppLauncherButton != null)
+					{
+						ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
+						this.AppLauncherButton = null;
+					}
+
 					this.InitializeToolbarButton();
 				}
 
 				_UseToolbarManager.value = value;
+			}
+		}
+
+		protected virtual ApplicationLauncher.AppScenes appIconVisibleScenes
+		{
+			get
+			{
+				return ApplicationLauncher.AppScenes.FLIGHT;
 			}
 		}
 
@@ -351,9 +395,9 @@
 
 			if (!this.UseToolbarManager)
 			{
-				if (GUI.Button(VOIDIconPos, VOIDIconTexture, this.iconStyle) && this.VOIDIconLocked)
-				{
-					this.ToggleMainWindow();
+				if (this.AppLauncherButton == null)
+				{
+					this.InitializeAppLauncherButton();
 				}
 			}
 			else if (this.ToolbarButton == null)
@@ -369,7 +413,7 @@
 				_mainWindowPos = GUILayout.Window(
 					this.windowID,
 					_mainWindowPos,
-					this.VOIDMainWindow,
+					VOID_Tools.GetWindowHandler(this.VOIDMainWindow),
 					string.Join(" ", new string[] { this.VoidName, this.VoidVersion }),
 					GUILayout.Width(250),
 					GUILayout.Height(50)
@@ -390,7 +434,7 @@
 				_configWindowPos = GUILayout.Window(
 					this.windowID,
 					_configWindowPos,
-					this.VOIDConfigWindow,
+					VOID_Tools.GetWindowHandler(this.VOIDConfigWindow),
 					string.Join(" ", new string[] { this.VoidName, "Configuration" }),
 					GUILayout.Width(250),
 					GUILayout.Height(50)
@@ -405,7 +449,7 @@
 			}
 		}
 
-		public void OnGUI()
+		public virtual void OnGUI()
 		{
 			if (Event.current.type == EventType.Repaint)
 			{
@@ -459,15 +503,14 @@
 			}
 		}
 
-		public void Update()
+		public virtual void Update()
 		{
 			this.LoadBeforeUpdate();
 
-			if (this.vessel != null)
-			{
-				SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
-					Math.Pow(VOID_Core.Instance.vessel.Radius(), 2);
-				SimManager.Instance.TryStartSimulation();
+			if (this.vessel != null && this.vesselSimActive)
+			{
+				Tools.PostDebugMessage(this, "Updating SimManager.");
+				this.UpdateSimManager();
 			}
 
 			if (!this.guiRunning)
@@ -504,7 +547,7 @@
 			this._updateTimer += Time.deltaTime;
 		}
 
-		public void FixedUpdate()
+		public virtual void FixedUpdate()
 		{
 			bool newPowerState = this.powerAvailable;
 
@@ -613,6 +656,9 @@
 
 			this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available");
 
+			this.vesselSimActive.value = GUILayout.Toggle(this.vesselSimActive.value,
+				"Enable Engineering Calculations");
+
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 
 			GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
@@ -688,6 +734,41 @@
 			this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset");
 		}
 
+		protected void UpdateSimManager()
+		{
+			if (SimManager.ResultsReady())
+			{
+				Tools.PostDebugMessage(this, "VesselSimulator results ready, setting Stages.");
+
+				this.Stages = SimManager.Stages;
+
+				if (this.Stages != null)
+				{
+					this.LastStage = this.Stages.Last();
+				}
+
+				if (HighLogic.LoadedSceneIsEditor)
+				{
+					SimManager.Gravity = VOID_Data.KerbinGee;
+				}
+				else
+				{
+					double radius = this.vessel.Radius();
+					SimManager.Gravity = this.vessel.mainBody.gravParameter / (radius * radius);
+				}
+
+				SimManager.minSimTime = (long)(this.updatePeriod * 1000);
+
+				SimManager.TryStartSimulation();
+			}
+			#if DEBUG
+			else
+			{
+				Tools.PostDebugMessage(this, "VesselSimulator results not ready.");
+			}
+			#endif
+		}
+
 		protected void LoadModulesOfType<T>()
 		{
 			var types = AssemblyLoader.loadedAssemblies
@@ -858,6 +939,12 @@
 
 		protected void InitializeToolbarButton()
 		{
+			// Do nothing if (the Toolbar is not available.
+			if (!ToolbarManager.ToolbarAvailable)
+			{
+				return;
+			}
+
 			this.ToolbarButton = ToolbarManager.Instance.add(this.VoidName, "coreToggle");
 			this.ToolbarButton.Text = this.VoidName;
 			this.SetIconTexture(this.powerState | this.activeState);
@@ -871,6 +958,27 @@
 			};
 
 			Tools.PostDebugMessage(string.Format("{0}: Toolbar Button initialized.", this.GetType().Name));
+		}
+
+		protected void InitializeAppLauncherButton()
+		{
+			if (ApplicationLauncher.Ready)
+			{
+				this.AppLauncherButton = ApplicationLauncher.Instance.AddModApplication(
+					this.ToggleMainWindow, this.ToggleMainWindow,
+					this.appIconVisibleScenes,
+					this.VOIDIconTexture
+				);
+
+				Tools.PostDebugMessage(
+					this,
+					"AppLauncherButton initialized in {0}",
+					Enum.GetName(
+						typeof(GameScenes),
+						HighLogic.LoadedScene
+					)
+				);
+			}
 		}
 
 		protected void ToggleMainWindow()
@@ -907,7 +1015,12 @@
 				this.ToolbarButton.TexturePath = texturePath;
 			}
 
-			this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath, false);
+			this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false);
+
+			if (this.AppLauncherButton != null)
+			{
+				this.AppLauncherButton.SetTexture(VOIDIconTexture);
+			}
 		}
 
 		protected void CheckAndSave()
@@ -963,7 +1076,11 @@
 		{
 			this._Name = "VOID Core";
 
-			this._Active.value = true;
+			System.Version version = this.GetType().Assembly.GetName().Version;
+
+			this.VoidVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.MajorRevision);
+
+			this.toggleActive = true;
 
 			this._skinName = this.defaultSkin;
 			this._skinIdx = int.MinValue;
@@ -973,11 +1090,27 @@
 			this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_light";
 			this.VOIDIconOffActivePath = "VOID/Textures/void_icon_dark";
 
+			this.vesselSimActive = true;
+
 			this.UseToolbarManager = false;
 
 			this.LoadConfig();
 
 			this.SetIconTexture(this.powerState | this.activeState);
+		}
+
+		public virtual void Dispose()
+		{
+			if (this.AppLauncherButton != null)
+			{
+				ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
+				this.AppLauncherButton = null;
+			}
+			if (this.ToolbarButton != null)
+			{
+				this.ToolbarButton.Destroy();
+				this.ToolbarButton = null;
+			}
 		}
 
 		protected enum IconState
@@ -995,15 +1128,14 @@
 		{
 			get
 			{
-				return VOID_Core.Instance;
-			}
-		}
-
-		public static Engineer.VesselSimulator.SimManager simManager
-		{
-			get
-			{
-				return Engineer.VesselSimulator.SimManager.Instance;
+				if (HighLogic.LoadedSceneIsEditor)
+				{
+					return VOID_EditorCore.Instance;
+				}
+				else
+				{
+					return VOID_Core.Instance;
+				}
 			}
 		}
 
@@ -1011,9 +1143,16 @@
 		{
 			get
 			{
-				return core.Kerbin.gravParameter / Math.Pow(core.Kerbin.Radius, 2);
-			}
-		}
+				if (kerbinGee == default(double))
+				{
+					kerbinGee = core.Kerbin.gravParameter / (core.Kerbin.Radius * core.Kerbin.Radius);
+				}
+
+				return kerbinGee;
+			}
+		}
+
+		private static double kerbinGee;
 	}
 }