using System; using System.Collections.Generic; using System.Linq; using Quadarax.Foundation.Core.Console; using Quadarax.Foundation.Core.QConsole.Argument; using Quadarax.Foundation.Core.QConsole.Value; using Quadarax.Foundation.Core.Value; namespace Quadarax.Foundation.Core.QConsole.Command.Base { public abstract class AbstractListCommand : AbstractCommand { #region *** Private Fields *** private readonly IList _items = new List(); #endregion #region *** Properties *** protected IEnumerable Items => _items; #endregion #region *** Constructors *** protected AbstractListCommand(Engine engine) : base(engine) { } #endregion #region *** Public Operations *** public void SetModel(ISelectionEntry[] modelItems, bool isItemAppends = false) { if (modelItems == null) throw new ArgumentNullException(nameof(modelItems)); if (!isItemAppends) ClearModel(); foreach (var item in modelItems) _items.Add(item); var asAppend = isItemAppends ? "as appended" : ""; WriteDebugInfo($"Command '{Name}' model set {asAppend} with {_items.Count} items."); } public void ClearModel() { _items.Clear(); WriteDebugInfo($"Command '{Name}' model was clear."); } public ISelectionEntry GetItem(int ordinal) { return _items[ordinal]; } #endregion #region *** Protected overrides *** protected override Result EndExecute(Result incommingResult) { if (_items == null) throw new Exception($"Command '{Name}' must have set model first in OnExecute."); using (var writer = new ConsoleWriter(ConsoleColor.Yellow)) { using (var writerGreen = new ConsoleWriter(ConsoleColor.Green)) { SetupPaging(); var isEndOfPaging = false; writerGreen.Write("Paging mode: "); writer.WriteLine(IsPagingMode() ? "ENABLED" : "Disabled"); writer.WriteLine(); while (!isEndOfPaging) { WriteDebugInfo( $"Command '{Name}': IsPagingMode={IsPagingMode()}; GetCurrentPage={GetCurrentPage()}; GetItemsPerPage={GetItemsPerPage()};"); int nCnt = 0; isEndOfPaging = !IsPagingMode(); var ordinal = (GetCurrentPage() - 1) * GetItemsPerPage(); foreach (var item in _items.Skip(GetCurrentPage() - 1).Take(GetItemsPerPage())) { writer.Write($"{ordinal + 1}. :"); OnWriteEntry(writerGreen, item); ordinal++; nCnt++; } writer.WriteLine(); if (IsPagingMode()) writer.WriteLine($"List shows {nCnt}/{_items.Count} items."); else writer.WriteLine($"List shows {nCnt} items."); if (IsPagingMode()) { writer.WriteLine($"Showing page {GetCurrentPage()}/{GetPagesCount()}."); using (var writerCyan = new ConsoleWriter(ConsoleColor.Cyan)) { using (var writerWhite = new ConsoleWriter(ConsoleColor.White)) { var isSelected = false; while (!isSelected) { writerWhite.WriteLine( $"Type special character [{QConsole.Defaults.RoleCharacters.InputIncrementPageCharacter}/{QConsole.Defaults.RoleCharacters.InputDecrementPageCharacter}/{QConsole.Defaults.RoleCharacters.InputFirstPageCharacter}/{QConsole.Defaults.RoleCharacters.InputLastPageCharacter}] or direct page value or ENTER to skip."); writerCyan.Write($"[{GetFirstPage()}-{GetLastPage()}]>"); var pageString = writerCyan.ReadLine().Trim(); try { isSelected = true; if (pageString == QConsole.Defaults.RoleCharacters .InputIncrementPageCharacter) { //increment page if (CheckPage(GetCurrentPage() + 1)) SetCurrentPage(GetCurrentPage() + 1); } else if (pageString == QConsole.Defaults.RoleCharacters .InputDecrementPageCharacter) { //decrement page if (CheckPage(GetCurrentPage() - 1)) SetCurrentPage(GetCurrentPage() - 1); } else if (pageString == QConsole.Defaults.RoleCharacters .InputFirstPageCharacter) { //first page SetCurrentPage(GetFirstPage()); } else if (pageString == QConsole.Defaults.RoleCharacters.InputLastPageCharacter) { //last page SetCurrentPage(GetLastPage()); } else if (pageString == QConsole.Defaults.RoleCharacters.InputExitPageCharacter) { //exit page isEndOfPaging = true; continue; } else { //direct page var pageNo = int.Parse(pageString); SetCurrentPage(pageNo); } } catch (Exception e) { using (var writerRed = new ConsoleWriter(ConsoleColor.Red)) { writerRed.Write("Error:").WriteLine(e.Message); } isSelected = false; } } } } } } } } return incommingResult; } protected abstract void OnWriteEntry(ConsoleWriter writer, ISelectionEntry entry); protected override IEnumerable OnSetupArguments() { var arguments = base.OnSetupArguments().ToList(); arguments.AddRange(new[] { new FlagArgument(Constants.Arguments.Lists.PageMode.Code, Constants.Arguments.Lists.PageMode.Description, Constants.Arguments.Lists.PageMode.Hint, false), new NamedArgument(Constants.Arguments.Lists.ItemsPerPage.Code, Constants.Arguments.Lists.ItemsPerPage.Description, Constants.Arguments.Lists.ItemsPerPage.Hint, TypeValuesEnum.Integer, QConsole.Defaults.Arguments.ItemsPerPage.ToString(), false), new NamedArgument(Constants.Arguments.Lists.Page.Code, Constants.Arguments.Lists.Page.Description, Constants.Arguments.Lists.Page.Hint, TypeValuesEnum.Integer, "1", false), }); return arguments; } protected void EnableDefaultPagingMode() { var argPageMode = GetArgument(Constants.Arguments.Lists.PageMode.Code); argPageMode.DefaultValue.Set(true); argPageMode.SetValueAsDefault(); } protected void DisableDefaultPagingMode() { var argPageMode = GetArgument(Constants.Arguments.Lists.PageMode.Code); argPageMode.DefaultValue.Set(false); argPageMode.SetValueAsDefault(); } #endregion #region *** Private Operations *** private bool IsPagingMode() { var argPageMode = GetArgument(Constants.Arguments.Lists.PageMode.Code); return (bool) argPageMode.Value.Get(); } private int GetItemsPerPage() { if (!IsPagingMode()) return _items.Count; var argPageItems = GetArgument(Constants.Arguments.Lists.ItemsPerPage.Code); return (int) argPageItems.Value.Get(); } private int GetCurrentPage() { var argPage = GetArgument(Constants.Arguments.Lists.Page.Code); return (int) argPage.Value.Get(); } private void SetCurrentPage(int page) { if (!CheckPage(page)) throw new Exception($"Page value must be inside interval <{GetFirstPage()};{GetLastPage()}>."); var argPage = GetArgument(Constants.Arguments.Lists.Page.Code); argPage.Value.Set(page); } private bool CheckPage(int page) { return !(page < GetFirstPage() || page > GetLastPage()); } private int GetFirstPage() { return 1; } private int GetLastPage() { return GetPagesCount(); } private int GetPagesCount() { return (_items.Count / GetItemsPerPage()) + 1; } private void SetupPaging() { if (!IsPagingMode()) { var argPageItems = GetArgument(Constants.Arguments.Lists.ItemsPerPage.Code); argPageItems.Value.Set(_items.Count); SetCurrentPage(1); } } #endregion } }