Added VOID_SurfAtmo and tweaked some loading stuff or something.
[VOID.git] / VOID_Core.cs
blob:a/VOID_Core.cs -> blob:b/VOID_Core.cs
// //
// VOID_Core.cs // VOID_Core.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;  
using KSP; using KSP;
using UnityEngine; using UnityEngine;
  using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
public class VOID_Core : VOID_Module, IVOID_Module public class VOID_Core : VOID_Module, IVOID_Module
{ {
/* /*
* Static Members * Static Members
* */ * */
protected static bool _initialized = false; protected static bool _initialized = false;
public static bool Initialized public static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected static VOID_Core _instance; protected static VOID_Core _instance;
public static VOID_Core Instance public static VOID_Core Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_Core(); _instance = new VOID_Core();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
  public static void Reset()
  {
  _instance.StopGUI();
  _instance = null;
  _initialized = false;
  }
   
public static double Constant_G = 6.674e-11; public static double Constant_G = 6.674e-11;
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion = "0.9.9"; protected string VoidVersion = "0.9.14";
   
  protected bool _factoryReset = false;
   
[AVOID_SaveValue("configValue")] [AVOID_SaveValue("configValue")]
protected VOID_SaveValue<int> configVersion = 1; protected VOID_SaveValue<int> configVersion = 1;
   
protected List<IVOID_Module> _modules = new List<IVOID_Module>(); protected List<IVOID_Module> _modules = new List<IVOID_Module>();
protected bool _modulesLoaded = false; protected bool _modulesLoaded = false;
   
protected List<Callback> _configurableCallbacks = new List<Callback>();  
   
[AVOID_SaveValue("mainWindowPos")] [AVOID_SaveValue("mainWindowPos")]
protected VOID_SaveValue<Rect> mainWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f); protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f);
   
[AVOID_SaveValue("mainGuiMinimized")] [AVOID_SaveValue("mainGuiMinimized")]
protected VOID_SaveValue<bool> mainGuiMinimized = false; protected VOID_SaveValue<bool> mainGuiMinimized = false;
   
[AVOID_SaveValue("configWindowPos")] [AVOID_SaveValue("configWindowPos")]
protected VOID_SaveValue<Rect> configWindowPos = new Rect(Screen.width / 2, Screen.height /2, 10f, 10f); protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f);
   
[AVOID_SaveValue("configWindowMinimized")] [AVOID_SaveValue("configWindowMinimized")]
protected VOID_SaveValue<bool> configWindowMinimized = true; protected VOID_SaveValue<bool> configWindowMinimized = true;
   
[AVOID_SaveValue("VOIDIconPos")] [AVOID_SaveValue("VOIDIconPos")]
protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f); protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f);
protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false); protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnPath = "VOID/Textures/void_icon_on"; protected string VOIDIconOnPath = "VOID/Textures/void_icon_on";
protected string VOIDIconOffPath = "VOID/Textures/void_icon_off"; protected string VOIDIconOffPath = "VOID/Textures/void_icon_off";
  protected bool VOIDIconLocked = true;
   
protected int windowBaseID = -96518722; protected int windowBaseID = -96518722;
protected int _windowID = 0; protected int _windowID = 0;
   
protected bool GUIStylesLoaded = false; protected bool GUIStylesLoaded = false;
   
protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>(); protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>();
   
[AVOID_SaveValue("togglePower")] [AVOID_SaveValue("togglePower")]
public VOID_SaveValue<bool> togglePower = true; public VOID_SaveValue<bool> togglePower = true;
   
public bool powerAvailable = true; public bool powerAvailable = true;
   
[AVOID_SaveValue("consumeResource")] [AVOID_SaveValue("consumeResource")]
protected VOID_SaveValue<bool> consumeResource = false; protected VOID_SaveValue<bool> consumeResource = false;
   
[AVOID_SaveValue("resourceName")] [AVOID_SaveValue("resourceName")]
protected VOID_SaveValue<string> resourceName = "ElectricCharge"; protected VOID_SaveValue<string> resourceName = "ElectricCharge";
   
