public GameOutcomeGroupControl(GameOutcomeGroup outcomeGroup)
        {
            InitializeComponent();

            this.ProbabilityControlsItemsControl.ItemsSource = this.outcomeProbabilityControls;

            if (outcomeGroup.RankRequirement != null && outcomeGroup.RankRequirement.GetCurrency() != null)
            {
                this.RankGroupGrid.Visibility = Visibility.Visible;

                UserCurrencyViewModel rankCurrency = outcomeGroup.RankRequirement.GetCurrency();
                this.RankTypeComboBox.SelectedItem    = rankCurrency;
                this.RankMinimumComboBox.SelectedItem = outcomeGroup.RankRequirement.RequiredRank;
            }
            else
            {
                this.PreDefinedGroupGrid.Visibility    = Visibility.Visible;
                this.PreDefinedGroupNameTextBlock.Text = EnumHelper.GetEnumName(outcomeGroup.Role);
            }

            foreach (GameOutcomeProbability probability in outcomeGroup.Probabilities)
            {
                this.AddProbability(new GameOutcomeProbabilityControl(probability));
            }
        }
        public async Task <GameOutcomeGroup> GetOutcomeGroup()
        {
            GameOutcomeGroup group     = null;
            string           groupName = null;

            if (this.RankGroupGrid.Visibility != Visibility.Visible)
            {
                UserRole role = EnumHelper.GetEnumValueFromString <UserRole>((string)this.PreDefinedGroupNameTextBlock.Text);
                groupName = EnumHelper.GetEnumName(role);
                group     = new GameOutcomeGroup(role);
            }
            else if (this.RankTypeComboBox.SelectedIndex >= 0 && this.RankMinimumComboBox.SelectedIndex >= 0)
            {
                UserCurrencyRequirementViewModel rankRequirement = new UserCurrencyRequirementViewModel((UserCurrencyViewModel)this.RankTypeComboBox.SelectedItem, (UserRankViewModel)this.RankMinimumComboBox.SelectedItem);
                groupName = rankRequirement.GetCurrency().Name + " - " + rankRequirement.RankName;
                group     = new GameOutcomeGroup(rankRequirement);
            }
            else
            {
                await MessageBoxHelper.ShowMessageDialog("A group is missing the Rank Type & Rank Name");

                return(null);
            }

            if (group != null && !string.IsNullOrEmpty(groupName))
            {
                foreach (GameOutcomeProbabilityControl probabilityControl in this.outcomeProbabilityControls)
                {
                    group.Probabilities.Add(probabilityControl.GetOutcomeProbability());
                }

                if (group.Probabilities.Sum(p => p.Probability) > 100)
                {
                    await MessageBoxHelper.ShowMessageDialog("The group " + groupName + " can not have a combined probability of more than 100%");

                    return(null);
                }
            }

            return(group);
        }
        private async void GameTypeComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            await this.RunAsyncOperation(async() =>
            {
                if (this.GameTypeComboBox.SelectedIndex >= 0)
                {
                    this.CurrencyGrid.IsEnabled = true;

                    this.MultiplayerGameDetailsGrid.Visibility = Visibility.Collapsed;
                    this.OutcomesDetailsGrid.Visibility        = Visibility.Collapsed;
                    this.UserCharityGameGrid.Visibility        = Visibility.Collapsed;

                    GameTypeEnum gameType = EnumHelper.GetEnumValueFromString <GameTypeEnum>((string)this.GameTypeComboBox.SelectedItem);

                    if (gameType == GameTypeEnum.OnlyOneWinner)
                    {
                        this.CurrencyRequirementTypeComboBox.SelectedItem = EnumHelper.GetEnumName(CurrencyRequirementTypeEnum.RequiredAmount);
                        this.CurrencyRequirementTypeComboBox.IsEnabled    = false;
                    }
                    else
                    {
                        this.CurrencyRequirementTypeComboBox.SelectedIndex = -1;
                        this.CurrencyRequirementTypeComboBox.IsEnabled     = true;
                    }

                    if (gameType == GameTypeEnum.IndividualProbabilty || gameType == GameTypeEnum.OnlyOneWinner)
                    {
                        this.MultiplayerGameDetailsGrid.Visibility = Visibility.Visible;
                    }

                    if (gameType == GameTypeEnum.SinglePlayer || gameType == GameTypeEnum.IndividualProbabilty)
                    {
                        this.OutcomesDetailsGrid.Visibility = Visibility.Visible;

                        this.outcomeCommandControls.Clear();

                        GameOutcomeCommandControl outcomeControl = new GameOutcomeCommandControl(new GameOutcome("Win"));
                        await outcomeControl.Initialize(this);
                        this.outcomeCommandControls.Add(outcomeControl);

                        this.outcomeGroupControls.Clear();

                        GameOutcomeGroup userGroup = new GameOutcomeGroup(UserRole.User);
                        userGroup.Probabilities.Add(new GameOutcomeProbability(50, 25));
                        this.outcomeGroupControls.Add(new GameOutcomeGroupControl(userGroup));

                        GameOutcomeGroup subscriberGroup = new GameOutcomeGroup(UserRole.Subscriber);
                        subscriberGroup.Probabilities.Add(new GameOutcomeProbability(50, 25));
                        this.outcomeGroupControls.Add(new GameOutcomeGroupControl(subscriberGroup));

                        GameOutcomeGroup modGroup = new GameOutcomeGroup(UserRole.Mod);
                        modGroup.Probabilities.Add(new GameOutcomeProbability(50, 25));
                        this.outcomeGroupControls.Add(new GameOutcomeGroupControl(modGroup));
                    }

                    if (gameType == GameTypeEnum.UserCharity)
                    {
                        this.UserCharityGameGrid.Visibility = Visibility.Visible;
                    }
                }
            });
        }
        private async void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            await this.RunAsyncOperation(async() =>
            {
                if (string.IsNullOrEmpty(this.GameNameTextBox.Text))
                {
                    await MessageBoxHelper.ShowMessageDialog("Name is missing");
                    return;
                }

                if (string.IsNullOrEmpty(this.GameChatCommandTextBox.Text))
                {
                    await MessageBoxHelper.ShowMessageDialog("Commands is missing");
                    return;
                }

                if (this.GameChatCommandTextBox.Text.Any(c => !Char.IsLetterOrDigit(c) && !Char.IsWhiteSpace(c)))
                {
                    await MessageBoxHelper.ShowMessageDialog("Commands can only contain letters and numbers");
                    return;
                }

                foreach (PermissionsCommandBase command in ChannelSession.AllChatCommands)
                {
                    if (this.command != command && this.GameNameTextBox.Text.Equals(command.Name))
                    {
                        await MessageBoxHelper.ShowMessageDialog("There already exists a chat command with the same name");
                        return;
                    }
                }

                IEnumerable <string> commandStrings = this.GetCommandStrings();
                if (commandStrings.GroupBy(c => c).Where(g => g.Count() > 1).Count() > 0)
                {
                    await MessageBoxHelper.ShowMessageDialog("Each command string must be unique");
                    return;
                }

                foreach (PermissionsCommandBase command in ChannelSession.AllChatCommands)
                {
                    if (command.IsEnabled && this.GetExistingCommand() != command)
                    {
                        if (commandStrings.Any(c => command.Commands.Contains(c)))
                        {
                            await MessageBoxHelper.ShowMessageDialog("There already exists a chat command that uses one of the command strings you have specified");
                            return;
                        }
                    }
                }

                int cooldown = 0;
                if (!int.TryParse(this.GameCooldownTextBox.Text, out cooldown) || cooldown < 0)
                {
                    await MessageBoxHelper.ShowMessageDialog("Cooldown must be 0 or greater");
                    return;
                }

                if (this.GameLowestRoleAllowedComboBox.SelectedIndex < 0)
                {
                    await MessageBoxHelper.ShowMessageDialog("A permission level must be selected");
                    return;
                }

                if (this.GameTypeComboBox.SelectedIndex < 0)
                {
                    await MessageBoxHelper.ShowMessageDialog("A game type must be selected");
                    return;
                }
                GameTypeEnum gameType = EnumHelper.GetEnumValueFromString <GameTypeEnum>((string)this.GameTypeComboBox.SelectedItem);

                if (this.CurrencyTypeComboBox.SelectedIndex < 0 || this.CurrencyRequirementTypeComboBox.SelectedIndex < 0)
                {
                    await MessageBoxHelper.ShowMessageDialog("A currency type and requirement must be selected");
                    return;
                }

                int minimum = 0;
                int maximum = 0;

                CurrencyRequirementTypeEnum currencyRequirementType = EnumHelper.GetEnumValueFromString <CurrencyRequirementTypeEnum>((string)this.CurrencyRequirementTypeComboBox.SelectedItem);
                if (currencyRequirementType != CurrencyRequirementTypeEnum.NoCurrencyCost && (!int.TryParse(this.CurrencyMinimumCostTextBox.Text, out minimum) || minimum < 0))
                {
                    await MessageBoxHelper.ShowMessageDialog("The currency minimum must be 0 or greater");
                    return;
                }

                if (currencyRequirementType == CurrencyRequirementTypeEnum.MinimumAndMaximum && (!int.TryParse(this.CurrencyMaximumCostTextBox.Text, out maximum) || maximum <= minimum))
                {
                    await MessageBoxHelper.ShowMessageDialog("The currency maximum must be greater than the minimum");
                    return;
                }

                int gameLength      = 0;
                int minParticipants = 0;
                if (this.MultiplayerGameDetailsGrid.Visibility == Visibility.Visible)
                {
                    if (!int.TryParse(this.GameLengthTextBox.Text, out gameLength) || gameLength < 0)
                    {
                        await MessageBoxHelper.ShowMessageDialog("Game length must be 0 or greater");
                        return;
                    }

                    if (!int.TryParse(this.GameMinimumParticipantsTextBox.Text, out minParticipants) || minParticipants < 1)
                    {
                        await MessageBoxHelper.ShowMessageDialog("Minimum participants must be 1 or greater");
                        return;
                    }
                }

                List <GameOutcome> outcomes           = new List <GameOutcome>();
                List <GameOutcomeGroup> outcomeGroups = new List <GameOutcomeGroup>();
                if (gameType == GameTypeEnum.SinglePlayer || gameType == GameTypeEnum.IndividualProbabilty)
                {
                    foreach (GameOutcomeCommandControl commandControl in this.outcomeCommandControls)
                    {
                        GameOutcome outcome = await commandControl.GetOutcome();
                        if (outcome == null)
                        {
                            return;
                        }
                        outcomes.Add(outcome);
                    }

                    if (outcomes.Select(o => o.Name).GroupBy(n => n).Where(g => g.Count() > 1).Count() > 0)
                    {
                        await MessageBoxHelper.ShowMessageDialog("Each outcome must have a unique name");
                        return;
                    }

                    foreach (GameOutcomeGroupControl groupControl in this.outcomeGroupControls)
                    {
                        GameOutcomeGroup group = await groupControl.GetOutcomeGroup();
                        if (group == null)
                        {
                            return;
                        }
                        outcomeGroups.Add(group);
                        for (int i = 0; i < outcomes.Count; i++)
                        {
                            group.Probabilities[i].OutcomeName = outcomes[i].Name;
                        }
                    }
                }

                UserRole permissionsRole = EnumHelper.GetEnumValueFromString <UserRole>((string)this.GameLowestRoleAllowedComboBox.SelectedItem);

                if (this.command != null)
                {
                    ChannelSession.Settings.GameCommands.Remove(this.command);
                }

                UserCurrencyRequirementViewModel currencyRequirement = new UserCurrencyRequirementViewModel((UserCurrencyViewModel)this.CurrencyTypeComboBox.SelectedItem, minimum, maximum);
                if (gameType == GameTypeEnum.SinglePlayer)
                {
                    this.command = new SinglePlayerGameCommand(this.GameNameTextBox.Text, this.GetCommandStrings(), permissionsRole, cooldown, currencyRequirement, currencyRequirementType, outcomes,
                                                               outcomeGroups, this.LoseLeftoverProbabilityCommandControl.GetCommand());
                }
                else if (gameType == GameTypeEnum.IndividualProbabilty)
                {
                    IndividualProbabilityGameCommand ipCommand = new IndividualProbabilityGameCommand(this.GameNameTextBox.Text, this.GetCommandStrings(), permissionsRole, cooldown,
                                                                                                      currencyRequirement, currencyRequirementType, outcomes, outcomeGroups, this.LoseLeftoverProbabilityCommandControl.GetCommand(), gameLength, minParticipants);
                    ipCommand.GameStartedCommand    = this.GameStartedCommandControl.GetCommand();
                    ipCommand.GameEndedCommand      = this.GameEndedCommandControl.GetCommand();
                    ipCommand.UserJoinedCommand     = this.UserJoinedCommandControl.GetCommand();
                    ipCommand.NotEnoughUsersCommand = this.NotEnoughUsersCommandControl.GetCommand();
                    this.command = ipCommand;
                }
                else if (gameType == GameTypeEnum.OnlyOneWinner)
                {
                    OnlyOneWinnerGameCommand oowCommand = new OnlyOneWinnerGameCommand(this.GameNameTextBox.Text, this.GetCommandStrings(), permissionsRole, cooldown, currencyRequirement,
                                                                                       gameLength, minParticipants);
                    oowCommand.GameStartedCommand    = this.GameStartedCommandControl.GetCommand();
                    oowCommand.GameEndedCommand      = this.GameEndedCommandControl.GetCommand();
                    oowCommand.UserJoinedCommand     = this.UserJoinedCommandControl.GetCommand();
                    oowCommand.NotEnoughUsersCommand = this.NotEnoughUsersCommandControl.GetCommand();
                    this.command = oowCommand;
                }
                else if (gameType == GameTypeEnum.UserCharity)
                {
                    UserCharityGameCommand ucCommand = new UserCharityGameCommand(this.GameNameTextBox.Text, this.GetCommandStrings(), permissionsRole, cooldown, currencyRequirement,
                                                                                  currencyRequirementType, this.GiveToRandomUserCharityToggleButton.IsChecked.GetValueOrDefault());
                    ucCommand.UserParticipatedCommand = this.UserParticipatedCommandControl.GetCommand();
                    this.command = ucCommand;
                }

                ChannelSession.Settings.GameCommands.Add(this.command);

                await ChannelSession.SaveSettings();

                this.Close();
            });
        }