<commit_before>﻿using Playnite.Database;
using Playnite.SDK.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PlayniteUI.Controls
{
    public class GameMenu : ContextMenu
    {
        public bool ShowStartSection
        {
            get
            {
                return (bool)GetValue(ShowStartSectionProperty);
            }

            set
            {
                SetValue(ShowStartSectionProperty, value);
            }
        }

        public static readonly DependencyProperty ShowStartSectionProperty =
            DependencyProperty.Register("ShowStartSection", typeof(bool), typeof(GameMenu), new PropertyMetadata(true, ShowStartSectionPropertyChangedCallback));

        private static void ShowStartSectionPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var obj = sender as GameMenu;
            obj.InitializeItems();
        }

        private IResourceProvider resources;
        private GamesEditor editor;
        private readonly SynchronizationContext context;

        private Image startIcon;
        private Image removeIcon;
        private Image linksIcon;
        private Image favoriteIcon;
        private Image unFavoriteIcon;
        private Image hideIcon;
        private Image unHideIcon;
        private Image browseIcon;
        private Image shortcutIcon;
        private Image installIcon;
        private Image editIcon;


        public Game Game
        {
            get; set;
        }

        public List<Game> Games
        {
            get;  set;
        }

        static GameMenu()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GameMenu), new FrameworkPropertyMetadata(typeof(GameMenu)));
        }

        public GameMenu() : this(App.GamesEditor)
        {            
        }

        public GameMenu(GamesEditor editor)
        {
            startIcon = Images.GetImageFromResource("Images/MenuIcons/start.png");
            removeIcon = Images.GetImageFromResource("Images/MenuIcons/remove.png");
            linksIcon = Images.GetImageFromResource("Images/MenuIcons/link.png");
            favoriteIcon = Images.GetImageFromResource("Images/MenuIcons/favorite.png");
            unFavoriteIcon = Images.GetImageFromResource("Images/MenuIcons/favoriteEmpty.png");
            hideIcon = Images.GetImageFromResource("Images/MenuIcons/hideCrosed.png");
            unHideIcon = Images.GetImageFromResource("Images/MenuIcons/hide.png");
            browseIcon = Images.GetImageFromResource("Images/MenuIcons/folder.png");
            shortcutIcon = Images.GetImageFromResource("Images/MenuIcons/shortcut.png");
            installIcon = Images.GetImageFromResource("Images/MenuIcons/install.png");
            editIcon = Images.GetImageFromResource("Images/MenuIcons/edit.png");

            context = SynchronizationContext.Current;
            this.editor = editor;
            resources = new ResourceProvider();
            DataContextChanged += GameMenu_DataContextChanged;
            InitializeItems();
        }

        private void GameMenu_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (DataContext is GameViewEntry entry)
            {
                AssignGame(entry.Game);
            }
            else if (DataContext is IEnumerable<GameViewEntry> entries)
            {
                if (entries.Count() > 0)
                {
                    AssignGame((entries.First() as GameViewEntry).Game);
                }

                if (entries.Count() == 1)
                {
                    Games = null;
                }
                else
                {
                    Games = entries.Select(a => (a as GameViewEntry).Game).ToList();
                }
            }
            else if (DataContext is IList<object> entries2)
            {
                if (entries2.Count() > 0)
                {
                    AssignGame((entries2.First() as GameViewEntry).Game);
                }

                if (entries2.Count() == 1)
                {
                    Games = null;
                }
                else
                {
                    Games = entries2.Select(a => (a as GameViewEntry).Game).ToList();
                }
            }
            else
            {
                AssignGame(null);
                Games = null;
            }

            InitializeItems();
        }

        private void AssignGame(Game game)
        {
            if (Game != null)
            {
                Game.PropertyChanged -= Game_PropertyChanged;
            }

            Game = game;

            if (Game != null)
            {
                Game.PropertyChanged += Game_PropertyChanged;
            }
        }

        private void Game_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((new string[]
            {
                "State", "OtherTasks", "Links", "Favorite", "Hidden"
            }).Contains(e.PropertyName))
            {
                //Can be called from different threads when game database update is done
                context.Send((a) => InitializeItems(), null);
            }
        }

        public void InitializeItems()
        {
            Items.Clear();

            if (Games != null)
            {
                // Set Favorites
                var favoriteItem = new MenuItem()
                {
                    Header = resources.FindString("LOCFavoriteGame"),
                    Icon = favoriteIcon
                };

                favoriteItem.Click += (s, e) =>
                {
                    editor.SetFavoriteGames(Games, true);
                };

                Items.Add(favoriteItem);

                var unFavoriteItem = new MenuItem()
                {<commit_msg>Deadlock at startup<commit_after>﻿using Playnite.Database;
using Playnite.SDK.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PlayniteUI.Controls
{
    public class GameMenu : ContextMenu
    {
        public bool ShowStartSection
        {
            get
            {
                return (bool)GetValue(ShowStartSectionProperty);
            }

            set
            {
                SetValue(ShowStartSectionProperty, value);
            }
        }

        public static readonly DependencyProperty ShowStartSectionProperty =
            DependencyProperty.Register("ShowStartSection", typeof(bool), typeof(GameMenu), new PropertyMetadata(true, ShowStartSectionPropertyChangedCallback));

        private static void ShowStartSectionPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var obj = sender as GameMenu;
            obj.InitializeItems();
        }

        private IResourceProvider resources;
        private GamesEditor editor;
        private readonly SynchronizationContext context;

        private Image startIcon;
        private Image removeIcon;
        private Image linksIcon;
        private Image favoriteIcon;
        private Image unFavoriteIcon;
        private Image hideIcon;
        private Image unHideIcon;
        private Image browseIcon;
        private Image shortcutIcon;
        private Image installIcon;
        private Image editIcon;


        public Game Game
        {
            get; set;
        }

        public List<Game> Games
        {
            get;  set;
        }

        static GameMenu()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GameMenu), new FrameworkPropertyMetadata(typeof(GameMenu)));
        }

        public GameMenu() : this(App.GamesEditor)
        {            
        }

        public GameMenu(GamesEditor editor)
        {
            startIcon = Images.GetImageFromResource("Images/MenuIcons/start.png");
            removeIcon = Images.GetImageFromResource("Images/MenuIcons/remove.png");
            linksIcon = Images.GetImageFromResource("Images/MenuIcons/link.png");
            favoriteIcon = Images.GetImageFromResource("Images/MenuIcons/favorite.png");
            unFavoriteIcon = Images.GetImageFromResource("Images/MenuIcons/favoriteEmpty.png");
            hideIcon = Images.GetImageFromResource("Images/MenuIcons/hideCrosed.png");
            unHideIcon = Images.GetImageFromResource("Images/MenuIcons/hide.png");
            browseIcon = Images.GetImageFromResource("Images/MenuIcons/folder.png");
            shortcutIcon = Images.GetImageFromResource("Images/MenuIcons/shortcut.png");
            installIcon = Images.GetImageFromResource("Images/MenuIcons/install.png");
            editIcon = Images.GetImageFromResource("Images/MenuIcons/edit.png");

            context = SynchronizationContext.Current;
            this.editor = editor;
            resources = new ResourceProvider();
            DataContextChanged += GameMenu_DataContextChanged;
            InitializeItems();
        }

        private void GameMenu_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (DataContext is GameViewEntry entry)
            {
                AssignGame(entry.Game);
            }
            else if (DataContext is IEnumerable<GameViewEntry> entries)
            {
                if (entries.Count() > 0)
                {
                    AssignGame((entries.First() as GameViewEntry).Game);
                }

                if (entries.Count() == 1)
                {
                    Games = null;
                }
                else
                {
                    Games = entries.Select(a => (a as GameViewEntry).Game).ToList();
                }
            }
            else if (DataContext is IList<object> entries2)
            {
                if (entries2.Count() > 0)
                {
                    AssignGame((entries2.First() as GameViewEntry).Game);
                }

                if (entries2.Count() == 1)
                {
                    Games = null;
                }
                else
                {
                    Games = entries2.Select(a => (a as GameViewEntry).Game).ToList();
                }
            }
            else
            {
                AssignGame(null);
                Games = null;
            }

            InitializeItems();
        }

        private void AssignGame(Game game)
        {
            if (Game != null)
            {
                Game.PropertyChanged -= Game_PropertyChanged;
            }

            Game = game;

            if (Game != null)
            {
                Game.PropertyChanged += Game_PropertyChanged;
            }
        }

        private void Game_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((new string[]
            {
                "State", "OtherTasks", "Links", "Favorite", "Hidden"
            }).Contains(e.PropertyName))
            {
                //Can be called from different threads when game database update is done
                context.Post((a) => InitializeItems(), null);
            }
        }

        public void InitializeItems()
        {
            Items.Clear();

            if (Games != null)
            {
                // Set Favorites
                var favoriteItem = new MenuItem()
                {
                    Header = resources.FindString("LOCFavoriteGame"),
                    Icon = favoriteIcon
                };

                favoriteItem.Click += (s, e) =>
                {
                    editor.SetFavoriteGames(Games, true);
                };

                Items.Add(favoriteItem);

                var unFavoriteItem = new MenuItem()
                {
{'fraction_non_alphanumeric': 0.08312020460358056, 'fraction_numerical': 0.001438618925831202, 'mean_word_length': 1.601996257018091, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5922159', 'n_tokens_mistral': 3068, 'n_tokens_neox': 2911, 'n_words': 616}