[AVOID_SaveValue("resourceRate")] [AVOID_SaveValue("resourceRate")]
protected VOID_SaveValue<float> resourceRate = 0.2f; protected VOID_SaveValue<float> resourceRate = 0.2f;
   
  [AVOID_SaveValue("updatePeriod")]
  protected VOID_SaveValue<double> _updatePeriod = 1001f/15000f;
  protected float _updateTimer = 0f;
  protected string stringFrequency;
   
  // Celestial Body Housekeeping
  protected List<CelestialBody> _allBodies = new List<CelestialBody>();
  protected bool bodiesLoaded = false;
   
  // Vessel Type Housekeeping
  protected List<VesselType> _allVesselTypes = new List<VesselType>();
  protected bool vesselTypesLoaded = false;
   
public float saveTimer = 0; public float saveTimer = 0;
   
protected string defaultSkin = "KSP window 2"; [AVOID_SaveValue("defaultSkin")]
protected VOID_SaveValue<string> _skin; protected VOID_SaveValue<string> defaultSkin = "KSP window 2";
  protected int _skinIdx = int.MinValue;
  protected List<GUISkin> skin_list;
  protected string[] forbiddenSkins =
  {
  "PlaqueDialogSkin",
  "FlagBrowserSkin",
  "SSUITextAreaDefault",
  "ExperimentsDialogSkin",
  "ExpRecoveryDialogSkin",
  "KSP window 5",
  "KSP window 6"
  };
  protected bool skinsLoaded = false;
   
public bool configDirty; public bool configDirty;
   
/* /*
* Properties * Properties
* */ * */
  public bool factoryReset
  {
  get
  {
  return this._factoryReset;
  }
  }
   
public List<IVOID_Module> Modules public List<IVOID_Module> Modules
{ {
get get
{ {
return this._modules; return this._modules;
} }
} }
   
public GUISkin Skin public GUISkin Skin
{ {
get get
{ {
if (this._skin == null) if (this.skin_list == null || this._skinIdx < 0 || this._skinIdx > this.skin_list.Count)
{ {
this._skin = this.defaultSkin; return AssetBase.GetGUISkin(this.defaultSkin);
} }
return AssetBase.GetGUISkin(this._skin); return this.skin_list[this._skinIdx];
} }
} }
   
public int windowID public int windowID
{ {
get get
{ {
if (this._windowID == 0) if (this._windowID == 0)
{ {
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
} }
return this._windowID++; return this._windowID++;
} }
} }
   
public Dictionary<string, GUIStyle> LabelStyles public Dictionary<string, GUIStyle> LabelStyles
{ {
get get
{ {
return this._LabelStyles; return this._LabelStyles;
  }
  }
   
  public List<CelestialBody> allBodies
  {
  get
  {
  return this._allBodies;
  }
  }
   
  public List<VesselType> allVesselTypes
  {
  get
  {
  return this._allVesselTypes;
  }
  }
   
  public float updateTimer
  {
  get
  {
  return this._updateTimer;
  }
  }
   
  public double updatePeriod
  {
  get
  {
  return this._updatePeriod;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
protected VOID_Core() protected VOID_Core()
{ {
this._Name = "VOID Core"; this._Name = "VOID Core";
   
  this._Active = true;
   
this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false); this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false);
this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false); this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false);
   
this.LoadConfig (); this.LoadConfig ();
} }
   
