Control GetBaseInstructions()
        {
            string GetGameStatusText(FilePatchStatus status) =>
            status switch
            {
                FilePatchStatus.Unknown => L10n.Get("Oops, error?", "File patch status"),
                FilePatchStatus.NoFile => L10n.Get("No file selected"),
                FilePatchStatus.ValidFile => L10n.Get("Game compatible with the patch!"),
                FilePatchStatus.InvalidFormat => L10n.Get("This is not a game in CIA format"),
                FilePatchStatus.InvalidRegion => L10n.Get("The patcher does not support this game region"),
                FilePatchStatus.InvalidTitle => L10n.Get("Invalid game..."),
                FilePatchStatus.InvalidVersion => L10n.Get("The patcher does not support this game version"),
                FilePatchStatus.InvalidDump => L10n.Get("Game dump is not valid. Make sure to dump your own game"),
                FilePatchStatus.GameIsEncrypted => L10n.Get("Game is encrypted. Redump the game decrypted"),
                _ => L10n.Get("Oops, error?", "File patch status"),
            };

            var selectGameBtn = new Button {
                Text    = L10n.Get("Select", "Choose button in patcher"),
                Command = viewModel.SelectGameCommand,
            };

            var selectedPathBox = new TextBox {
                ReadOnly        = true,
                PlaceholderText = L10n.Get("Click in the button Select"),
                Width           = 300,
            };

            selectedPathBox.TextBinding.BindDataContext <PatcherViewModel>(vm => vm.SelectedGamePath);

            var verifySpinning = new Spinner {
                Enabled = true
            };

            verifySpinning.BindDataContext(s => s.Visible, (PatcherViewModel vm) => vm.SelectGameCommand.IsRunning);

            var verifyLabel = new Label {
                Text = string.Empty,
                Font = SystemFonts.Bold(),
            };

            verifyLabel.TextBinding.Bind(
                Binding.Property(viewModel, vm => vm.SelectGameCommand.IsRunning)
                .Convert(r => r
                        ? L10n.Get("Please wait while we check the game...")
                        : GetGameStatusText(viewModel.FileStatus)));
            verifyLabel.Bind(
                l => l.TextColor,
                Binding.Property(viewModel, vm => vm.FileStatus)
                .Convert(s => s == FilePatchStatus.ValidFile
                        ? Colors.Green
                        : Colors.Red));

            var citraRadioBtn = new RadioButton {
                Text = L10n.Get("Citra emulator"),
            };

            citraRadioBtn.Bind(
                c => c.Checked,
                Binding.Property(viewModel, vm => vm.TargetDevice)
                .ToBool(TargetDevice.CitraPcLayeredFs));

            var consoleRadioBtn = new RadioButton(citraRadioBtn)
            {
                Text = L10n.Get("Console"),
            };

            consoleRadioBtn.Bind(
                c => c.Checked,
                Binding.Property(viewModel, vm => vm.TargetDevice)
                .ToBool(TargetDevice.ConsoleLayeredFs));

            var patchBtn = new Button {
                Text    = L10n.Get("Patch!", "Button in patcher"),
                Font    = SystemFonts.Bold(),
                Command = viewModel.PatchCommand,
            };

            var consoleControl = GetConsoleInstructions();
            var citraControl   = GetCitraInstructions();
            var infoLayout     = new Panel();

            infoLayout.Bind(
                c => c.Content,
                Binding.Property(viewModel, vm => vm.TargetDevice)
                .Convert(t => t == TargetDevice.CitraPcLayeredFs ? citraControl : consoleControl));

            var table = new TableLayout {
                Padding = 10,
                Spacing = new Size(10, 10),
                Rows    =
                {
                    new TableRow(L10n.Get("1. Buy the game in the Nintendo e-shop")),
                    new TableRow(L10n.Get("2. Dump the game to the microSD using the format no legit CIA\n   (e.g. using godmode9)")),
                    new TableRow(L10n.Get("3. Copy the game from the microSD to the computer.")),
                    new TableRow(L10n.Get("4. Choose the CIA file:")),
                    new TableLayout {
                        Spacing = new Size(10,                                                                                            10),
                        Rows    = { new TableRow(selectGameBtn,                                                                       selectedPathBox) },
                    },
                    new TableLayout {
                        Spacing = new Size(10,                                                                                            10),
                        Rows    = { new TableRow(verifySpinning,                                                                      verifyLabel) },
                    },
                    new TableRow(L10n.Get("5. Select how you will play the game:")),
                    new TableLayout {
                        Spacing = new Size(10,                                                                                            10),
                        Rows    =
                        {
                            new TableRow(citraRadioBtn,   null),
                            new TableRow(consoleRadioBtn, null),
                        },
                    },
                    new TableRow(infoLayout),
                    new TableRow()
                    {
                        ScaleHeight = true
                    },
                    new TableLayout(new TableRow(patchBtn,                                                                            null)),
                    new TableRow(),
                },
            };

            var drawable = new Drawable {
                Content = table,
            };

            Bitmap clippyImage = Bitmap.FromResource(ResourcesName.Clippy);

            drawable.Paint += (sender, e) =>
                              e.Graphics.DrawImage(
                image: clippyImage,
                x: table.Width - clippyImage.Width - 10,
                y: 200,
                width: clippyImage.Width,
                height: clippyImage.Height);

            return(drawable);
        }
        //private ModelEnergyProperties ModelEnergyProperties { get; set; }
        public Dialog_SHW(HoneybeeSchema.SHWSystem shw = default, bool lockedMode = false, Func <string> roomIDPicker = default)
        {
            var sys = shw ?? new SHWSystem($"SHWSystem_{Guid.NewGuid().ToString().Substring(0, 8)}");
            var vm  = new SHWViewModel(sys, this);

            vm.SetAmbientCoffConditionRoomPicker(roomIDPicker);

            //Padding = new Padding(4);
            Title       = $"Service Hot Water - {DialogHelper.PluginName}";
            WindowStyle = WindowStyle.Default;
            Width       = 450;
            this.Icon   = DialogHelper.HoneybeeIcon;

            var layout = new DynamicLayout();

            layout.DefaultSpacing = new Size(5, 5);
            layout.Padding        = new Padding(10);


            //string identifier,
            //string displayName = null,
            //object userData = null,
            //SHWEquipmentType equipmentType = SHWEquipmentType.Gas_WaterHeater,
            //AnyOf<double, Autocalculate> heaterEfficiency = null,
            //AnyOf< double, string> ambientCondition = null,
            //double ambientLossCoefficient = 6.0

            var nameText = new TextBox();

            var eqpType       = new EnumDropDown <SHWEquipmentType>();
            var heaterEffAuto = new RadioButton()
            {
                Text = "Autocalculate"
            };
            var heaterEffNumber = new RadioButton();
            var heaterEff       = new NumericStepper();

            // ambientCoffCondition
            var ambientLayout = new DynamicLayout();

            ambientLayout.DefaultSpacing = new Size(5, 5);

            var ambientCoffConditionNumber = new RadioButton();
            var ambientCoffConditionRoom   = new RadioButton()
            {
                Text = "Room ID"
            };

            var ambientCoffCondition = new DoubleText()
            {
                Width = 370
            };
            var ambientCoffConditionRoomLayout = new DynamicLayout();
            var ambientCoffConditionRoomID     = new TextBox();
            var ambientCoffConditionRoomID_btn = new Button();

            ambientCoffConditionRoomLayout.AddRow(ambientCoffConditionRoomID);
            ambientCoffConditionRoomLayout.AddRow(ambientCoffConditionRoomID_btn);

            var ambientCoffConditionUnit = new Label();

            ambientCoffConditionUnit.TextBinding.Bind(vm, _ => _.AmbientCoffConditionNumber.DisplayUnitAbbreviation);

            ambientLayout.AddSeparateRow("Ambient Condition:");
            ambientLayout.AddSeparateRow(ambientCoffConditionNumber, ambientCoffCondition, ambientCoffConditionUnit);
            ambientLayout.AddSeparateRow(ambientCoffConditionRoom, ambientCoffConditionRoomLayout);
            ambientLayout.Bind(_ => _.Enabled, vm, _ => _.AmbientCoffConditionEnabled);


            var ambientLossCoefficient = new NumericStepper()
            {
                MaximumDecimalPlaces = 2
            };

            nameText.Bind(_ => _.Text, vm, _ => _.Name);
            eqpType.Bind(_ => _.SelectedValue, vm, _ => _.EquipType);


            heaterEffAuto.Bind(c => c.Checked, vm, _ => _.HeaterEffAuto);
            heaterEffNumber.Bind(c => c.Checked, vm, _ => _.HeaterEffEnabled);
            heaterEff.Bind(c => c.Value, vm, _ => _.HeaterEff);
            heaterEff.Bind(c => c.Enabled, vm, _ => _.HeaterEffEnabled);

            ambientCoffConditionNumber.Bind(c => c.Checked, vm, _ => _.AmbientCoffConditionNumberEnabled);
            ambientCoffConditionRoom.Bind(c => c.Checked, vm, _ => _.AmbientCoffConditionRoomIDEnabled);
            //ambientCoffCondition.Bind(c => c.Value, vm, _ => _.AmbientCoffConditionNumber);
            ambientCoffCondition.Bind(c => c.Enabled, vm, _ => _.AmbientCoffConditionNumberEnabled);
            ambientCoffConditionRoomLayout.Bind(c => c.Enabled, vm, _ => _.AmbientCoffConditionRoomIDEnabled);

            ambientCoffConditionRoomID.Bind(c => c.Text, vm, _ => _.AmbientCoffConditionRoomID);
            ambientCoffConditionRoomID.Bind(_ => _.Visible, vm, _ => _.VisibleAmbientCoffConditionRoomInput);
            ambientCoffConditionRoomID_btn.Bind(_ => _.Text, vm, _ => _.AmbientCoffConditionRoomID);
            ambientCoffConditionRoomID_btn.Bind(_ => _.Visible, vm, _ => _.VisibleAmbientCoffConditionRoomPicker);
            ambientCoffConditionRoomID_btn.Command = vm.AmbientCoffConditionRoomPickerCommand;

            ambientCoffCondition.ReservedText = ReservedText.Varies;
            ambientCoffCondition.SetDefault(22);
            ambientCoffCondition.TextBinding.Bind(vm, _ => _.AmbientCoffConditionNumber.NumberText);


            ambientLossCoefficient.Bind(_ => _.Value, vm, _ => _.AmbientLostCoff);

            layout.AddRow("Name:");
            layout.AddRow(nameText);
            layout.AddRow("Equipment Type:");
            layout.AddRow(eqpType);

            layout.AddRow("Heater Efficiency:");
            layout.AddRow(heaterEffAuto);
            layout.AddSeparateRow(heaterEffNumber, heaterEff);

            layout.AddRow(ambientLayout);

            layout.AddRow("Ambient Loss Coefficient [W/K]");
            layout.AddRow(ambientLossCoefficient);

            var locked = new CheckBox()
            {
                Text = "Locked", Enabled = false
            };

            locked.Checked = lockedMode;

            var OKButton = new Button {
                Text = "OK", Enabled = !lockedMode
            };

            OKButton.Click += (sender, e) => {
                try
                {
                    OkCommand.Execute(vm.GreateSys(shw));
                }
                catch (Exception er)
                {
                    MessageBox.Show(this, er.Message);
                    //throw;
                }
            };

            var abortButton = new Button {
                Text = "Cancel"
            };

            abortButton.Click += (sender, e) => Close();

            var hbData = new Button {
                Text = "Data"
            };

            hbData.Click += (sender, e) => Dialog_Message.Show(this, vm.GreateSys(shw).ToJson(true), "Schema Data");

            layout.AddSeparateRow(locked, null, OKButton, abortButton, null, hbData);
            layout.AddRow(null);
            Content = layout;
        }