public ScreenManager(Scheduler owner)
 {
     Owner             = owner;
     Owner.BlockFound += TryAttachScreen;
     Owner.Loading    += Load;
     Owner.Saving     += Save;
     Owner.RegisterCommand(ID, Command);
     Updater = Screens.GetEnumerator();
 }
        void TryAttachScreen(GridScanArgs <IMyTerminalBlock> item)
        {   //Check if we found a surface provider block that was used by one of our windows.
            if (item.First)
            {
                Owner.Tick10 -= ScreenUpdateTick;
            }
            var p = item.Item as IMyTextSurfaceProvider;

            if (p != null)
            {
                for (int i = PendingScreens.Count - 1; i >= 0; i--)
                {
                    if (PendingScreens[i].Item1.BlockId == item.Item.EntityId)
                    {   //found a matching block!
                        object     data;
                        IHasOutput job;
                        if ((PendingScreens[i].Item1.SurfaceId <= p.SurfaceCount) && //found a matching surface
                            Jobs.TryGetValue(PendingScreens[i].Item2, out job) && //found an output provider
                            job.TryParseMode(PendingScreens[i].Item3, out data))    //managed to restore its data object
                        {
                            var surface = p.GetSurface(PendingScreens[i].Item1.SurfaceId);
                            if (!Screens.ContainsKey(surface)) //add to active screens if necessary
                            {
                                Screens[surface] = new List <Window>();
                            }
                            Screens[surface].Add(new Window(PendingScreens[i].Item1, surface, data, job));
                        }
                        PendingScreens.RemoveAt(i);
                    }
                }
            }
            if (item.Last)
            {
                PendingScreens.Clear(); //we forget any windows we couldn't restore
                Updater.Dispose();
                Updater           = Screens.GetEnumerator();
                Owner.BlockFound -= TryAttachScreen; //as such, we won't need scanning the grid again
                Owner.Tick10     += ScreenUpdateTick;
            }
        }
        bool Init()
        {
            #region controller and settings

            var controllers = new List <IMyShipController>();
            GridTerminalSystem.GetBlocksOfType(controllers, x => x.IsSameConstructAs(Me));

            bool cruiseEnabledInSettings = false;
            bool alignEnabledInSettings  = false;

            Settings = new MyIni();
            if (Settings.TryParse(Storage))
            {
                if (Settings.ContainsSection(SettingsHeader))
                {
                    targetSpeed                 = Settings.Get(SettingsHeader, SettingsTargetSpeed).ToSingle(targetSpeed);
                    thrustDirection             = (Base6Directions.Direction)Settings.Get(SettingsHeader, SettingsSelectedThrusters).ToInt32((int)thrustDirection);
                    targetAltAscending          = Settings.Get(SettingsHeader, SettingsTargetAltAscending).ToDouble(targetAltAscending);
                    targetAltDescending         = Settings.Get(SettingsHeader, SettingsTargetAltDescending).ToDouble(targetAltDescending);
                    disableCruiseExitingGravity = Settings.Get(SettingsHeader, SettingsDisableCruiseExitingGravity).ToBoolean(disableCruiseExitingGravity);
                    disableAlignExitingGravity  = Settings.Get(SettingsHeader, SettingsDisableAlignExitingGravity).ToBoolean(disableAlignExitingGravity);
                    useSeaLevel                 = Settings.Get(SettingsHeader, SettingsUseSeaLevel).ToBoolean(useSeaLevel);
                    worldTopSpeed               = Settings.Get(SettingsHeader, SettingsWorldTopSpeed).ToSingle(worldTopSpeed);

                    cruiseEnabledInSettings = Settings.Get(SettingsHeader, SettingsCruiseEnabled).ToBoolean();
                    alignEnabledInSettings  = Settings.Get(SettingsHeader, SettingsCruiseEnabled).ToBoolean();

                    var parts = Settings.Get(SettingsHeader, SettingsController).ToString().Split(';');
                    if (parts.Length == 3)
                    {
                        GetController(controllers, new Vector3I(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2])));
                    }
                }
            }



            //If fetching controller from storage failed, try to set up a new.
            if (MainController == null)
            {
                if (!GetController(controllers))
                {
                    Errors["no controller"] = "No ship controller found. Can't resume. Sit in one for a few seconds.";
                    return(false);
                }
            }
            if (MainController != null)
            {
                Errors.Remove("no controller");
            }

            Settings.Set(SettingsHeader, SettingsController, $"{MainController.Position.X};{MainController.Position.Y};{MainController.Position.Z}");
            SaveSettings();

            //screen = (MainController as IMyTextSurfaceProvider).GetSurface(0);
            //screen.ContentType = ContentType.TEXT_AND_IMAGE;

            //var sprites = new List<string>();
            //screen.GetSprites(sprites);
            //Me.CustomData = "";
            //foreach (var item in sprites)
            //{
            //	Me.CustomData += item + "\n";
            //}

            #endregion



            var allBlocks = new List <IMyTerminalBlock>();
            GridTerminalSystem.GetBlocksOfType(allBlocks, x => x.IsSameConstructAs(Me));

            List <IMyGyro>        gyros     = new List <IMyGyro>();
            List <IMyThrust>      thrusters = new List <IMyThrust>();
            List <IMyTextSurface> screens   = new List <IMyTextSurface>();

            foreach (var item in allBlocks)
            {
                //if(item is IMyProjector)
                //{
                //	proj = new ProjectorVisualization(item as IMyProjector, Vector3I.Zero);
                //}

                if (item is IMyGyro)
                {
                    gyros.Add(item as IMyGyro);
                }

                if (item is IMyThrust)
                {
                    thrusters.Add(item as IMyThrust);
                }
                if (item as IMyTextSurfaceProvider != null)
                {
                    if (item.CustomName.Contains("#ACC"))
                    {
                        int screennr = 0;
                        var parts    = item.CustomName.Split('@');
                        if (parts.Length > 1)
                        {
                            for (int i = 0; i < parts.Length; i++)
                            {
                                if (parts[i].EndsWith("#ACC") && parts.Length > i + 1)
                                {
                                    int.TryParse(new string(parts[i + 1].TakeWhile(char.IsDigit).ToArray()), out screennr);
                                }
                            }
                        }
                        screens.Add((item as IMyTextSurfaceProvider).GetSurface(screennr));
                        screens[screens.Count - 1].ContentType = ContentType.SCRIPT;
                        screens[screens.Count - 1].Script      = "";
                    }
                }
            }

            if (screens.Count > 0)
            {
                LCDs = new Screens(screens);
            }

            if (gyros.Count > 0)
            {
                Align = new Aligner(MainController, gyros);
                if (alignEnabledInSettings)
                {
                    StartAlign(true);
                }
            }

            if (thrusters.Count > 0)
            {
                Cruise = new CruiseControl(MainController, thrusters);
                if (cruiseEnabledInSettings)
                {
                    StartCruiseControl(true);
                }
            }
            return(true);
        }