using System; using System.Collections.Generic; using System.Linq; using Quadarax.Foundation.Core.Console; using Quadarax.Foundation.Core.QConsole.Argument; using Quadarax.Foundation.Core.Value; namespace Quadarax.Foundation.Core.QConsole.Command.Base { public abstract class AbstractSelectionCommand : AbstractListCommand { #region *** Private fields *** private int _maxSelections; private int _minSelections; private IList _selectedItems; #endregion #region *** Properties *** protected abstract bool IsStoredToGlobal { get; } protected int MaxSelections => _maxSelections; protected int MinSelections => _minSelections; public ISelectionEntry[] SelectedItems => _selectedItems.ToArray(); #endregion #region *** Constructors *** protected AbstractSelectionCommand(Engine engine,int minSelection, int maxSelection) : base(engine) { if (maxSelection==0) throw new ArgumentOutOfRangeException(nameof(maxSelection),$"Max selections value must be bigger than zero in command '{Name}'."); if (minSelection==0) throw new ArgumentOutOfRangeException(nameof(minSelection),$"Min selections value must be bigger than zero in command '{Name}'."); if (minSelection > maxSelection) throw new ArgumentOutOfRangeException(nameof(maxSelection),$"Max selections value must be bigger than Min selection value in command '{Name}'."); _maxSelections = maxSelection; _minSelections = minSelection; _selectedItems = new List(); } #endregion #region *** Public Operations *** public void ClearSelected() { _selectedItems.Clear(); WriteDebugInfo($"Command '{Name}' clears selected items."); } #endregion #region *** Protected Overrides *** protected override IEnumerable OnSetupArguments() { var arguments = base.OnSetupArguments().ToList(); arguments.AddRange( new [] { new FlagArgument(Constants.Arguments.Selection.Code, Constants.Arguments.Selection.Description, Constants.Arguments.Selection.Hint, false) }); return arguments; } protected override Result EndExecute(Result incommingResult) { var result = base.EndExecute(incommingResult); if (!result.IsSuccess) return result; ClearSelected(); var nCnt = Items.Count(); var selectionEnabled = GetArgument(Constants.Arguments.Selection.Code); if ((bool) selectionEnabled.Value.Get() == false) return result; using (var writer = new ConsoleWriter(ConsoleColor.White)) { using (var writerCyan = new ConsoleWriter(ConsoleColor.Cyan)) { writer.WriteLine($"Select ordinal values separated by '{Engine.Configuration.CharacterSelectionInputValueSeparator}'..."); writer.WriteLine($"Must be selected at least {MinSelections} ordinals and maximal {MaxSelections} ordinals."); writerCyan.Write($"[1-{nCnt}]>"); var ordinalString = writerCyan.ReadLine(); var ordinals = ordinalString.Split(new[] {Engine.Configuration.CharacterSelectionInputValueSeparator}, StringSplitOptions.RemoveEmptyEntries); if (!(MinSelections<=ordinals.Length && ordinals.Length <= MaxSelections)) throw new Exception($"Number of ordinals must be in interval <{MinSelections};{MaxSelections}>. Current number of ordinals is {ordinals.Length}."); foreach (var ordinal in ordinals.Select(x=>int.Parse(x))) { if (ordinal<0 || ordinal > nCnt) throw new Exception($"Ordinal {ordinal} is out of scope interval <1;{nCnt}>."); _selectedItems.Add(GetItem(ordinal-1)); } writer.WriteLine($"Selected {_selectedItems.Count} ordinals."); if (IsStoredToGlobal) Engine.AppendSelection(_selectedItems.ToArray()); } } return result; } protected void EnableDefaultSelectionMode() { var argSelectionMode = GetArgument(Constants.Arguments.Selection.Code); argSelectionMode.DefaultValue.Set(true); argSelectionMode.SetValueAsDefault(); } protected void DisableDefaultSelectionMode() { var argSelectionMode = GetArgument(Constants.Arguments.Selection.Code); argSelectionMode.DefaultValue.Set(false); argSelectionMode.SetValueAsDefault(); } #endregion #region *** Private Operations *** #endregion } }