public void DrawToSurfaces(ILSDataSet ILSData, VORDataSet VORData, NDBDataSet NDBData)
        {
            List <IMyTextSurfaceProvider> SurfaceProviders = GetScreens(CockpitTag);

            if (SurfaceProviders == null)
            {
                Echo("No screen found!");
                return;
            }

            CombinedDataSet CombinedData = new CombinedDataSet
            {
                ILSData = ILSData,
                VORData = VORData
            };

            foreach (IMyTextSurfaceProvider _sp in SurfaceProviders)
            {
                IMyTerminalBlock _spTerminal       = _sp as IMyTerminalBlock;
                string           _customDataString = _spTerminal.CustomData;
                MyIni            _customData       = new MyIni();

                MyIniParseResult iniResult;
                if (!_customData.TryParse(_customDataString, out iniResult))
                {
                    throw new Exception(iniResult.ToString());
                }


                if (_customData.Get("NavigationSurfaces", "0").ToString("none") == "none")
                {
                    for (int i = 0; i < _sp.SurfaceCount; i++)
                    {
                        switch (i)
                        {
                        case 1:
                            _customData.Set("NavigationSurfaces", i.ToString(), "ILS");
                            break;

                        case 2:
                            _customData.Set("NavigationSurfaces", i.ToString(), "VOR");
                            break;

                        case 3:
                            _customData.Set("NavigationSurfaces", i.ToString(), "Data");
                            break;

                        default:
                            _customData.Set("NavigationSurfaces", i.ToString(), "N/A");
                            break;
                        }
                    }

                    _spTerminal.CustomData = _customData.ToString();
                    continue;
                }

                string[] DrawSurfaces = new string[_sp.SurfaceCount];
                try
                {
                    for (var i = 0; i < _sp.SurfaceCount; i++)
                    {
                        string value = _customData.Get("NavigationSurfaces", i.ToString()).ToString();
                        DrawSurfaces[i] = value;
                    }
                }
                catch (Exception)
                {
                    Echo("Error in building DrawSurfaces Loop");
                }

                // ILS Screen
                try
                {
                    IMyTextSurface ILSSurface = _sp.GetSurface(Array.IndexOf(DrawSurfaces, "ILS"));
                    Draw.DrawSurface(ILSSurface, Surface.ILS, ILSData);
                }
                catch (Exception)
                {
                    Echo("No ILS Surface found in \"" + _spTerminal.CustomName.ToString() + "\".");
                }


                // VOR Screen
                try
                {
                    IMyTextSurface VORSurface = _sp.GetSurface(Array.IndexOf(DrawSurfaces, "VOR"));
                    Draw.DrawSurface(VORSurface, Surface.VOR, VORData);
                }
                catch (Exception)
                {
                    Echo("No VOR Surface found in \"" + _spTerminal.CustomName.ToString() + "\".");
                }


                // NDB Screen
                try
                {
                    IMyTextSurface VORSurface = _sp.GetSurface(Array.IndexOf(DrawSurfaces, "NDB"));
                    Draw.DrawSurface(VORSurface, Surface.NDB, NDBData);
                }
                catch (Exception)
                {
                    Echo("No NDB Surface found in \"" + _spTerminal.CustomName.ToString() + "\".");
                }


                // Data Screen
                try
                {
                    IMyTextSurface DataSurface = _sp.GetSurface(Array.IndexOf(DrawSurfaces, "Data"));
                    Draw.DrawSurface(DataSurface, Surface.Data, CombinedData);
                }
                catch (Exception)
                {
                    Echo("No Data Surface found in " + _spTerminal.CustomName.ToString());
                }
            }
        }
            private static void DrawILS(ref MySpriteDrawFrame Frame, IMyTextSurface Surface, ILSDataSet ILSData)
            {
                if (ILSData.Rotation == null)
                {
                    DrawCross(ref Frame);
                    return;
                }


                // Vars
                float CircleSize  = Size.Y * 0.95f;
                float ArrowLength = Size.Y * 0.8f;

                float ArrowRotation = (float)ILSData.Rotation;
                float Deviation     = (float)ILSData.LocalizerDeviation; // between -12 and 12.

                // Re-position the Center position a bit offset in order to accomodate glideslope indicator.
                Center -= CenterSub;

                // Circle
                MySprite Circle1 = MySprite.CreateSprite("Circle", Center, new Vector2(CircleSize, CircleSize));

                Circle1.Color = CockpitFGColor.Alpha(1f);
                Frame.Add(Circle1);

                MySprite Circle2 = MySprite.CreateSprite("Circle", Center, new Vector2(CircleSize, CircleSize) * 0.95f);

                Circle2.Color = CockpitBGColor.Alpha(1f);
                Frame.Add(Circle2);

                // Arrow
                MySprite ArrowBody = MySprite.CreateSprite("SquareSimple", Center, new Vector2(12 * UnitX, ArrowLength)); // new Vector2(10 * UnitX, 60 * UnitY)

                ArrowBody.Color           = Color.LawnGreen.Alpha(1f);
                ArrowBody.RotationOrScale = ToRadian(ArrowRotation);
                Frame.Add(ArrowBody);

                float AConstant = ArrowLength / 2.1f;
                float Ax        = (float)Math.Sin(ToRadian(ArrowRotation)) * AConstant;
                float Ay        = (float)Math.Cos(ToRadian(ArrowRotation)) * AConstant * -1;

                MySprite ArrowHead = MySprite.CreateSprite("Triangle", Center + new Vector2(Ax, Ay), Size * 0.2f);

                ArrowHead.Color           = Color.LawnGreen.Alpha(1f);
                ArrowHead.RotationOrScale = ToRadian(ArrowRotation);
                Frame.Add(ArrowHead);


                // Deviation bar
                float DConstant = Deviation / (float)LOCFullScaleDeflectionAngle * (Size.Y * 0.4f);
                float Dx        = (float)Math.Sin(ToRadian(ArrowRotation + 90)) * DConstant * -1;
                float Dy        = (float)Math.Cos(ToRadian(ArrowRotation + 90)) * DConstant;

                MySprite DeviationBarMask = MySprite.CreateSprite("SquareSimple", Center, new Vector2(12 * UnitX, ArrowLength / 2.7f));

                DeviationBarMask.Color           = CockpitBGColor.Alpha(1f);
                DeviationBarMask.RotationOrScale = ToRadian(ArrowRotation);
                Frame.Add(DeviationBarMask);

                MySprite DeviationBar = MySprite.CreateSprite("SquareSimple", Center + new Vector2(Dx, Dy), new Vector2(12 * UnitX, ArrowLength / 3));

                DeviationBar.Color           = Color.LawnGreen.Alpha(1f);
                DeviationBar.RotationOrScale = ToRadian(ArrowRotation);
                Frame.Add(DeviationBar);



                // Localizer Deviation Scale
                float DSM2 = -1.0f * (Size.Y * 0.4f);
                float DSM1 = -0.5f * (Size.Y * 0.4f);
                float DSP1 = 0.5f * (Size.Y * 0.4f);
                float DSP2 = 1.0f * (Size.Y * 0.4f);


                float DSM2x = (float)Math.Sin(ToRadian(ArrowRotation + 90)) * DSM2 * -1;
                float DSM2y = (float)Math.Cos(ToRadian(ArrowRotation + 90)) * DSM2;

                float DSM1x = (float)Math.Sin(ToRadian(ArrowRotation + 90)) * DSM1 * -1;
                float DSM1y = (float)Math.Cos(ToRadian(ArrowRotation + 90)) * DSM1;

                float DSP1x = (float)Math.Sin(ToRadian(ArrowRotation + 90)) * DSP1 * -1;
                float DSP1y = (float)Math.Cos(ToRadian(ArrowRotation + 90)) * DSP1;

                float DSP2x = (float)Math.Sin(ToRadian(ArrowRotation + 90)) * DSP2 * -1;
                float DSP2y = (float)Math.Cos(ToRadian(ArrowRotation + 90)) * DSP2;

                MySprite DSM2Sprite = MySprite.CreateSprite("Circle", Center + new Vector2(DSM2x, DSM2y), new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite DSM1Sprite = MySprite.CreateSprite("Circle", Center + new Vector2(DSM1x, DSM1y), new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite DSCSprite  = MySprite.CreateSprite("Circle", Center, new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite DSP1Sprite = MySprite.CreateSprite("Circle", Center + new Vector2(DSP1x, DSP1y), new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite DSP2Sprite = MySprite.CreateSprite("Circle", Center + new Vector2(DSP2x, DSP2y), new Vector2(CircleSize, CircleSize) * 0.1f);

                DSM2Sprite.Color = CockpitFGColor.Alpha(1f);
                DSM1Sprite.Color = CockpitFGColor.Alpha(1f);
                DSCSprite.Color  = CockpitFGColor.Alpha(1f);
                DSP1Sprite.Color = CockpitFGColor.Alpha(1f);
                DSP2Sprite.Color = CockpitFGColor.Alpha(1f);

                Frame.Add(DSM2Sprite);
                Frame.Add(DSM1Sprite);
                Frame.Add(DSCSprite);
                Frame.Add(DSP1Sprite);
                Frame.Add(DSP2Sprite);


                // GlideSlope
                Vector2 GSCenter = new Vector2(Size.X * 1.3f, Center.Y);
                Vector2 GSM2     = new Vector2(GSCenter.X, GSCenter.Y - Size.Y * 0.4f);
                Vector2 GSM1     = new Vector2(GSCenter.X, GSCenter.Y - Size.Y * 0.2f);
                Vector2 GSP1     = new Vector2(GSCenter.X, GSCenter.Y + Size.Y * 0.2f);
                Vector2 GSP2     = new Vector2(GSCenter.X, GSCenter.Y + Size.Y * 0.4f);

                float   DeviationUnits = (float)ILSData.GlideSlopeDeviation / (float)GSFullScaleDeflectionAngle * Size.Y * 0.4f;
                Vector2 GSDiamondPos   = new Vector2(GSCenter.X, GSCenter.Y + DeviationUnits);


                MySprite GDSM2Sprite = MySprite.CreateSprite("Circle", GSM2, new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite GDSM1Sprite = MySprite.CreateSprite("Circle", GSM1, new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite GDSP1Sprite = MySprite.CreateSprite("Circle", GSP1, new Vector2(CircleSize, CircleSize) * 0.1f);
                MySprite GDSP2Sprite = MySprite.CreateSprite("Circle", GSP2, new Vector2(CircleSize, CircleSize) * 0.1f);

                MySprite GDSCSprite = MySprite.CreateSprite("SquareSimple", GSCenter, new Vector2(CircleSize * 0.2f, UnitY * 6));
                MySprite GSDiamond  = MySprite.CreateSprite("SquareSimple", GSDiamondPos, new Vector2(UnitX * 25, UnitY * 25));

                GDSCSprite.Color          = CockpitFGColor.Alpha(1f);
                GSDiamond.Color           = Color.LawnGreen.Alpha(1f);
                GSDiamond.RotationOrScale = ToRadian(45f);

                GDSM2Sprite.Color = CockpitFGColor.Alpha(1f);
                GDSM1Sprite.Color = CockpitFGColor.Alpha(1f);
                GDSP1Sprite.Color = CockpitFGColor.Alpha(1f);
                GDSP2Sprite.Color = CockpitFGColor.Alpha(1f);

                Frame.Add(GDSM2Sprite);
                Frame.Add(GDSM1Sprite);
                Frame.Add(GDSCSprite);
                Frame.Add(GDSP1Sprite);
                Frame.Add(GDSP2Sprite);

                Frame.Add(GSDiamond);

                // Re-center the center position.
                Center += CenterSub;
            }
        public void Main(string argument, UpdateType updateSource)
        {
            if (!SetupComplete)
            {
                Echo("Running setup.");
                Setup();
                InitializeStorage();
            }
            else
            {
                Echo("Skipping setup");
            }

            if (!argument.Equals(""))
            {
                switch (argument.ToLower())
                {
                // General Commands
                case "reset":
                    InitializeStorage();
                    break;

                // ILS Commands
                case "startils":
                    ShipShouldListenForILS = true;
                    break;

                case "stopsearchils":
                    ShipShouldListenForILS = false;
                    break;

                case "stopils":
                    ShipHasSelectedILS     = false;
                    ShipShouldListenForILS = false;
                    // ResetDefaultILSInConfig();
                    break;

                // VOR Commands
                case "startvor":
                    ShipShouldListenForVOR = true;
                    break;

                case "stopsearchvor":
                    ShipShouldListenForVOR = false;
                    break;

                case "stopvor":
                    ShipHasSelectedVOR     = false;
                    ShipShouldListenForVOR = false;
                    // ResetDefaultVORInConfig();
                    break;
                }
                // OBS 90
                if (argument.ToLower().StartsWith("obs "))
                {
                    string[] argPart = argument.Split(' ');
                    double   OBS;
                    if (double.TryParse(argPart[1], out OBS))
                    {
                        config.Set("VORNavigation", "OBS", OBS.ToString());
                        SaveStorage();
                    }
                }

                // SurfaceToggle 0 1
                if (argument.ToLower().StartsWith("surfacetoggle "))
                {
                    string[] argPart = argument.Split(' ');
                    int      SurfaceProviderIndex, SurfaceIndex;

                    int.TryParse(argPart[1], out SurfaceProviderIndex);
                    int.TryParse(argPart[2], out SurfaceIndex);

                    ToggleSurface(SurfaceProviderIndex, SurfaceIndex);
                }
            }

            // Update the ship and gravity vectors.
            UpdateVectors();


            // Main Logic
            if (ShipShouldListenForILS)
            {
                // If ship is connected to an ILS and is listening, another ILS closer by will override
                // the active transmitter. Normally ShipShouldListen will be false once connected.
                SearchForILSMessages();
            }

            if (ShipShouldListenForVOR)
            {
                SearchForVORMessages();
            }

            if (ShipShouldListenForNDB)
            {
                SearchForNDBMessages();
            }

            ILSData = new ILSDataSet();
            if (ShipHasSelectedILS)
            {
                ILSData = HandleILS();
            }

            VORDataSet VORData = new VORDataSet();

            if (ShipHasSelectedVOR)
            {
                VORData = HandleVOR();
            }

            NDBDataSet NDBData = new NDBDataSet();

            if (ShipHasSelectedNDB)
            {
                NDBData = HandleNDB();
            }

            DrawToSurfaces(ILSData, VORData, NDBData);
        }