protected void LoadModules() protected void LoadModulesOfType<T>()
{ {
var types = AssemblyLoader.loadedAssemblies var types = AssemblyLoader.loadedAssemblies
.Select (a => a.assembly.GetExportedTypes ()) .Select (a => a.assembly.GetExportedTypes ())
.SelectMany (t => t) .SelectMany (t => t)
.Where (v => typeof(IVOID_Module).IsAssignableFrom (v) .Where (v => typeof(T).IsAssignableFrom (v)
&& !(v.IsInterface || v.IsAbstract) && && !(v.IsInterface || v.IsAbstract) &&
!typeof(VOID_Core).IsAssignableFrom (v) !typeof(VOID_Core).IsAssignableFrom (v)
); );
   
Tools.PostDebugMessage (string.Format ( Tools.PostDebugMessage (string.Format (
"{0}: Found {1} modules to check.", "{0}: Found {1} modules to check.",
this.GetType ().Name, this.GetType ().Name,
types.Count () types.Count ()
)); ));
foreach (var voidType in types) foreach (var voidType in types)
{ {
  if (!HighLogic.LoadedSceneIsEditor &&
  typeof(IVOID_EditorModule).IsAssignableFrom(voidType)
  )
  {
  continue;
  }
   
Tools.PostDebugMessage (string.Format ( Tools.PostDebugMessage (string.Format (
"{0}: found Type {1}", "{0}: found Type {1}",
this.GetType ().Name, this.GetType ().Name,
voidType.Name voidType.Name
)); ));
   
this.LoadModule(voidType); this.LoadModule(voidType);
} }
   
this._modulesLoaded = true; this._modulesLoaded = true;
   
Tools.PostDebugMessage (string.Format ("VOID_Core: Loaded {0} modules.", this.Modules.Count)); Tools.PostDebugMessage(string.Format(
  "{0}: Loaded {1} modules.",
  this.GetType().Name,
  this.Modules.Count
  ));
} }
   
protected void LoadModule(Type T) protected void LoadModule(Type T)
{ {
var existingModules = this._modules.Where (mod => mod.GetType ().Name == T.Name); var existingModules = this._modules.Where (mod => mod.GetType ().Name == T.Name);
if (existingModules.Any()) if (existingModules.Any())
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: refusing to load {1}: already loaded", "{0}: refusing to load {1}: already loaded",
this.GetType().Name, this.GetType().Name,
T.Name T.Name
)); ));
return; return;
} }
IVOID_Module module = Activator.CreateInstance (T) as IVOID_Module; IVOID_Module module = Activator.CreateInstance (T) as IVOID_Module;
module.LoadConfig(); module.LoadConfig();
this._modules.Add (module); this._modules.Add (module);
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"{0}: loaded module {1}.", "{0}: loaded module {1}.",
this.GetType().Name, this.GetType().Name,
T.Name T.Name
)); ));
} }
   
  protected void Preload_BeforeUpdate()
  {
  if (!this.bodiesLoaded)
  {
  this.LoadAllBodies();
  }
   
  if (!this.vesselTypesLoaded)
  {
  this.LoadVesselTypes();
  }
  }
   
public void Update() public void Update()
{ {
this.saveTimer += Time.deltaTime; this.Preload_BeforeUpdate ();
   
  if (this.vessel != null)
  {
  SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
  Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);
  SimManager.Instance.TryStartSimulation();
  }
   
if (!this.guiRunning) if (!this.guiRunning)
{ {
this.StartGUI (); this.StartGUI ();
} }
   
if (!HighLogic.LoadedSceneIsFlight && this.guiRunning) if (!HighLogic.LoadedSceneIsFlight && this.guiRunning)
{ {
this.StopGUI (); this.StopGUI ();
} }
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
if (!module.guiRunning && module.toggleActive) if (!module.guiRunning && module.toggleActive)
{ {
module.StartGUI (); module.StartGUI ();
} }
if (module.guiRunning && !module.toggleActive || !this.togglePower || !HighLogic.LoadedSceneIsFlight) if (module.guiRunning && !module.toggleActive ||
  !this.togglePower ||
  !HighLogic.LoadedSceneIsFlight ||
  this.factoryReset
  )
{ {
module.StopGUI(); module.StopGUI();
} }
}  
  if (module is IVOID_BehaviorModule)
if (this.saveTimer > 2f) {
{ ((IVOID_BehaviorModule)module).Update();
this.SaveConfig (); }
this.saveTimer = 0; }
}  
  this.CheckAndSave ();
  this._updateTimer += Time.deltaTime;
} }
   
