private void DoPorkchopGui(Orbit o, double universalTime, MechJebModuleTargetController target)
		{
            // That mess is why you should not compute anything inside a GUI call
            // TODO : rewrite all that...
			if (worker == null)
			{
			    if (Event.current.type == EventType.Layout)
			        layoutSkipped = true;
			    return;
			}
            if (Event.current.type == EventType.Layout)
                layoutSkipped = false;
            if (layoutSkipped)
                return;

            string dv = " - ";
			string departure = " - ";
			string duration = " - ";
			if (worker.Finished && worker.computed.GetLength(1) == porkchop_Height)
			{
				if (plot == null && Event.current.type == EventType.Layout)
				{

                    int width = worker.computed.GetLength(0);
                    int height = worker.computed.GetLength(1);

                    if (texture != null && (texture.width != width || texture.height != height))
                    {
                        Object.Destroy(texture);
                        texture = null;
                    }

                    if (texture == null)
                        texture = new Texture2D(width, height, TextureFormat.RGB24, false);

                    Porkchop.RefreshTexture(worker.computed, texture);

                    plot = new PlotArea(
						worker.minDepartureTime,
						worker.maxDepartureTime,
						worker.minTransferTime,
						worker.maxTransferTime,
						texture,
						(xmin, xmax, ymin, ymax) => {
							minDepartureTime = Math.Max(xmin, universalTime);
							maxDepartureTime = xmax;
							minTransferTime = Math.Max(ymin, 3600);
							maxTransferTime = ymax;
							GUI.changed = true;
						});
					plot.selectedPoint = new int[]{worker.bestDate, worker.bestDuration};
				}
			}
			if (plot != null)
			{
				var point = plot.selectedPoint;
				if (plot.hoveredPoint != null)
					point = plot.hoveredPoint;

				var p = worker.computed[point[0], point[1]];
				if (p != null)
				{
					dv = MuUtils.ToSI(p.dV.magnitude) + "m/s";
					if (worker.DateFromIndex(point[0]) < Planetarium.GetUniversalTime())
						departure = "any time now";
					else
						departure = GuiUtils.TimeToDHMS(worker.DateFromIndex(point[0]) - Planetarium.GetUniversalTime());
					duration = GuiUtils.TimeToDHMS(worker.DurationFromIndex(point[1]));
				}
				plot.DoGUI();
				if (!plot.draggable) _draggable = false;
			}
			else
			{
				GUIStyle progressStyle = new GUIStyle
				{
					font = GuiUtils.skin.font,
					fontSize = GuiUtils.skin.label.fontSize,
					fontStyle = GuiUtils.skin.label.fontStyle,
					normal = {textColor = GuiUtils.skin.label.normal.textColor}
				};

				GUILayout.Box("Computing: " + worker.Progress + "%", progressStyle, new GUILayoutOption[] {
					GUILayout.Width(windowWidth),
					GUILayout.Height(porkchop_Height)});
			}
			GUILayout.BeginHorizontal();
			GUILayout.Label("ΔV: " + dv);
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Reset", GuiUtils.yellowOnHover))
				ComputeTimes(o, target.TargetOrbit, universalTime);
			GUILayout.EndHorizontal();

			GUILayout.BeginHorizontal();
			GUILayout.Label("Select: ");
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Lowest ΔV"))
			{
				plot.selectedPoint = new int[]{ worker.bestDate, worker.bestDuration };
				GUI.changed = false;
			}

			if (GUILayout.Button("ASAP"))
			{
				int bestDuration = 0;
				for (int i = 1; i < worker.computed.GetLength(1); i++)
				{
					if (worker.computed[0, bestDuration].dV.sqrMagnitude > worker.computed[0, i].dV.sqrMagnitude)
						bestDuration = i;
				}
				plot.selectedPoint = new int[]{ 0, bestDuration };
				GUI.changed = false;
			}
			GUILayout.EndHorizontal();

			GUILayout.Label("Departure in " + departure);
			GUILayout.Label("Transit duration " + duration);
		}
        private void DoPorkchopGui(Orbit o, double universalTime, MechJebModuleTargetController target)
        {
            CelestialBody targetCelestial = target.Target as CelestialBody;

            // That mess is why you should not compute anything inside a GUI call
            // TODO : rewrite all that...
            if (worker == null)
            {
                if (Event.current.type == EventType.Layout)
                {
                    layoutSkipped = true;
                }
                return;
            }
            if (Event.current.type == EventType.Layout)
            {
                layoutSkipped = false;
            }
            if (layoutSkipped)
            {
                return;
            }

            string dv        = " - ";
            string departure = " - ";
            string duration  = " - ";

            if (worker.Finished && worker.computed.GetLength(1) == porkchop_Height)
            {
                if (plot == null && Event.current.type == EventType.Layout)
                {
                    int width  = worker.computed.GetLength(0);
                    int height = worker.computed.GetLength(1);

                    if (texture != null && (texture.width != width || texture.height != height))
                    {
                        Object.Destroy(texture);
                        texture = null;
                    }

                    if (texture == null)
                    {
                        texture = new Texture2D(width, height, TextureFormat.RGB24, false);
                    }

                    Porkchop.RefreshTexture(worker.computed, texture);

                    plot = new PlotArea(
                        worker.minDepartureTime,
                        worker.maxDepartureTime,
                        worker.minTransferTime,
                        worker.maxTransferTime,
                        texture,
                        (xmin, xmax, ymin, ymax) => {
                        minDepartureTime = Math.Max(xmin, universalTime);
                        maxDepartureTime = xmax;
                        minTransferTime  = Math.Max(ymin, 3600);
                        maxTransferTime  = ymax;
                        GUI.changed      = true;
                    });
                    plot.selectedPoint = new int[] { worker.bestDate, worker.bestDuration };
                }
            }
            if (plot != null)
            {
                var point = plot.selectedPoint;
                if (plot.hoveredPoint != null)
                {
                    point = plot.hoveredPoint;
                }

                var p = worker.computed[point[0], point[1]];
                if (p > 0)
                {
                    dv = MuUtils.ToSI(p) + "m/s";
                    if (worker.DateFromIndex(point[0]) < Planetarium.GetUniversalTime())
                    {
                        departure = Localizer.Format("#MechJeb_adv_label1");//any time now
                    }
                    else
                    {
                        departure = GuiUtils.TimeToDHMS(worker.DateFromIndex(point[0]) - Planetarium.GetUniversalTime());
                    }
                    duration = GuiUtils.TimeToDHMS(worker.DurationFromIndex(point[1]));
                }
                plot.DoGUI();
                if (!plot.draggable)
                {
                    _draggable = false;
                }
            }
            else
            {
                GUIStyle progressStyle = new GUIStyle
                {
                    font      = GuiUtils.skin.font,
                    fontSize  = GuiUtils.skin.label.fontSize,
                    fontStyle = GuiUtils.skin.label.fontStyle,
                    normal    = { textColor = GuiUtils.skin.label.normal.textColor }
                };

                GUILayout.Box(Localizer.Format("#MechJeb_adv_computing") + worker.Progress + "%", progressStyle, GUILayout.Width(windowWidth), GUILayout.Height(porkchop_Height));//"Computing:"
            }
            GUILayout.BeginHorizontal();
            GUILayout.Label("ΔV: " + dv);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(Localizer.Format("#MechJeb_adv_reset_button"), GuiUtils.yellowOnHover))
            {
                ComputeTimes(o, target.TargetOrbit, universalTime);
            }
            GUILayout.EndHorizontal();

            includeCaptureBurn = GUILayout.Toggle(includeCaptureBurn, Localizer.Format("#MechJeb_adv_captureburn"));//"include capture burn"

            // fixup the default value of the periapsis if the target changes
            if (targetCelestial != null && lastTargetCelestial != targetCelestial)
            {
                if (targetCelestial.atmosphere)
                {
                    periapsisHeight = targetCelestial.atmosphereDepth / 1000 + 10;
                }
                else
                {
                    periapsisHeight = 100;
                }
            }

            GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_adv_periapsis"), periapsisHeight, "km");

            GUILayout.BeginHorizontal();
            GUILayout.Label(Localizer.Format("#MechJeb_adv_label2"));       //"Select: "
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(Localizer.Format("#MechJeb_adv_button1"))) //Lowest ΔV
            {
                plot.selectedPoint = new int[] { worker.bestDate, worker.bestDuration };
                GUI.changed        = false;
            }

            if (GUILayout.Button(Localizer.Format("#MechJeb_adv_button2")))//ASAP
            {
                int bestDuration = 0;
                for (int i = 1; i < worker.computed.GetLength(1); i++)
                {
                    if (worker.computed[0, bestDuration] > worker.computed[0, i])
                    {
                        bestDuration = i;
                    }
                }
                plot.selectedPoint = new int[] { 0, bestDuration };
                GUI.changed        = false;
            }
            GUILayout.EndHorizontal();

            GUILayout.Label(Localizer.Format("#MechJeb_adv_label3") + " " + departure); //Departure in
            GUILayout.Label(Localizer.Format("#MechJeb_adv_label4") + " " + duration);  //Transit duration

            lastTargetCelestial = targetCelestial;
        }