using Dominion.NET_WPF.Caching;
using Dominion.NET_WPF.Enums;
using Dominion.NET_WPF.Models;
using DominionBase;
using DominionBase.Cards;
using DominionBase.Piles;
using DominionBase.Players;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using Visibility = System.Windows.Visibility;
namespace Dominion.NET_WPF.Controls
{
///
/// Interaction logic for ucChooser.xaml
///
public partial class ucChooser : UserControl
{
#region Dependency Properties
public static readonly RoutedEvent ChooserOkClickEvent = EventManager.RegisterRoutedEvent(
"ChooserOkClick",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(ucChooser));
public static readonly DependencyProperty ChoiceProperty = DependencyProperty.Register("Choice", typeof(Choice), typeof(ucChooser), new UIPropertyMetadata(null));
public static readonly DependencyProperty CanPreselectProperty = DependencyProperty.Register("CanPreselect", typeof(bool), typeof(ucChooser), new UIPropertyMetadata(null));
#endregion
public ucChooser()
{
InitializeComponent();
((INotifyCollectionChanged)lbReorder.Items).CollectionChanged += LbReorder_CollectionChanged;
}
#region Properties
public event RoutedEventHandler ChooserOkClick
{
add { AddHandler(ChooserOkClickEvent, value); }
remove { RemoveHandler(ChooserOkClickEvent, value); }
}
private Guid _LastChoiceId = Guid.Empty;
private ChoiceResult _LastChoiceResult;
private readonly List _usedHotkeys = new List();
public AutoYieldCollection AutoYields { get; } = new AutoYieldCollection();
private List Yields = new List {
"Always for {0}", "Never for {0}",
"Always for {0} this turn", "No more for {0} this turn",
"Always this turn", "No more this turn",
"Always", "Never"
};
public string Target { get; set; }
public IPlayer Player { get; set; }
public ChoiceResult ChoiceResult { get; private set; }
public Choice Choice
{
get { return GetValue(ChoiceProperty) as Choice; }
set
{
SetValue(ChoiceProperty, value);
CanPreselect = value == null
|| (value.EventArgs == null && value.ChoiceType != ChoiceType.Supplies)
|| value.Options == null
|| value.Options.Any(o => o.IsRequired)
;
}
}
public bool? CanPreselect
{
get { return GetValue(CanPreselectProperty) as bool?; }
set { SetValue(CanPreselectProperty, value); }
}
public List SupplyControls { get; set; } = new List();
public bool IsReady
{
set
{
ChoiceResult = null;
if (!value)
{
Player = null;
Choice = null;
ChoiceResult = null;
SupplyControls.Clear();
}
if (value && Choice != null)
{
tbText.Text = string.Empty;
wrapPanel1.Visibility = Visibility.Visible;
wrapPanel1.Children.Clear();
bReorder.Visibility = bCardPool.Visibility = lbCardPool.Visibility = Visibility.Collapsed;
lbReorder.DataContext = null;
bHidden.Visibility = Visibility.Collapsed;
lbHidden.DataContext = null;
wpButtons.Visibility = bButtonDiv.Visibility = Visibility.Visible;
bNone.Visibility = Visibility.Visible;
bAll.Visibility = Visibility.Collapsed;
bOK.IsEnabled = false;
if (Choice.EventArgs is AttackedEventArgs args)
tbText.Text = string.Format("{1} played {2}{0}", Environment.NewLine, args.Attacker, args.AttackCard);
foreach (var sc in SupplyControls)
sc.Clickability = SupplyVisibility.Plain;
tbText.Text += $"{Player}, {Utilities.RenderText(Choice.Text)}";
switch (Choice.ChoiceType)
{
case ChoiceType.Options:
ChoiceResult = new ChoiceResult(new List());
_usedHotkeys.Clear();
foreach (var option in Choice.Options)
{
var optionPreText = string.Empty;
var optionShortcut = string.Empty;
var optionText = option.Text;
var shortcutIndex = FindShortcutIndex(option.Text);
if (shortcutIndex >= 0)
{
optionPreText = option.Text.Substring(0, shortcutIndex);
optionShortcut = $"_{option.Text.Substring(shortcutIndex, 1)}";
optionText = option.Text.Substring(shortcutIndex + 1);
}
wrapPanel1.Children.Add(CreateButton(option, Choice.EventArgs, option.IsRequired, buttonTexts: new string[] { optionPreText, optionShortcut, optionText }));
}
if (Choice.Maximum > 1 && Choice.Maximum >= wrapPanel1.Children.Count)
bAll.Visibility = Visibility.Visible;
break;
case ChoiceType.Cards:
ChoiceResult = new ChoiceResult(new CardCollection());
if (!Choice.IsOrdered)
{
foreach (var card in Choice.Cards)
{
if (card is DominionBase.Cards.Universal.Blank)
{
var bDivider = new Border
{
BorderBrush = Brushes.BlueViolet,
BorderThickness = new Thickness(2),
Margin = new Thickness(4)
};
wrapPanel1.Children.Add(bDivider);
}
else
{
wrapPanel1.Children.Add(CreateCardButton(card));
}
}
if (Choice.Maximum > 1 && Choice.Maximum >= wrapPanel1.Children.OfType().Count())
bAll.Visibility = Visibility.Visible;
}
else
{
wrapPanel1.Visibility = Visibility.Collapsed;
ViewModel.CardListViewModel clvmHidden;
switch (Choice.Visibility)
{
case DominionBase.Piles.Visibility.All:
bReorder.Visibility = Visibility.Visible;
if (Choice.Cards.Count() == Choice.Minimum)
{
var clvm = new ViewModel.CardListViewModel();
clvm.ShowCards(Choice.Cards, Choice.Visibility);
lbReorder.DataContext = clvm;
}
else
{
bCardPool.Visibility = lbCardPool.Visibility = Visibility.Visible;
var clvmReorder = new ViewModel.CardListViewModel();
clvmReorder.ShowCards(new CardCollection(), Choice.Visibility);
lbReorder.DataContext = clvmReorder;
var clvmPool = new ViewModel.CardListViewModel { PreserveSourceOrdering = true };
clvmPool.ShowCards(Choice.Cards, Choice.Visibility);
lbCardPool.DataContext = clvmPool;
}
if (lbReorder.Items.Count >= Choice.Minimum && lbReorder.Items.Count <= Choice.Maximum)
bOK.IsEnabled = true;
else
bOK.IsEnabled = false;
break;
case DominionBase.Piles.Visibility.Top:
bHidden.Visibility = Visibility.Visible;
clvmHidden = new ViewModel.CardListViewModel();
clvmHidden.ShowCards(Choice.Cards, Choice.Visibility);
lbHidden.DataContext = clvmHidden;
if (lbHidden.Items.Count >= Choice.Minimum && lbHidden.Items.Count <= Choice.Maximum)
bOK.IsEnabled = true;
else
bOK.IsEnabled = false;
break;
case DominionBase.Piles.Visibility.None:
bHidden.Visibility = Visibility.Visible;
var showCards = Choice.Cards;
if (WMain.Settings?.ChooserAutomaticallyMoveStashToTop == true
&& Choice.Text == ResourcesHelper.Get("RearrangeShuffledCards")
&& Choice.Cards.Any(c =>
c is DominionBase.Cards.Promotional.Stash
|| c is DominionBase.Cards.Promotional2ndEdition.Stash
))
{
showCards = new CardCollection(Choice.Cards.OrderByDescending(card =>
card is DominionBase.Cards.Promotional.Stash
|| card is DominionBase.Cards.Promotional2ndEdition.Stash));
}
clvmHidden = new ViewModel.CardListViewModel();
clvmHidden.ShowCards(showCards, Choice.Visibility);
lbHidden.DataContext = clvmHidden;
if (lbHidden.Items.Count >= Choice.Minimum && lbHidden.Items.Count <= Choice.Maximum)
bOK.IsEnabled = true;
else
bOK.IsEnabled = false;
break;
}
// "All" & "None" aren't valid for this case, either
cbAutoClick.Visibility = bButtonDiv.Visibility = Visibility.Collapsed;
bAll.Visibility = bNone.Visibility = Visibility.Collapsed;
}
break;
case ChoiceType.Supplies:
var tbSupplyNotification = new TextBlock
{
Text = "<-- Select a Supply pile to the left",
FontSize = 14
};
wrapPanel1.Children.Add(tbSupplyNotification);
foreach (var sc in SupplyControls)
{
if (Choice.Supplies.Values.Contains(sc.Supply))
{
if (Choice.Source.Type == DominionBase.Cards.Seaside.TypeClass.Embargo
|| Choice.Source.Type == DominionBase.Cards.Seaside2ndEdition.TypeClass.Embargo
//|| Choice.Source.Type == DominionBase.Cards.Seaside2019Errata.TypeClass.Embargo
|| Choice.Source.Type == DominionBase.Cards.DarkAges.TypeClass.BandOfMisfits
|| Choice.Source.Type == DominionBase.Cards.DarkAges2ndEdition.TypeClass.BandOfMisfits
//|| Choice.Source.Type == DominionBase.Cards.DarkAges2019Errata.TypeClass.BandOfMisfits
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Ferry
//|| _Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Inheritance
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.LostArts
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Pathfinding
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Plan
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Seaway
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Teacher
|| Choice.Source.Type == DominionBase.Cards.Adventures.TypeClass.Training
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Ferry
//|| _Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Inheritance
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.LostArts
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Pathfinding
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Plan
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Seaway
|| Choice.Source.Type == DominionBase.Cards.Adventures2ndEdition.TypeClass.Training
|| Choice.Source.Type == DominionBase.Cards.Empires.TypeClass.Overlord
|| Choice.Source.Type == DominionBase.Cards.Empires.TypeClass.SaltTheEarth
//|| Choice.Source.Type == DominionBase.Cards.Empires2019Errata.TypeClass.Overlord
)
sc.Clickability = SupplyVisibility.Selectable;
else
sc.Clickability = SupplyVisibility.Gainable;
sc.SupplyClick += SupplyControl_SupplyClick;
}
else
sc.Clickability = SupplyVisibility.NotClickable;
}
cbAutoClick.IsChecked = true;
if (Choice.Minimum > 0)
wpButtons.Visibility = Visibility.Collapsed;
break;
case ChoiceType.SuppliesAndCards:
foreach (var card in Choice.Cards)
wrapPanel1.Children.Add(CreateCardButton(card));
var tbSupplyCardNotification = new TextBlock { Text = "<-- Select a Supply pile to the left" };
if (Choice.Cards.Any())
tbSupplyCardNotification.Text += " or a card above";
tbSupplyCardNotification.FontSize = 14;
wrapPanel1.Children.Add(tbSupplyCardNotification);
foreach (var sc in SupplyControls)
{
if (Choice.Supplies.Values.Contains(sc.Supply))
{
if (Choice.Source.Type == DominionBase.Cards.Intrigue.TypeClass.WishingWell
|| Choice.Source.Type == DominionBase.Cards.Intrigue2ndEdition.TypeClass.WishingWell
|| Choice.Source.Type == DominionBase.Cards.Prosperity.TypeClass.Contraband
|| Choice.Source.Type == DominionBase.Cards.DarkAges.TypeClass.BandOfMisfits
|| Choice.Source.Type == DominionBase.Cards.DarkAges.TypeClass.Mystic
|| Choice.Source.Type == DominionBase.Cards.DarkAges.TypeClass.Rebuild
|| Choice.Source.Type == DominionBase.Cards.DarkAges2ndEdition.TypeClass.BandOfMisfits
|| Choice.Source.Type == DominionBase.Cards.DarkAges2ndEdition.TypeClass.Mystic
|| Choice.Source.Type == DominionBase.Cards.DarkAges2ndEdition.TypeClass.Rebuild
//|| Choice.Source.Type == DominionBase.Cards.DarkAges2019Errata.TypeClass.BandOfMisfits
|| Choice.Source.Type == DominionBase.Cards.Guilds.TypeClass.Doctor
|| Choice.Source.Type == DominionBase.Cards.Guilds.TypeClass.Journeyman
|| Choice.Source.Type == DominionBase.Cards.Guilds2ndEdition.TypeClass.Doctor
|| Choice.Source.Type == DominionBase.Cards.Guilds2ndEdition.TypeClass.Journeyman
|| Choice.Source.Type == DominionBase.Cards.Empires.TypeClass.Overlord
//|| Choice.Source.Type == DominionBase.Cards.Empires2019Errata.TypeClass.Overlord
)
sc.Clickability = SupplyVisibility.Selectable;
else
sc.Clickability = SupplyVisibility.Gainable;
sc.SupplyClick += SupplyControl_SupplyClick;
}
else
sc.Clickability = SupplyVisibility.NotClickable;
}
cbAutoClick.IsChecked = true;
if (Choice.Minimum > 0)
wpButtons.Visibility = Visibility.Collapsed;
break;
case ChoiceType.Boons:
foreach (var boon in Choice.Boons)
wrapPanel1.Children.Add(CreateCardButton(boon));
if (Choice.Maximum > 1 && Choice.Maximum >= wrapPanel1.Children.OfType().Count())
bAll.Visibility = Visibility.Visible;
break;
}
bMain.Background = BrushRepository.GetOutcomeBrush(Choice.ChoiceOutcome);
bMain.BorderBrush = BrushRepository.GetOutcomeBrush(Choice.ChoiceOutcome, true);
if (wrapPanel1.Visibility == Visibility.Visible)
{
bNone.Visibility = Choice.Minimum == 0 ? Visibility.Visible : Visibility.Collapsed;
if ((bAll.Visibility == Visibility.Collapsed && bNone.Visibility == Visibility.Collapsed) ||
(bOK.Visibility == Visibility.Collapsed && cbAutoClick.Visibility == Visibility.Collapsed))
bButtonDiv.Visibility = Visibility.Collapsed;
else
bButtonDiv.Visibility = Visibility.Visible;
}
if (WMain.Settings != null && cbAutoClick.Visibility == Visibility.Visible)
cbAutoClick.IsChecked = WMain.Settings.ChooserAutomaticallyClickWhenSatisfied;
FilterAutoYields();
// Automatic chooser clicking!
if (WMain.Settings != null && WMain.Settings.ChooserAutomaticallyRevealMoat &&
Choice.EventArgs is AttackedEventArgs &&
Choice.ChoiceType == ChoiceType.Cards &&
Choice.Text == ResourcesHelper.Get("ShouldReveal") &&
Choice.Cards.Any(c =>
c is DominionBase.Cards.Base.Moat
|| c is DominionBase.Cards.Base2ndEdition.Moat
))
{
var icbMoat = wrapPanel1.Children.OfType().FirstOrDefault(
icb => icb.Card is Card
&& (icb.Card.Type == DominionBase.Cards.Base.TypeClass.Moat
|| icb.Card.Type == DominionBase.Cards.Base2ndEdition.TypeClass.Moat)
);
if (icbMoat != null)
{
cbAutoClick.IsChecked = true;
icbMoat.IsChecked = true;
ToggleButton_Checked(icbMoat, null);
}
}
else if (WMain.Settings != null && WMain.Settings.ChooserAutomaticallyRevealProvince
&& Choice.EventArgs == null && Choice.Source != null
&& (Choice.Source.Type == DominionBase.Cards.Cornucopia.TypeClass.Tournament
|| Choice.Source.Type == DominionBase.Cards.Cornucopia2ndEdition.TypeClass.Tournament)
&& Choice.ChoiceType == ChoiceType.Options
&& Choice.Text == "Do you want to reveal a Province from your hand?")
{
var tbYes = wrapPanel1.Children.OfType().FirstOrDefault(
tb => ((Option)tb.Tag).Text == DominionBase.ResourcesHelper.Get("Yes"));
if (tbYes != null)
{
cbAutoClick.IsChecked = true;
tbYes.IsChecked = true;
ToggleButton_Checked(tbYes, null);
}
}
}
}
}
#endregion Properties
public void ClearAutoYields(AutoYieldDuration duration)
{
AutoYields.ClearByDuration(duration);
}
private void FilterAutoYields()
{
if (Choice.Options == null)
return;
var anyRequired = Choice.Options.Any(o => o.IsRequired);
var children = wrapPanel1.Children.OfType().ToList();
foreach (var item in children)
{
if (item.Tag is Option option)
{
var action = AutoYields.GetAction(Choice.EventArgs.GetType(), option.Source.Type, option.Value, Choice.Triggers.FirstOrDefault()?.Type);
switch (action)
{
case AutoYieldAction.Skip:
wrapPanel1.Children.Remove(item);
break;
case AutoYieldAction.Yield:
if (!anyRequired)
SplitButton_Clicked(item, null);
break;
}
}
}
if (!anyRequired && wrapPanel1.Children.Count == 0)
BNone_Click(bNone, null);
}
private void ToggleButton_MouseLeave(object sender, MouseEventArgs e)
{
var button = (ToggleButton)sender;
var option = (Option)button.Tag;
HighlightSource(option.Source, HighlightMode.None);
}
private void ToggleButton_MouseEnter(object sender, MouseEventArgs e)
{
var button = (ToggleButton)sender;
var option = (Option)button.Tag;
HighlightSource(option.Source, HighlightMode.Primary);
}
private void tbText_MouseLeave(object sender, MouseEventArgs e)
{
HighlightSource(Choice.Triggers.FirstOrDefault() ?? Choice.Source, HighlightMode.None);
}
private void tbText_MouseEnter(object sender, MouseEventArgs e)
{
HighlightSource(Choice.Triggers.FirstOrDefault() ?? Choice.Source, HighlightMode.Primary);
}
private void HighlightSource(IGameObject source, HighlightMode mode)
{
Control gameObject = null;
if (Window.GetWindow(this) is WMain window && source != null)
gameObject = window.FindGameObject(source);
if (gameObject is CardStackControl csc)
csc.Highlight = mode;
else if (gameObject is SupplyControl sc)
sc.Highlight = mode;
// Also highlight "ModifiedBy" chain
if (source is Card card && card.ModifiedBy != null)
HighlightSource(card.ModifiedBy, mode == HighlightMode.None ? HighlightMode.None : HighlightMode.Secondary);
}
private int FindShortcutIndex(string text)
{
var inTag = false;
var inElement = false;
// Scan through the text to make sure we're not in an XML-like element or tag definition
// e.g. "5 Currency" would return 15, the index for 'C'
for (var index = 0; index < text.Length; index++)
{
if (!inTag && text[index] == '<')
{
inTag = true;
inElement = true;
}
if (inTag && text[index] == '>')
inTag = false;
if (inTag && text[index] == '/')
inElement = false;
if (inTag)
continue;
if ((char.IsUpper(text[index]) || (char.IsNumber(text[index]) && !inElement)) && !_usedHotkeys.Contains(text[index]))
{
_usedHotkeys.Add(text[index]);
return index;
}
}
return -1;
}
private void SupplyControl_SupplyClick(object sender, RoutedEventArgs e)
{
if ((e.Source as SupplyControl)?.Supply is Supply supply)
{
bOK.IsEnabled = false;
ChoiceResult = new ChoiceResult(supply);
if (ChoiceResult != null)
bOK.IsEnabled = true;
if (bOK.IsEnabled && ChoiceResult.Supply != null && cbAutoClick.IsChecked == true)
BOK_Click(bOK, null);
}
}
private void SplitButton_Clicked(object sender, RoutedEventArgs e)
{
if (sender is SplitButton button && button.Tag is Option option)
{
ChoiceResult = new ChoiceResult(new List { option.Text });
BOK_Click(bOK, null);
}
}
private void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
bool? isChecked = false;
object tag = (sender as FrameworkElement)?.Tag;
if (sender is ToggleButton button)
isChecked = button.IsChecked;
else if (sender is ucICardButton icb)
isChecked = icb.IsChecked;
bOK.IsEnabled = false;
switch (Choice.ChoiceType)
{
case ChoiceType.Options:
if (ChoiceResult == null)
ChoiceResult = new ChoiceResult(new List());
var option = ((Option)tag)?.Text;
if (Choice.Maximum == 1)
{
foreach (var chkdToggleButton in wrapPanel1.Children.OfType().Where(tb => ChoiceResult.Options.Contains(((Option)tb.Tag).Text)))
{
chkdToggleButton.IsChecked = false;
ChoiceResult.Options.Remove(((Option)chkdToggleButton.Tag).Text);
}
}
if (isChecked == true)
ChoiceResult.Options.Add(option);
else if (ChoiceResult.Options.Contains(option))
ChoiceResult.Options.Remove(option);
if ((Choice.Minimum > 0 || ChoiceResult.Options.Any()) &&
ChoiceResult.Options.Count >= Choice.Minimum &&
ChoiceResult.Options.Count <= Choice.Maximum)
bOK.IsEnabled = true;
break;
case ChoiceType.Cards:
case ChoiceType.SuppliesAndCards:
//case DominionBase.ChoiceType.Pile:
if (ChoiceResult == null)
ChoiceResult = new ChoiceResult(new CardCollection());
var card = tag as Card;
if (isChecked == true)
ChoiceResult.Cards.Add(card);
else if (ChoiceResult.Cards.Contains(card))
ChoiceResult.Cards.Remove(card);
if ((Choice.Minimum > 0 || ChoiceResult.Cards.Any()) &&
ChoiceResult.Cards.Count >= Choice.Minimum &&
ChoiceResult.Cards.Count <= Choice.Maximum)
bOK.IsEnabled = true;
break;
case ChoiceType.Supplies:
ChoiceResult = isChecked == true ? new ChoiceResult(tag as Supply) : null;
if (ChoiceResult != null)
bOK.IsEnabled = true;
break;
case ChoiceType.Boons:
if (ChoiceResult == null)
ChoiceResult = new ChoiceResult(new ItemCollection());
var boon = tag as IBoon;
if (isChecked == true)
ChoiceResult.Boons.Add(boon);
else if (ChoiceResult.Boons.Contains(boon))
ChoiceResult.Boons.Remove(boon);
if ((Choice.Minimum > 0 || ChoiceResult.Boons.Any()) &&
ChoiceResult.Boons.Count >= Choice.Minimum &&
ChoiceResult.Boons.Count <= Choice.Maximum)
bOK.IsEnabled = true;
break;
}
foreach (var control in wrapPanel1.Children.OfType())
{
var pButtonText = (Panel)((Border)control.Content).Child;
var option = ((Option)control.Tag).Text;
if (Choice.IsOrdered)
{
pButtonText.Visibility = Visibility.Visible;
var ordinal = string.Empty;
switch (Choice.ChoiceType)
{
case ChoiceType.Options:
if (ChoiceResult?.Options.Contains(option) == true)
ordinal = Utilities.Ordinal(ChoiceResult.Options.IndexOf(option) + 1);
break;
}
if (pButtonText.Children[0] is TextBlock textBlock)
textBlock.Text = ordinal != string.Empty ? $"{ordinal}: " : string.Empty;
}
}
foreach (var control in wrapPanel1.Children.OfType())
{
var card = control.Tag as Card;
if (Choice.IsOrdered)
{
switch (Choice.ChoiceType)
{
case ChoiceType.Cards:
//case DominionBase.ChoiceType.Pile:
if (ChoiceResult.Cards.Contains(card))
control.Order = ChoiceResult.Cards.IndexOf(card) + 1;
else
control.Order = 0;
break;
}
}
}
if (bOK.IsEnabled &&
(ChoiceResult.Supply != null ||
(ChoiceResult.Cards != null && (ChoiceResult.Cards.Count == Choice.Maximum || ChoiceResult.Cards.Count == Choice.Cards.Count())) ||
(ChoiceResult.Options != null && (ChoiceResult.Options.Count == Choice.Maximum || ChoiceResult.Options.Count == Choice.Options.Count)) ||
(ChoiceResult.Boons != null && (ChoiceResult.Boons.Count == Choice.Maximum || ChoiceResult.Boons.Count == Choice.Boons.Count()))
) && cbAutoClick.IsChecked == true)
BOK_Click(bOK, null);
}
private FrameworkElement CreateCardButton(IDisplayable card)
{
var icb = new ucICardButton
{
Tag = card,
Card = card,
IsOrdered = Choice.IsOrdered,
};
icb.CardButtonClick += ToggleButton_Checked;
return icb;
}
private FrameworkElement CreateButton(object tag, EventArgs eventArgs, bool isRequired = false, ICommand command = null, string[] buttonTexts = null)
{
var wp = new WrapPanel { Orientation = Orientation.Horizontal, VerticalAlignment = VerticalAlignment.Center };
var border = new Border
{
Padding = new Thickness(10, 0, 10, 0),
Child = wp
};
ToggleButton tb;
if (eventArgs == null || isRequired)
{
tb = new ToggleButton
{
Command = command
};
if (command == null)
tb.Click += ToggleButton_Checked;
}
else
{
var cm = new ContextMenu
{
ItemsSource = Yields.Select(y => new MenuItem {
Header = string.Format(y, Choice.Triggers.FirstOrDefault()?.Name ?? "card"),
Tag = y
}),
Tag = tag
};
cm.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(Sbmi_Click));
tb = new SplitButton
{
MainButtonCommand = command,
DropDownContextMenu = cm,
};
if (command == null)
tb.Click += SplitButton_Clicked;
}
tb.Margin = new Thickness(5, 0, 5, 0);
tb.Height = double.NaN;
tb.Width = double.NaN;
tb.MinHeight = 40;
tb.MinWidth = 40;
tb.MaxHeight = 100;
tb.MaxWidth = 200;
tb.Background = (VisualBrush)FindResource("StandardBlueBrush");
tb.VerticalContentAlignment = VerticalAlignment.Stretch;
tb.Content = border;
tb.Tag = tag;
tb.MouseEnter += ToggleButton_MouseEnter;
tb.MouseLeave += ToggleButton_MouseLeave;
if (isRequired)
{
border.BorderThickness = new Thickness(2);
border.BorderBrush = Brushes.Crimson;
}
else
{
tb.ToolTip = "Optional";
}
if (buttonTexts != null)
{
var buttonText = new TextBlock { TextWrapping = TextWrapping.Wrap };
if (!string.IsNullOrEmpty(buttonTexts[0]))
{
var temp = (TextBlock)Utilities.RenderText(buttonTexts[0], NET_WPF.RenderSize.Small, false)[0];
buttonText.Inlines.AddRange(temp.Inlines.ToList());
}
if (!string.IsNullOrEmpty(buttonTexts[1]))
{
buttonText.Inlines.Add(new Run(buttonTexts[1].Substring(1))
{
FontWeight = FontWeights.Bold,
Foreground = Brushes.Crimson,
TextDecorations = TextDecorations.Underline
});
}
if (!string.IsNullOrEmpty(buttonTexts[2]))
{
var temp = (TextBlock)Utilities.RenderText(buttonTexts[2], NET_WPF.RenderSize.Small, false)[0];
buttonText.Inlines.AddRange(temp.Inlines.ToList());
}
wp.Children.Add(new AccessText { Width = 0, Text = buttonTexts[1] });
wp.Children.Add(buttonText);
}
//else
// //tb.Command = command;
// tb.MainButtonCommand = command;
return tb;
}
private void Sbmi_Click(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is MenuItem item && sender is ContextMenu cm && cm.Tag is Option option)
{
switch ((string)item.Tag)
{
case "Always for {0}":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Duration = AutoYieldDuration.Game,
Action = AutoYieldAction.Yield,
Source = option.Source.Type,
SourceValue = option.Value,
Target = Choice.Triggers.FirstOrDefault()?.Type
});
break;
case "Never for {0}":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Game,
Action = AutoYieldAction.Skip,
Target = Choice.Triggers.FirstOrDefault()?.Type
});
break;
case "Always for {0} this turn":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Duration = AutoYieldDuration.Turn,
Action = AutoYieldAction.Yield,
Source = option.Source.Type,
SourceValue = option.Value,
Target = Choice.Triggers.FirstOrDefault()?.Type
});
break;
case "No more for {0} this turn":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Turn,
Action = AutoYieldAction.Skip,
Target = Choice.Triggers.FirstOrDefault()?.Type
});
break;
case "Always this turn":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Turn,
Action = AutoYieldAction.Yield,
Target = null
});
break;
case "No more this turn":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Turn,
Action = AutoYieldAction.Skip,
Target = null
});
break;
case "Always":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Game,
Action = AutoYieldAction.Yield,
Target = null
});
break;
case "Never":
AutoYields.Add(new AutoYield
{
Event = Choice.EventArgs.GetType(),
Source = option.Source.Type,
SourceValue = option.Value,
Duration = AutoYieldDuration.Game,
Action = AutoYieldAction.Skip,
Target = null
});
break;
default:
return;
}
FilterAutoYields();
}
}
private void BOK_Click(object sender, RoutedEventArgs e)
{
((UIElement)sender).IsEnabled = false;
if (ChoiceResult == null)
ChoiceResult = new ChoiceResult();
if (bReorder.Visibility == Visibility.Visible)
{
ChoiceResult = new ChoiceResult(new CardCollection());
// Must add the cards back in reverse order
var cardViewModels = (lbReorder.DataContext as ViewModel.CardListViewModel)?.Cards.Reverse();
if (cardViewModels != null)
foreach (var cvm in cardViewModels)
ChoiceResult.Cards.Add(cvm.Card);
}
else if (bHidden.Visibility == Visibility.Visible)
{
ChoiceResult = new ChoiceResult(new CardCollection());
// Must add the cards back in reverse order
var cardViewModels = (lbHidden.DataContext as ViewModel.CardListViewModel)?.Cards.Reverse();
if (cardViewModels != null)
foreach (var cvm in cardViewModels)
ChoiceResult.Cards.Add(cvm.Card);
}
foreach (var sc in SupplyControls)
sc.SupplyClick -= SupplyControl_SupplyClick;
_LastChoiceId = Choice.UniqueId;
_LastChoiceResult = ChoiceResult;
RaiseEvent(new RoutedEventArgs(ChooserOkClickEvent));
((UIElement)sender).IsEnabled = true;
}
private void BNone_Click(object sender, RoutedEventArgs e)
{
cbAutoClick.IsChecked = false;
foreach (FrameworkElement control in wrapPanel1.Children)
{
if (control is ToggleButton button)
{
button.IsChecked = false;
ToggleButton_Checked(control, null);
}
else if (control is ucICardButton cb)
{
cb.IsChecked = false;
ToggleButton_Checked(control, null);
}
}
BOK_Click(bOK, null);
}
private void BAll_Click(object sender, RoutedEventArgs e)
{
cbAutoClick.IsChecked = false;
foreach (FrameworkElement control in wrapPanel1.Children)
{
if (control is ToggleButton button)
button.IsChecked = false;
else if (control is ucICardButton cb)
cb.IsChecked = false;
ToggleButton_Checked(control, null);
}
foreach (FrameworkElement control in wrapPanel1.Children)
{
if (control is ToggleButton button)
button.IsChecked = true;
else if (control is ucICardButton cb)
cb.IsChecked = true;
ToggleButton_Checked(control, null);
}
BOK_Click(bOK, null);
}
private void LbReorder_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (Choice == null)
return;
if (((ItemCollection)sender).Count >= Choice.Minimum &&
((ItemCollection)sender).Count <= Choice.Maximum)
bOK.IsEnabled = true;
else
bOK.IsEnabled = false;
}
private void LbCardPool_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if ((e.Source as ListBox)?.SelectedItem != null)
{
var item = ((ListBox)e.Source).SelectedItem;
var list = ((ListBox)e.Source).ItemsSource as IList;
list?.Remove(item);
(lbReorder.ItemsSource as IList)?.Add(item);
}
}
private void LbReorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if ((e.Source as ListBox)?.SelectedItem != null && lbCardPool.Visibility == Visibility.Visible)
{
var item = ((ListBox)e.Source).SelectedItem;
var list = ((ListBox)e.Source).ItemsSource as IList;
list?.Remove(item);
(lbCardPool.ItemsSource as IList)?.Add(item);
}
}
}
}