public void FixedUpdate() public void FixedUpdate()
{ {
if (this.consumeResource && if (this.consumeResource &&
this.vessel.vesselType != VesselType.EVA && this.vessel.vesselType != VesselType.EVA &&
TimeWarp.deltaTime != 0 TimeWarp.deltaTime != 0
) )
{ {
float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName, float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName,
this.resourceRate * TimeWarp.fixedDeltaTime); this.resourceRate * TimeWarp.fixedDeltaTime);
if (powerReceived > 0) if (powerReceived > 0)
{ {
this.powerAvailable = true; this.powerAvailable = true;
} }
else else
{ {
this.powerAvailable = false; this.powerAvailable = false;
} }
} }
   
  foreach (IVOID_BehaviorModule module in
  this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract))
  {
  module.FixedUpdate();
  }
  }
   
  protected void LoadSkins()
  {
  this.skin_list = AssetBase.FindObjectsOfTypeIncludingAssets(typeof(GUISkin))
  .Where(s => !this.forbiddenSkins.Contains(s.name))
  .Select(s => s as GUISkin)
  .ToList();
   
  Tools.PostDebugMessage(string.Format(
  "{0}: loaded {1} GUISkins.",
  this.GetType().Name,
  this.skin_list.Count
  ));
   
  if (this._skinIdx == int.MinValue)
  {
  this._skinIdx = this.skin_list.IndexOf(this.Skin);
  Tools.PostDebugMessage(string.Format(
  "{0}: resetting _skinIdx to default.",
  this.GetType().Name
  ));
  }
   
  Tools.PostDebugMessage(string.Format(
  "{0}: _skinIdx = {1}.",
  this.GetType().Name,
  this._skinIdx.ToString()
  ));
   
  this.skinsLoaded = true;
} }
   
protected void LoadGUIStyles() protected void LoadGUIStyles()
{ {
  this.LabelStyles["link"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["link"].fontStyle = FontStyle.Bold;
   
this.LabelStyles["center"] = new GUIStyle(GUI.skin.label); this.LabelStyles["center"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["center"].normal.textColor = Color.white; this.LabelStyles["center"].normal.textColor = Color.white;
this.LabelStyles["center"].alignment = TextAnchor.UpperCenter; this.LabelStyles["center"].alignment = TextAnchor.UpperCenter;
   
this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label); this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["center_bold"].normal.textColor = Color.white; this.LabelStyles["center_bold"].normal.textColor = Color.white;
this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter; this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter;
this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold; this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold;
   
this.LabelStyles["txt_right"] = new GUIStyle(GUI.skin.label); this.LabelStyles["right"] = new GUIStyle(GUI.skin.label);
this.LabelStyles["txt_right"].normal.textColor = Color.white; this.LabelStyles["right"].normal.textColor = Color.white;
this.LabelStyles["txt_right"].alignment = TextAnchor.UpperRight; this.LabelStyles["right"].alignment = TextAnchor.UpperRight;
   
  this.LabelStyles ["red"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles ["red"].normal.textColor = Color.red;
  this.LabelStyles ["red"].alignment = TextAnchor.MiddleCenter;
   
this.GUIStylesLoaded = true; this.GUIStylesLoaded = true;
  }
   
   
  protected void LoadAllBodies()
  {
  this._allBodies = FlightGlobals.Bodies;
  this.bodiesLoaded = true;
  }
   
  protected void LoadVesselTypes()
  {
  this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();
  this.vesselTypesLoaded = true;
  }
   
  protected void CheckAndSave()
  {
  this.saveTimer += Time.deltaTime;
   
  if (this.saveTimer > 2f)
  {
  Tools.PostDebugMessage (string.Format (
  "{0}: Time to save, checking if configDirty: {1}",
  this.GetType ().Name,
  this.configDirty
  ));
   
  if (!this.configDirty)
  {
  return;
  }
   
  this.SaveConfig ();
  this.saveTimer = 0;
  }
} }
   
public void VOIDMainWindow(int _) public void VOIDMainWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
if (this.powerAvailable) if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)
{ {
string str = "ON"; if (!HighLogic.LoadedSceneIsEditor)
if (togglePower) str = "OFF"; {
if (GUILayout.Button("Power " + str)) togglePower = !togglePower; string str = "ON";
if (togglePower) if (togglePower) str = "OFF";
  if (GUILayout.Button("Power " + str)) togglePower = !togglePower;
  }
   
  if (togglePower || HighLogic.LoadedSceneIsEditor)
{ {
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name); module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name);
} }
} }
} }
else else
{ {
GUIStyle label_txt_red = new GUIStyle(GUI.skin.label); GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]);
label_txt_red.normal.textColor = Color.red;  
label_txt_red.alignment = TextAnchor.MiddleCenter;  
GUILayout.Label("-- POWER LOST --", label_txt_red);  
} }
   
