using System; using System.Collections.Generic; using System.Linq; using Telegram.Bot.Types.ReplyMarkups; using TelegramBotBase.Base; using TelegramBotBase.Controls.Hybrid; namespace TelegramBotBase.Form; /// /// Base class for an buttons array /// public class ButtonForm { private readonly List _buttons = new(); public ButtonForm() { } public ButtonForm(ControlBase control) { DependencyControl = control; } public ButtonForm(IEnumerable rows) { _buttons = rows.ToList(); } public IReplyMarkup Markup { get; set; } public ControlBase DependencyControl { get; set; } /// /// Contains the number of rows. /// public int Rows => _buttons.Count; /// /// Contains the highest number of columns in an row. /// public int Cols { get { return _buttons.Select(a => a.Count).OrderByDescending(a => a).FirstOrDefault(); } } public ButtonRow this[int row] => _buttons[row]; public int Count { get { if (_buttons.Count == 0) { return 0; } return _buttons.Select(a => a.ToArray()).ToList().Aggregate((a, b) => a.Union(b).ToArray()).Length; } } public void AddButtonRow(string text, string value, string url = null) { _buttons.Add(new List { new(text, value, url) }); } //public void AddButtonRow(ButtonRow row) //{ // Buttons.Add(row.ToList()); //} public void AddButtonRow(ButtonRow row) { _buttons.Add(row); } public void AddButtonRow(params ButtonBase[] row) { AddButtonRow(row.ToList()); } public void AddButtonRows(IEnumerable rows) { _buttons.AddRange(rows); } public void InsertButtonRow(int index, IEnumerable row) { _buttons.Insert(index, row.ToList()); } public void InsertButtonRow(int index, ButtonRow row) { _buttons.Insert(index, row); } //public void InsertButtonRow(int index, params ButtonBase[] row) //{ // InsertButtonRow(index, row.ToList()); //} public static T[][] SplitTo(IEnumerable items, int itemsPerRow = 2) { var splitted = default(T[][]); try { var t = items.Select((a, index) => new { a, index }) .GroupBy(a => a.index / itemsPerRow) .Select(a => a.Select(b => b.a).ToArray()).ToArray(); splitted = t; } catch { } return splitted; } /// /// Add buttons splitted in the amount of columns (i.e. 2 per row...) /// /// /// public void AddSplitted(IEnumerable buttons, int buttonsPerRow = 2) { var sp = SplitTo(buttons, buttonsPerRow); foreach (var bl in sp) { AddButtonRow(bl); } } /// /// Returns a range of rows from the buttons. /// /// /// /// public List GetRange(int start, int count) { return _buttons.Skip(start).Take(count).ToList(); } public List ToList() { return _buttons.DefaultIfEmpty(new List()).Select(a => a.ToList()) .Aggregate((a, b) => a.Union(b).ToList()); } public List ToRowList() { return _buttons; } public InlineKeyboardButton[][] ToInlineButtonArray() { var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToInlineButton(this)).ToArray()).ToArray(); return ikb; } public KeyboardButton[][] ToReplyButtonArray() { var ikb = _buttons.Select(a => a.ToArray().Select(b => b.ToKeyboardButton(this)).ToArray()).ToArray(); return ikb; } public List ToArray() { return _buttons; } public int FindRowByButton(ButtonBase button) { var row = _buttons.FirstOrDefault(a => a.ToArray().Count(b => b == button) > 0); if (row == null) { return -1; } return _buttons.IndexOf(row); } public Tuple FindRow(string text, bool useText = true) { var r = _buttons.FirstOrDefault(a => a.Matches(text, useText)); if (r == null) { return null; } var i = _buttons.IndexOf(r); return new Tuple(r, i); } /// /// Returns the first Button with the given value. /// /// /// public ButtonBase GetButtonByValue(string value) { return ToList().Where(a => a.Value == value).FirstOrDefault(); } public static implicit operator InlineKeyboardMarkup(ButtonForm form) { if (form == null) { return null; } var ikm = new InlineKeyboardMarkup(form.ToInlineButtonArray()); return ikm; } public static implicit operator ReplyKeyboardMarkup(ButtonForm form) { if (form == null) { return null; } var ikm = new ReplyKeyboardMarkup(form.ToReplyButtonArray()); return ikm; } /// /// Creates a copy of this form. /// /// public ButtonForm Duplicate() { var bf = new ButtonForm { Markup = Markup, DependencyControl = DependencyControl }; foreach (var b in _buttons) { var lst = new ButtonRow(); foreach (var b2 in b) { lst.Add(b2); } bf._buttons.Add(lst); } return bf; } /// /// Creates a copy of this form and filters by the parameter. /// /// public ButtonForm FilterDuplicate(string filter, bool byRow = false) { var bf = new ButtonForm { Markup = Markup, DependencyControl = DependencyControl }; foreach (var b in _buttons) { var lst = new ButtonRow(); foreach (var b2 in b) { if (b2.Text.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) == -1) { continue; } //Copy full row, when at least one match has found. if (byRow) { lst = b; break; } lst.Add(b2); } if (lst.Count > 0) { bf._buttons.Add(lst); } } return bf; } /// /// Creates a copy of this form and filters by the parameter. /// /// public ButtonForm TagDuplicate(List tags, bool byRow = false) { var bf = new ButtonForm { Markup = Markup, DependencyControl = DependencyControl }; foreach (var b in _buttons) { var lst = new ButtonRow(); foreach (var b2 in b) { if (!(b2 is TagButtonBase tb)) { continue; } if (!tags.Contains(tb.Tag)) { continue; } //Copy full row, when at least one match has found. if (byRow) { lst = b; break; } lst.Add(b2); } if (lst.Count > 0) { bf._buttons.Add(lst); } } return bf; } }