public NDBDataSet HandleNDB()
        {
            string   NDBName     = config.Get("NDBStation", "Name").ToString();
            Vector3D NDBPosition = CreateVectorFromGPSCoordinateString(config.Get("NDBStation", "Position").ToString());

            NDBDataSet NDBData = new NDBDataSet();

            NDBData.Name = NDBName;

            Vector3D HeadingVector = Vector3D.Normalize(Vector3D.Reject(Vector3D.Normalize(CockpitBlock.WorldMatrix.Forward), GravVectorNorm));
            Vector3D CrossHeadingVector;

            if (Math.Acos(Vector3D.Dot(CockpitBlock.WorldMatrix.Down, GravVectorNorm)) < (Math.PI / 2))
            {
                CrossHeadingVector = Vector3D.Reject(CockpitBlock.WorldMatrix.Right, GravVectorNorm);
            }
            else
            {
                CrossHeadingVector = Vector3D.Reject(CockpitBlock.WorldMatrix.Left, GravVectorNorm);
            }

            Vector3D Direction  = Vector3D.Normalize(Vector3D.Reject(NDBPosition - ShipVector, GravVectorNorm));
            double   Angle      = ToDegrees(Math.Acos(Vector3D.Dot(Direction, HeadingVector)));
            double   CrossAngle = ToDegrees(Math.Acos(Vector3D.Dot(Direction, CrossHeadingVector)));

            if (CrossAngle > 90)
            {
                Angle = 360 - Angle;
            }

            NDBData.Rotation = Angle;

            return(NDBData);
        }
            private static void DrawNDB(ref MySpriteDrawFrame Frame, IMyTextSurface Surface, NDBDataSet NDBData)
            {
                if (NDBData.Rotation == null)
                {
                    DrawCross(ref Frame);
                    return;
                }

                // Vars
                float CircleSize    = Size.Y * 0.95f;
                float ArrowLength   = Size.Y * 0.8f;
                float ArrowRotation = (float)NDBData.Rotation;

                // 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));

                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);
            }
        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());
                }
            }
        }
        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);
        }