this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration"); this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration");
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
public void VOIDConfigWindow(int _) public void VOIDConfigWindow(int _)
{ {
GUILayout.BeginVertical (); GUILayout.BeginVertical ();
   
this.DrawConfigurables (); this.DrawConfigurables ();
   
GUILayout.EndVertical (); GUILayout.EndVertical ();
GUI.DragWindow (); GUI.DragWindow ();
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources"); if (HighLogic.LoadedSceneIsFlight)
  {
  this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");
   
  this.VOIDIconLocked = GUILayout.Toggle (this.VOIDIconLocked, "Lock Icon Position");
  }
   
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
  GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
   
  GUIContent _content = new GUIContent();
   
  _content.text = "◄";
  _content.tooltip = "Select previous skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this._skinIdx--;
  if (this._skinIdx < 0) this._skinIdx = skin_list.Count - 1;
  Tools.PostDebugMessage (string.Format (
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinIdx,
  this.skin_list.Count
  ));
  }
   
  string skin_name = skin_list[this._skinIdx].name;
  _content.text = skin_name;
  _content.tooltip = "Current skin";
  GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true));
   
  _content.text = "►";
  _content.tooltip = "Select next skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this._skinIdx++;
  if (this._skinIdx >= skin_list.Count) this._skinIdx = 0;
  Tools.PostDebugMessage (string.Format (
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinIdx,
  this.skin_list.Count
  ));
  }
   
  if (this.Skin.name != this.defaultSkin)
  {
  this.defaultSkin = this.Skin.name;
  }
   
  GUILayout.EndHorizontal();
   
  GUILayout.BeginHorizontal();
  GUILayout.Label("Update Rate (Hz):");
  if (this.stringFrequency == null)
  {
  this.stringFrequency = (1f / this.updatePeriod).ToString();
  }
  this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true));
  // GUILayout.FlexibleSpace();
  if (GUILayout.Button("Apply"))
  {
  double updateFreq = 1f / this.updatePeriod;
  double.TryParse(stringFrequency, out updateFreq);
  this._updatePeriod = 1 / updateFreq;
  }
  GUILayout.EndHorizontal();
   
foreach (IVOID_Module mod in this.Modules) foreach (IVOID_Module mod in this.Modules)
{ {
mod.DrawConfigurables (); mod.DrawConfigurables ();
} }
   
  this._factoryReset = GUILayout.Toggle (this._factoryReset, "Factory Reset");
  }
   
  public void OnGUI()
  {
  if (Event.current.type == EventType.Repaint)
  {
  return;
  }
   
  /*
  Tools.PostDebugMessage(string.Format(
  "Event.current.type: {0}" +
  "\nthis.VOIDIconLocked: {1}" +
  "\nEvent.current.mousePosition: {2}" +
  "\nVOIDIconPos: ({3}, {4}),({5}, {6})",
  Event.current.type,
  this.VOIDIconLocked,
  Event.current.mousePosition,
  this.VOIDIconPos.value.xMin,
  this.VOIDIconPos.value.yMin,
  this.VOIDIconPos.value.xMax,
  this.VOIDIconPos.value.yMax
  ));
  */
   
  if (!this.VOIDIconLocked &&
  VOIDIconPos.value.Contains(Event.current.mousePosition)
  && Event.current.type == EventType.mouseDrag
  )
  {
  Tools.PostDebugMessage(string.Format(
  "Event.current.type: {0}" +
  "\ndelta.x: {1}; delta.y: {2}",
  Event.current.type,
  Event.current.delta.x,
  Event.current.delta.y
  ));
   
  Rect tmp = new Rect(VOIDIconPos);
   
  tmp.x = Event.current.mousePosition.x - tmp.width / 2;
  tmp.y = Event.current.mousePosition.y - tmp.height / 2;
   
  if (tmp.x > Screen.width - tmp.width)
  {
  tmp.x = Screen.width - tmp.width;
  }
   
  if (tmp.y > Screen.height - tmp.height)
  {
  tmp.y = Screen.height - tmp.height;
  }
   
  VOIDIconPos = tmp;
  }
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
if (!this._modulesLoaded) if (!this._modulesLoaded)
{ {
this.LoadModules (); this.LoadModulesOfType<IVOID_Module> ();
} }
   
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
   
  if (!this.skinsLoaded)
  {
  this.LoadSkins();
  }
   
GUI.skin = this.Skin; GUI.skin = this.Skin;
   
if (!this.GUIStylesLoaded) if (!this.GUIStylesLoaded)
{ {
this.LoadGUIStyles (); this.LoadGUIStyles ();
} }
   
this.VOIDIconTexture = this.VOIDIconOff; //icon off default this.VOIDIconTexture = this.VOIDIconOff; //icon off default
if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true
if (GUI.Button(new Rect(VOIDIconPos), VOIDIconTexture, new GUIStyle())) if (GUI.Button(VOIDIconPos, VOIDIconTexture) && this.VOIDIconLocked)
{ {
this.mainGuiMinimized = !this.mainGuiMinimized; this.mainGuiMinimized = !this.mainGuiMinimized;
} }
   
if (!this.mainGuiMinimized) if (!this.mainGuiMinimized)
{ {
Rect _mainWindowPos = this.mainWindowPos; Rect _mainWindowPos = this.mainWindowPos;
   
_mainWindowPos = GUILayout.Window ( _mainWindowPos = GUILayout.Window (
this.windowID, this.windowID,
_mainWindowPos, _mainWindowPos,
this.VOIDMainWindow, this.VOIDMainWindow,
string.Join (" ", new string[] {this.VoidName, this.VoidVersion}), string.Join (" ", new string[] {this.VoidName, this.VoidVersion}),
GUILayout.Width (250), GUILayout.Width (250),
GUILayout.Height (50) GUILayout.Height (50)
); );
   
  _mainWindowPos = Tools.ClampRectToScreen (_mainWindowPos);
   
if (_mainWindowPos != this.mainWindowPos) if (_mainWindowPos != this.mainWindowPos)
{ {
this.mainWindowPos = _mainWindowPos; this.mainWindowPos = _mainWindowPos;
} }
} }
   
if (!this.configWindowMinimized) if (!this.configWindowMinimized && !this.mainGuiMinimized)
{ {
Rect _configWindowPos = this.configWindowPos; Rect _configWindowPos = this.configWindowPos;
   
_configWindowPos = GUILayout.Window ( _configWindowPos = GUILayout.Window (
this.windowID, this.windowID,
_configWindowPos, _configWindowPos,
this.VOIDConfigWindow, this.VOIDConfigWindow,
string.Join (" ", new string[] {this.VoidName, "Configuration"}), string.Join (" ", new string[] {this.VoidName, "Configuration"}),
GUILayout.Width (250), GUILayout.Width (250),
GUILayout.Height (50) GUILayout.Height (50)
); );
   
  _configWindowPos = Tools.ClampRectToScreen (_configWindowPos);
   
if (_configWindowPos != this.configWindowPos) if (_configWindowPos != this.configWindowPos)
{ {
this.configWindowPos = _configWindowPos; this.configWindowPos = _configWindowPos;
} }
} }
} }
   
  public void ResetGUI()
  {
  this.StopGUI ();
   
  foreach (IVOID_Module module in this.Modules)
  {
  module.StopGUI ();
  module.StartGUI ();
  }
   
  this.StartGUI ();
  }
   
public override void LoadConfig() public override void LoadConfig()
{ {
base.LoadConfig (); base.LoadConfig ();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.LoadConfig (); module.LoadConfig ();
} }
} }
   
public override void SaveConfig() public void SaveConfig()
{ {
if (!this.configDirty) var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
{ config.load ();
return;  
} this._SaveToConfig(config);
   
base.SaveConfig ();  
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.SaveConfig (); module._SaveToConfig (config);
} }
   
  config.save();
   
this.configDirty = false; this.configDirty = false;
} }
} }
} }