Interaction logic for Balloon.xaml
Inheritance: System.Windows.Window
コード例 #1
0
ファイル: Agent.xaml.cs プロジェクト: kawatan/Apricot
        public Agent(string name)
        {
            InitializeComponent();

            this.characterName = name;
            this.cachedBitmapImageDictionary = new Dictionary<string, BitmapImage>();
            this.cachedMotionList = new List<Motion>();
            this.fadeStoryboardDictionary = new Dictionary<Storyboard, Window>();
            this.imageStoryboardDictionary = new Dictionary<Image, Storyboard>();
            this.queue = new System.Collections.Queue();
            this.motionQueue = new Queue<Motion>();
            this.ContextMenu = new ContextMenu();

            MenuItem opacityMenuItem = new MenuItem();
            MenuItem scalingMenuItem = new MenuItem();
            MenuItem refreshMenuItem = new MenuItem();
            MenuItem topmostMenuItem = new MenuItem();
            MenuItem showInTaskbarMenuItem = new MenuItem();
            MenuItem muteMenuItem = new MenuItem();
            MenuItem charactersMenuItem = new MenuItem();
            MenuItem updateMenuItem = new MenuItem();
            MenuItem exitMenuItem = new MenuItem();
            double opacity = 1;
            double scale = 2;

            opacityMenuItem.Header = Properties.Resources.Opacity;

            do
            {
                MenuItem menuItem = new MenuItem();

                menuItem.Header = String.Concat(((int)Math.Floor(opacity * 100)).ToString(System.Globalization.CultureInfo.CurrentCulture), Properties.Resources.Percent);
                menuItem.Tag = opacity;
                menuItem.Click += new RoutedEventHandler(delegate
                {
                    foreach (Window window in Application.Current.Windows)
                    {
                        Agent agent = window as Agent;

                        if (agent != null)
                        {
                            agent.opacity = (double)menuItem.Tag;

                            Storyboard storyboard1 = new Storyboard();
                            DoubleAnimation doubleAnimation1 = new DoubleAnimation(agent.Opacity, agent.opacity, TimeSpan.FromMilliseconds(500));

                            foreach (KeyValuePair<Storyboard, Window> kvp in agent.fadeStoryboardDictionary)
                            {
                                kvp.Key.Stop(kvp.Value);
                            }

                            agent.fadeStoryboardDictionary.Clear();

                            if (agent.Opacity < agent.opacity)
                            {
                                SineEase sineEase = new SineEase();

                                sineEase.EasingMode = EasingMode.EaseOut;
                                doubleAnimation1.EasingFunction = sineEase;
                            }
                            else if (agent.Opacity > agent.opacity)
                            {
                                SineEase sineEase = new SineEase();

                                sineEase.EasingMode = EasingMode.EaseIn;
                                doubleAnimation1.EasingFunction = sineEase;
                            }

                            doubleAnimation1.CurrentStateInvalidated += new EventHandler(delegate (object s, EventArgs e)
                            {
                                if (((Clock)s).CurrentState == ClockState.Filling)
                                {
                                    agent.Opacity = agent.opacity;
                                    storyboard1.Remove(agent);
                                    agent.fadeStoryboardDictionary.Remove(storyboard1);
                                }
                            });

                            storyboard1.Children.Add(doubleAnimation1);

                            Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(Window.OpacityProperty));

                            agent.fadeStoryboardDictionary.Add(storyboard1, agent);
                            agent.BeginStoryboard(storyboard1, HandoffBehavior.SnapshotAndReplace, true);

                            if (agent.balloon.Opacity != 1)
                            {
                                Storyboard storyboard2 = new Storyboard();
                                DoubleAnimation doubleAnimation2 = new DoubleAnimation(agent.balloon.Opacity, 1, TimeSpan.FromMilliseconds(500));
                                SineEase sineEase = new SineEase();

                                sineEase.EasingMode = EasingMode.EaseOut;

                                doubleAnimation2.EasingFunction = sineEase;
                                doubleAnimation2.CurrentStateInvalidated += new EventHandler(delegate (object s, EventArgs e)
                                {
                                    if (((Clock)s).CurrentState == ClockState.Filling)
                                    {
                                        agent.balloon.Opacity = 1;
                                        storyboard2.Remove(agent.balloon);
                                        agent.fadeStoryboardDictionary.Remove(storyboard2);
                                    }
                                });

                                storyboard2.Children.Add(doubleAnimation2);

                                Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath(Window.OpacityProperty));

                                agent.fadeStoryboardDictionary.Add(storyboard2, agent.balloon);
                                agent.balloon.BeginStoryboard(storyboard2, HandoffBehavior.SnapshotAndReplace, true);
                            }
                        }
                    }
                });

                opacityMenuItem.Items.Add(menuItem);
                opacity -= 0.1;
            } while (Math.Floor(opacity * 100) > 0);

            scalingMenuItem.Header = Properties.Resources.Scaling;

            do
            {
                MenuItem menuItem = new MenuItem();

                menuItem.Header = String.Concat(((int)Math.Floor(scale * 100)).ToString(System.Globalization.CultureInfo.CurrentCulture), Properties.Resources.Percent);
                menuItem.Tag = scale;
                menuItem.Click += new RoutedEventHandler(delegate
                {
                    foreach (Window window in Application.Current.Windows)
                    {
                        Agent agent = window as Agent;

                        if (agent != null)
                        {
                            agent.scale = (double)menuItem.Tag;

                            foreach (Character character in from character in Script.Instance.Characters where character.Name.Equals(agent.characterName) select character)
                            {
                                Storyboard storyboard = new Storyboard();
                                DoubleAnimation doubleAnimation1 = new DoubleAnimation(agent.ZoomScaleTransform.ScaleX, agent.scale, TimeSpan.FromMilliseconds(500));
                                DoubleAnimation doubleAnimation2 = new DoubleAnimation(agent.ZoomScaleTransform.ScaleY, agent.scale, TimeSpan.FromMilliseconds(500));
                                DoubleAnimation doubleAnimation3 = new DoubleAnimation(agent.LayoutRoot.Width, character.Size.Width * agent.scale, TimeSpan.FromMilliseconds(500));
                                DoubleAnimation doubleAnimation4 = new DoubleAnimation(agent.LayoutRoot.Height, character.Size.Height * agent.scale, TimeSpan.FromMilliseconds(500));

                                if (agent.scaleStoryboard != null)
                                {
                                    agent.scaleStoryboard.Stop(agent.LayoutRoot);
                                }

                                if (agent.ZoomScaleTransform.ScaleX < agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseOut;
                                    doubleAnimation1.EasingFunction = sineEase;
                                }
                                else if (agent.ZoomScaleTransform.ScaleX > agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseIn;
                                    doubleAnimation1.EasingFunction = sineEase;
                                }

                                if (agent.ZoomScaleTransform.ScaleY < agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseOut;
                                    doubleAnimation2.EasingFunction = sineEase;
                                }
                                else if (agent.ZoomScaleTransform.ScaleY > agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseIn;
                                    doubleAnimation2.EasingFunction = sineEase;
                                }

                                if (agent.LayoutRoot.Width < character.Size.Width * agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseOut;
                                    doubleAnimation3.EasingFunction = sineEase;
                                }
                                else if (agent.LayoutRoot.Width > character.Size.Width * agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseIn;
                                    doubleAnimation3.EasingFunction = sineEase;
                                }

                                if (agent.LayoutRoot.Height < character.Size.Height * agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseOut;
                                    doubleAnimation4.EasingFunction = sineEase;
                                }
                                else if (agent.LayoutRoot.Height > character.Size.Height * agent.scale)
                                {
                                    SineEase sineEase = new SineEase();

                                    sineEase.EasingMode = EasingMode.EaseIn;
                                    doubleAnimation4.EasingFunction = sineEase;
                                }

                                storyboard.CurrentStateInvalidated += new EventHandler(delegate (object s, EventArgs e)
                                {
                                    if (((Clock)s).CurrentState == ClockState.Filling)
                                    {
                                        agent.ZoomScaleTransform.ScaleX = agent.scale;
                                        agent.ZoomScaleTransform.ScaleY = agent.scale;

                                        foreach (Character c in from c in Script.Instance.Characters where c.Name.Equals(agent.characterName) select c)
                                        {
                                            agent.LayoutRoot.Width = c.Size.Width * agent.scale;
                                            agent.LayoutRoot.Height = c.Size.Height * agent.scale;
                                        }

                                        storyboard.Remove(agent.LayoutRoot);
                                        agent.scaleStoryboard = null;
                                    }
                                });
                                storyboard.Children.Add(doubleAnimation1);
                                storyboard.Children.Add(doubleAnimation2);
                                storyboard.Children.Add(doubleAnimation3);
                                storyboard.Children.Add(doubleAnimation4);

                                Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("(0).(1).(2)", ContentControl.ContentProperty, Canvas.RenderTransformProperty, ScaleTransform.ScaleXProperty));
                                Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("(0).(1).(2)", ContentControl.ContentProperty, Canvas.RenderTransformProperty, ScaleTransform.ScaleYProperty));
                                Storyboard.SetTargetProperty(doubleAnimation3, new PropertyPath(ContentControl.WidthProperty));
                                Storyboard.SetTargetProperty(doubleAnimation4, new PropertyPath(ContentControl.HeightProperty));

                                agent.scaleStoryboard = storyboard;
                                agent.LayoutRoot.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, true);
                            }
                        }
                    }
                });

                scalingMenuItem.Items.Add(menuItem);
                scale -= 0.25;
            } while (Math.Floor(scale * 100) > 0);

            refreshMenuItem.Header = Properties.Resources.Refresh;
            refreshMenuItem.Click += new RoutedEventHandler(delegate
            {
                foreach (Window window in Application.Current.Windows)
                {
                    Agent agent = window as Agent;

                    if (agent != null)
                    {
                        agent.Render();
                    }
                }
            });
            topmostMenuItem.Header = Properties.Resources.Topmost;
            topmostMenuItem.IsCheckable = true;
            topmostMenuItem.Click += new RoutedEventHandler(delegate
            {
                foreach (Window window in Application.Current.Windows)
                {
                    if (window is Agent && window == Application.Current.MainWindow)
                    {
                        window.Topmost = topmostMenuItem.IsChecked;
                    }
                }
            });
            showInTaskbarMenuItem.Header = Properties.Resources.ShowInTaskbar;
            showInTaskbarMenuItem.IsCheckable = true;
            showInTaskbarMenuItem.Click += new RoutedEventHandler(delegate
            {
                foreach (Window window in Application.Current.Windows)
                {
                    if (window is Agent)
                    {
                        window.ShowInTaskbar = showInTaskbarMenuItem.IsChecked;
                    }
                }
            });
            muteMenuItem.Header = Properties.Resources.Mute;
            muteMenuItem.IsCheckable = true;
            muteMenuItem.Click += new RoutedEventHandler(delegate
            {
                foreach (Window window in Application.Current.Windows)
                {
                    Agent agent = window as Agent;

                    if (agent != null)
                    {
                        agent.isMute = muteMenuItem.IsChecked;
                    }
                }
            });
            charactersMenuItem.Header = Properties.Resources.Characters;
            updateMenuItem.Header = Properties.Resources.Update;
            updateMenuItem.Click += new RoutedEventHandler(delegate
            {
                Script.Instance.Update(true);
            });
            exitMenuItem.Header = Properties.Resources.Exit;
            exitMenuItem.Click += new RoutedEventHandler(delegate
            {
                if (Script.Instance.Enabled)
                {
                    Script.Instance.Enabled = false;
                }
            });

            this.ContextMenu.Items.Add(opacityMenuItem);
            this.ContextMenu.Items.Add(scalingMenuItem);
            this.ContextMenu.Items.Add(refreshMenuItem);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(topmostMenuItem);
            this.ContextMenu.Items.Add(showInTaskbarMenuItem);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(muteMenuItem);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(charactersMenuItem);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(updateMenuItem);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(exitMenuItem);
            this.ContextMenu.Opened += new RoutedEventHandler(delegate
            {
                Agent agent = Application.Current.MainWindow as Agent;

                if (agent != null)
                {
                    foreach (MenuItem menuItem in opacityMenuItem.Items)
                    {
                        menuItem.IsChecked = Math.Floor((double)menuItem.Tag * 100) == Math.Floor(agent.Opacity * 100);
                    }

                    foreach (MenuItem menuItem in scalingMenuItem.Items)
                    {
                        menuItem.IsChecked = Math.Floor((double)menuItem.Tag * 100) == Math.Floor(agent.ZoomScaleTransform.ScaleX * 100) && Math.Floor((double)menuItem.Tag * 100) == Math.Floor(agent.ZoomScaleTransform.ScaleY * 100);
                    }

                    topmostMenuItem.IsChecked = agent.Topmost;
                    showInTaskbarMenuItem.IsChecked = agent.ShowInTaskbar;
                    muteMenuItem.IsChecked = agent.isMute;

                    List<MenuItem> menuItemList = new List<MenuItem>(charactersMenuItem.Items.Cast<MenuItem>());
                    HashSet<string> pathHashSet = new HashSet<string>();
                    LinkedList<KeyValuePair<Character, string>> characterLinkedList = new LinkedList<KeyValuePair<Character, string>>();

                    foreach (Character character in Script.Instance.Characters)
                    {
                        string path = Path.IsPathRooted(character.Script) ? character.Script : Path.GetFullPath(character.Script);

                        if (!pathHashSet.Contains(path))
                        {
                            pathHashSet.Add(path);
                        }

                        characterLinkedList.AddLast(new KeyValuePair<Character, string>(character, path));
                    }

                    List<KeyValuePair<string, string>> keyValuePairList = (from fileName in Directory.EnumerateFiles(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "*", SearchOption.AllDirectories) let extension = Path.GetExtension(fileName) let isZip = extension.Equals(".zip", StringComparison.OrdinalIgnoreCase) where isZip || extension.Equals(".xml", StringComparison.OrdinalIgnoreCase) select new KeyValuePair<bool, string>(isZip, fileName)).Concat(from path in pathHashSet select new KeyValuePair<bool, string>(Path.GetExtension(path).Equals(".zip", StringComparison.OrdinalIgnoreCase), path)).Aggregate<KeyValuePair<bool, string>, List<KeyValuePair<string, string>>>(new List<KeyValuePair<string, string>>(), (list, kvp1) =>
                    {
                        if (!list.Exists(delegate (KeyValuePair<string, string> kvp2)
                        {
                            return kvp2.Value.Equals(kvp1.Value);
                        }))
                        {
                            if (kvp1.Key)
                            {
                                FileStream fs = null;

                                try
                                {
                                    fs = new FileStream(kvp1.Value, FileMode.Open, FileAccess.Read, FileShare.Read);

                                    using (ZipArchive zipArchive = new ZipArchive(fs))
                                    {
                                        fs = null;

                                        foreach (ZipArchiveEntry zipArchiveEntry in from zipArchiveEntry in zipArchive.Entries where zipArchiveEntry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase) select zipArchiveEntry)
                                        {
                                            Stream stream = null;

                                            try
                                            {
                                                stream = zipArchiveEntry.Open();

                                                foreach (string attribute in from attribute in ((System.Collections.IEnumerable)XDocument.Load(stream).XPathEvaluate("/script/character/@name")).Cast<XAttribute>() select attribute.Value)
                                                {
                                                    list.Add(new KeyValuePair<string, string>(attribute, kvp1.Value));
                                                }
                                            }
                                            catch
                                            {
                                                return list;
                                            }
                                            finally
                                            {
                                                if (stream != null)
                                                {
                                                    stream.Close();
                                                }
                                            }
                                        }
                                    }
                                }
                                finally
                                {
                                    if (fs != null)
                                    {
                                        fs.Close();
                                    }
                                }
                            }
                            else
                            {
                                FileStream fs = null;

                                try
                                {
                                    fs = new FileStream(kvp1.Value, FileMode.Open, FileAccess.Read, FileShare.Read);

                                    foreach (string attribute in from attribute in ((System.Collections.IEnumerable)XDocument.Load(fs).XPathEvaluate("/script/character/@name")).Cast<XAttribute>() select attribute.Value)
                                    {
                                        list.Add(new KeyValuePair<string, string>(attribute, kvp1.Value));
                                    }
                                }
                                catch
                                {
                                    return list;
                                }
                                finally
                                {
                                    if (fs != null)
                                    {
                                        fs.Close();
                                    }
                                }
                            }
                        }

                        return list;
                    });

                    charactersMenuItem.Items.Clear();

                    keyValuePairList.Sort(delegate (KeyValuePair<string, string> kvp1, KeyValuePair<string, string> kvp2)
                    {
                        return String.Compare(kvp1.Key, kvp2.Key, StringComparison.CurrentCulture);
                    });
                    keyValuePairList.ForEach(delegate (KeyValuePair<string, string> kvp)
                    {
                        for (LinkedListNode<KeyValuePair<Character, string>> nextLinkedListNode = characterLinkedList.First; nextLinkedListNode != null; nextLinkedListNode = nextLinkedListNode.Next)
                        {
                            if (nextLinkedListNode.Value.Key.Name.Equals(kvp.Key) && nextLinkedListNode.Value.Value.Equals(kvp.Value))
                            {
                                MenuItem selectedMenuItem = menuItemList.Find(delegate (MenuItem menuItem)
                                {
                                    return kvp.Key.Equals(menuItem.Header as string) && kvp.Value.Equals(menuItem.Tag as string) && (menuItem.IsChecked || menuItem.HasItems);
                                });

                                if (selectedMenuItem == null)
                                {
                                    selectedMenuItem = new MenuItem();
                                    selectedMenuItem.Header = kvp.Key;
                                    selectedMenuItem.Tag = kvp.Value;
                                }
                                else
                                {
                                    selectedMenuItem.Items.Clear();
                                    menuItemList.Remove(selectedMenuItem);
                                }

                                charactersMenuItem.Items.Add(selectedMenuItem);

                                List<MenuItem> childMenuItemList = new List<MenuItem>();
                                Dictionary<string, SortedSet<int>> dictionary = new Dictionary<string, SortedSet<int>>();
                                List<string> motionTypeList = new List<string>();

                                this.cachedMotionList.ForEach(delegate (Motion motion)
                                {
                                    if (motion.Type != null)
                                    {
                                        SortedSet<int> sortedSet;

                                        if (dictionary.TryGetValue(motion.Type, out sortedSet))
                                        {
                                            if (!sortedSet.Contains(motion.ZIndex))
                                            {
                                                sortedSet.Add(motion.ZIndex);
                                            }
                                        }
                                        else
                                        {
                                            sortedSet = new SortedSet<int>();
                                            sortedSet.Add(motion.ZIndex);
                                            dictionary.Add(motion.Type, sortedSet);
                                            motionTypeList.Add(motion.Type);
                                        }
                                    }
                                });

                                motionTypeList.Sort(delegate (string s1, string s2)
                                {
                                    return String.Compare(s1, s2, StringComparison.CurrentCulture);
                                });
                                motionTypeList.ForEach(delegate (string type)
                                {
                                    foreach (MenuItem menuItem in selectedMenuItem.Items)
                                    {
                                        if (type.Equals(menuItem.Header as string))
                                        {
                                            if (nextLinkedListNode.Value.Key.HasTypes)
                                            {
                                                menuItem.IsChecked = nextLinkedListNode.Value.Key.Types.Contains(menuItem.Header as string);
                                            }
                                            else
                                            {
                                                menuItem.IsChecked = false;
                                            }

                                            childMenuItemList.Add(menuItem);

                                            return;
                                        }
                                    }

                                    MenuItem childMenuItem = new MenuItem();

                                    childMenuItem.Header = type;
                                    childMenuItem.Tag = nextLinkedListNode.Value.Key.Name;
                                    childMenuItem.Click += new RoutedEventHandler(delegate
                                    {
                                        string tag = childMenuItem.Tag as string;

                                        if (tag != null)
                                        {
                                            foreach (Character c in from c in Script.Instance.Characters where c.Name.Equals(tag) select c)
                                            {
                                                foreach (Window window in Application.Current.Windows)
                                                {
                                                    Agent a = window as Agent;

                                                    if (a != null && c.Name.Equals(a.characterName))
                                                    {
                                                        string header = childMenuItem.Header as string;

                                                        a.Render();

                                                        if (c.Types.Contains(header))
                                                        {
                                                            c.Types.Remove(header);
                                                        }
                                                        else if (header != null)
                                                        {
                                                            SortedSet<int> sortedSet1;

                                                            if (dictionary.TryGetValue(header, out sortedSet1))
                                                            {
                                                                foreach (string s in c.Types.ToArray())
                                                                {
                                                                    SortedSet<int> sortedSet2;

                                                                    if (dictionary.TryGetValue(s, out sortedSet2) && sortedSet1.SequenceEqual(sortedSet2))
                                                                    {
                                                                        c.Types.Remove(s);
                                                                    }
                                                                }
                                                            }

                                                            c.Types.Add(header);
                                                        }

                                                        foreach (Image image in a.Canvas.Children.Cast<Image>())
                                                        {
                                                            Image i = image;
                                                            Motion motion = i.Tag as Motion;

                                                            if (motion != null)
                                                            {
                                                                List<string> typeList = null;
                                                                bool isVisible;

                                                                if (motion.Type == null)
                                                                {
                                                                    typeList = new List<string>();
                                                                    a.cachedMotionList.ForEach(delegate (Motion m)
                                                                    {
                                                                        if (m.ZIndex == motion.ZIndex)
                                                                        {
                                                                            typeList.Add(m.Type);
                                                                        }
                                                                    });
                                                                }

                                                                if (typeList == null)
                                                                {
                                                                    if (c.HasTypes)
                                                                    {
                                                                        typeList = new List<string>();
                                                                        a.cachedMotionList.ForEach(delegate (Motion m)
                                                                        {
                                                                            if (m.ZIndex == motion.ZIndex && c.Types.Contains(m.Type))
                                                                            {
                                                                                typeList.Add(m.Type);
                                                                            }
                                                                        });
                                                                        isVisible = typeList.Count > 0 && typeList.LastIndexOf(motion.Type) == typeList.Count - 1;
                                                                    }
                                                                    else
                                                                    {
                                                                        isVisible = false;
                                                                    }
                                                                }
                                                                else if (c.HasTypes)
                                                                {
                                                                    isVisible = !typeList.Exists(delegate (string t)
                                                                    {
                                                                        return c.Types.Contains(t);
                                                                    });
                                                                }
                                                                else
                                                                {
                                                                    isVisible = true;
                                                                }

                                                                if (isVisible && (i.Visibility != Visibility.Visible || i.OpacityMask != null))
                                                                {
                                                                    LinearGradientBrush linearGradientBrush = i.OpacityMask as LinearGradientBrush;

                                                                    if (linearGradientBrush == null)
                                                                    {
                                                                        GradientStopCollection gradientStopCollection = new GradientStopCollection();

                                                                        gradientStopCollection.Add(new GradientStop(Color.FromArgb(0, 0, 0, 0), 0));
                                                                        gradientStopCollection.Add(new GradientStop(Color.FromArgb(0, 0, 0, 0), 1));

                                                                        i.OpacityMask = linearGradientBrush = new LinearGradientBrush(gradientStopCollection, new Point(0.5, 0), new Point(0.5, 1));
                                                                    }

                                                                    Storyboard storyboard;
                                                                    ColorAnimation colorAnimation1 = new ColorAnimation(linearGradientBrush.GradientStops[0].Color, Color.FromArgb(Byte.MaxValue, 0, 0, 0), TimeSpan.FromMilliseconds(250));
                                                                    ColorAnimation colorAnimation2 = new ColorAnimation(linearGradientBrush.GradientStops[1].Color, Color.FromArgb(Byte.MaxValue, 0, 0, 0), TimeSpan.FromMilliseconds(250));
                                                                    SineEase sineEase1 = new SineEase();
                                                                    SineEase sineEase2 = new SineEase();

                                                                    if (a.imageStoryboardDictionary.TryGetValue(i, out storyboard))
                                                                    {
                                                                        storyboard.Stop(i);
                                                                        a.imageStoryboardDictionary[i] = storyboard = new Storyboard();
                                                                    }
                                                                    else
                                                                    {
                                                                        storyboard = new Storyboard();
                                                                        a.imageStoryboardDictionary.Add(i, storyboard);
                                                                    }

                                                                    sineEase1.EasingMode = sineEase2.EasingMode = EasingMode.EaseInOut;

                                                                    colorAnimation1.EasingFunction = sineEase1;
                                                                    colorAnimation2.BeginTime = TimeSpan.FromMilliseconds(250);
                                                                    colorAnimation2.EasingFunction = sineEase2;

                                                                    storyboard.CurrentStateInvalidated += new EventHandler(delegate (object s, EventArgs e)
                                                                    {
                                                                        if (((Clock)s).CurrentState == ClockState.Filling)
                                                                        {
                                                                            i.OpacityMask = null;
                                                                            a.Render();
                                                                            storyboard.Remove(i);
                                                                            a.imageStoryboardDictionary.Remove(i);
                                                                        }
                                                                    });
                                                                    storyboard.Children.Add(colorAnimation1);
                                                                    storyboard.Children.Add(colorAnimation2);

                                                                    Storyboard.SetTargetProperty(colorAnimation1, new PropertyPath("(0).(1)[0].(2)", Image.OpacityMaskProperty, LinearGradientBrush.GradientStopsProperty, GradientStop.ColorProperty));
                                                                    Storyboard.SetTargetProperty(colorAnimation2, new PropertyPath("(0).(1)[1].(2)", Image.OpacityMaskProperty, LinearGradientBrush.GradientStopsProperty, GradientStop.ColorProperty));

                                                                    i.Visibility = Visibility.Visible;
                                                                    i.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, true);
                                                                }
                                                                else if (!isVisible && (i.Visibility == Visibility.Visible || i.OpacityMask != null))
                                                                {
                                                                    LinearGradientBrush linearGradientBrush = i.OpacityMask as LinearGradientBrush;

                                                                    if (linearGradientBrush == null)
                                                                    {
                                                                        GradientStopCollection gradientStopCollection = new GradientStopCollection();

                                                                        gradientStopCollection.Add(new GradientStop(Color.FromArgb(Byte.MaxValue, 0, 0, 0), 0));
                                                                        gradientStopCollection.Add(new GradientStop(Color.FromArgb(Byte.MaxValue, 0, 0, 0), 1));

                                                                        i.OpacityMask = linearGradientBrush = new LinearGradientBrush(gradientStopCollection, new Point(0.5, 0), new Point(0.5, 1));
                                                                    }

                                                                    Storyboard storyboard;
                                                                    ColorAnimation colorAnimation1 = new ColorAnimation(linearGradientBrush.GradientStops[0].Color, Color.FromArgb(0, 0, 0, 0), TimeSpan.FromMilliseconds(250));
                                                                    ColorAnimation colorAnimation2 = new ColorAnimation(linearGradientBrush.GradientStops[1].Color, Color.FromArgb(0, 0, 0, 0), TimeSpan.FromMilliseconds(250));
                                                                    SineEase sineEase1 = new SineEase();
                                                                    SineEase sineEase2 = new SineEase();

                                                                    if (a.imageStoryboardDictionary.TryGetValue(i, out storyboard))
                                                                    {
                                                                        storyboard.Stop(i);
                                                                        a.imageStoryboardDictionary[i] = storyboard = new Storyboard();
                                                                    }
                                                                    else
                                                                    {
                                                                        storyboard = new Storyboard();
                                                                        a.imageStoryboardDictionary.Add(i, storyboard);
                                                                    }

                                                                    sineEase1.EasingMode = sineEase2.EasingMode = EasingMode.EaseInOut;

                                                                    colorAnimation1.EasingFunction = sineEase1;
                                                                    colorAnimation2.BeginTime = TimeSpan.FromMilliseconds(250);
                                                                    colorAnimation2.EasingFunction = sineEase2;

                                                                    storyboard.CurrentStateInvalidated += new EventHandler(delegate (object s, EventArgs e)
                                                                    {
                                                                        if (((Clock)s).CurrentState == ClockState.Filling)
                                                                        {
                                                                            i.OpacityMask = null;
                                                                            a.Render();
                                                                            storyboard.Remove(i);
                                                                            a.imageStoryboardDictionary.Remove(i);
                                                                        }
                                                                    });
                                                                    storyboard.Children.Add(colorAnimation1);
                                                                    storyboard.Children.Add(colorAnimation2);

                                                                    Storyboard.SetTargetProperty(colorAnimation1, new PropertyPath("(0).(1)[0].(2)", Image.OpacityMaskProperty, LinearGradientBrush.GradientStopsProperty, GradientStop.ColorProperty));
                                                                    Storyboard.SetTargetProperty(colorAnimation2, new PropertyPath("(0).(1)[1].(2)", Image.OpacityMaskProperty, LinearGradientBrush.GradientStopsProperty, GradientStop.ColorProperty));

                                                                    i.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, true);
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    });

                                    if (nextLinkedListNode.Value.Key.HasTypes)
                                    {
                                        childMenuItem.IsChecked = nextLinkedListNode.Value.Key.Types.Contains(childMenuItem.Header as string);
                                    }
                                    else
                                    {
                                        childMenuItem.IsChecked = false;
                                    }

                                    childMenuItemList.Add(childMenuItem);
                                });

                                selectedMenuItem.Items.Clear();

                                if (childMenuItemList.Count > 0)
                                {
                                    selectedMenuItem.IsChecked = false;
                                    childMenuItemList.ForEach(delegate (MenuItem mi)
                                    {
                                        selectedMenuItem.Items.Add(mi);
                                    });
                                }
                                else
                                {
                                    selectedMenuItem.IsChecked = true;
                                }

                                characterLinkedList.Remove(nextLinkedListNode);

                                return;
                            }
                        }

                        MenuItem unselectedMenuItem = menuItemList.Find(delegate (MenuItem menuItem)
                        {
                            return kvp.Key.Equals(menuItem.Header as string) && kvp.Value.Equals(menuItem.Tag as string) && !menuItem.IsChecked && !menuItem.HasItems;
                        });

                        if (unselectedMenuItem == null)
                        {
                            unselectedMenuItem = new MenuItem();
                            unselectedMenuItem.Header = kvp.Key;
                            unselectedMenuItem.Tag = kvp.Value;
                            unselectedMenuItem.Click += new RoutedEventHandler(delegate
                            {
                                string tag = unselectedMenuItem.Tag as string;

                                if (tag != null)
                                {
                                    List<Character> characterList = new List<Character>();

                                    if (Path.GetExtension(tag).Equals(".zip", StringComparison.OrdinalIgnoreCase))
                                    {
                                        FileStream fs = null;

                                        try
                                        {
                                            fs = new FileStream(tag, FileMode.Open, FileAccess.Read, FileShare.Read);

                                            using (ZipArchive zipArchive = new ZipArchive(fs))
                                            {
                                                fs = null;

                                                StringBuilder stringBuilder = new StringBuilder(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));

                                                if (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).LastIndexOf(Path.DirectorySeparatorChar) != Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).Length - 1)
                                                {
                                                    stringBuilder.Append(Path.DirectorySeparatorChar);
                                                }

                                                string path = tag.StartsWith(stringBuilder.ToString(), StringComparison.Ordinal) ? tag.Remove(0, stringBuilder.Length) : tag;

                                                foreach (ZipArchiveEntry zipArchiveEntry in from zipArchiveEntry in zipArchive.Entries where zipArchiveEntry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase) select zipArchiveEntry)
                                                {
                                                    Stream stream = null;

                                                    try
                                                    {
                                                        stream = zipArchiveEntry.Open();

                                                        foreach (string a in from a in ((System.Collections.IEnumerable)XDocument.Load(stream).XPathEvaluate("/script/character/@name")).Cast<XAttribute>() select a.Value)
                                                        {
                                                            Character character = new Character();

                                                            character.Name = a;
                                                            character.Script = path;

                                                            characterList.Add(character);
                                                        }
                                                    }
                                                    catch
                                                    {
                                                        return;
                                                    }
                                                    finally
                                                    {
                                                        if (stream != null)
                                                        {
                                                            stream.Close();
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            if (fs != null)
                                            {
                                                fs.Close();
                                            }
                                        }
                                    }
                                    else
                                    {
                                        FileStream fs = null;

                                        try
                                        {
                                            fs = new FileStream(tag, FileMode.Open, FileAccess.Read, FileShare.Read);

                                            StringBuilder stringBuilder = new StringBuilder(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));

                                            if (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).LastIndexOf(Path.DirectorySeparatorChar) != Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).Length - 1)
                                            {
                                                stringBuilder.Append(Path.DirectorySeparatorChar);
                                            }

                                            string path = tag.StartsWith(stringBuilder.ToString(), StringComparison.Ordinal) ? tag.Remove(0, stringBuilder.Length) : tag;

                                            foreach (string a in from a in ((System.Collections.IEnumerable)XDocument.Load(fs).XPathEvaluate("/script/character/@name")).Cast<XAttribute>() select a.Value)
                                            {
                                                Character character = new Character();

                                                character.Name = a;
                                                character.Script = path;

                                                characterList.Add(character);
                                            }
                                        }
                                        catch
                                        {
                                            return;
                                        }
                                        finally
                                        {
                                            if (fs != null)
                                            {
                                                fs.Close();
                                            }
                                        }
                                    }

                                    if (characterList.Count > 0)
                                    {
                                        Switch(characterList);
                                    }
                                }
                            });
                        }
                        else
                        {
                            menuItemList.Remove(unselectedMenuItem);
                        }

                        charactersMenuItem.Items.Add(unselectedMenuItem);
                    });
                }
            });

            if (this == Application.Current.MainWindow)
            {
                System.Configuration.Configuration config = null;
                string directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);

                if (Directory.Exists(directory))
                {
                    string fileName = Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                    foreach (string s in from s in Directory.EnumerateFiles(directory, "*.config") where fileName.Equals(Path.GetFileNameWithoutExtension(s)) select s)
                    {
                        System.Configuration.ExeConfigurationFileMap exeConfigurationFileMap = new System.Configuration.ExeConfigurationFileMap();

                        exeConfigurationFileMap.ExeConfigFilename = s;
                        config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(exeConfigurationFileMap, System.Configuration.ConfigurationUserLevel.None);
                    }
                }

                if (config == null)
                {
                    config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
                }

                if (config.AppSettings.Settings["Left"] != null && config.AppSettings.Settings["Top"] != null)
                {
                    if (config.AppSettings.Settings["Left"].Value.Length > 0 && config.AppSettings.Settings["Top"].Value.Length > 0)
                    {
                        this.Left = Double.Parse(config.AppSettings.Settings["Left"].Value, System.Globalization.CultureInfo.InvariantCulture);
                        this.Top = Double.Parse(config.AppSettings.Settings["Top"].Value, System.Globalization.CultureInfo.InvariantCulture);
                    }
                }

                if (config.AppSettings.Settings["Opacity"] != null)
                {
                    if (config.AppSettings.Settings["Opacity"].Value.Length > 0)
                    {
                        this.opacity = Double.Parse(config.AppSettings.Settings["Opacity"].Value, System.Globalization.CultureInfo.InvariantCulture);
                    }
                }

                if (config.AppSettings.Settings["Scale"] != null)
                {
                    if (config.AppSettings.Settings["Scale"].Value.Length > 0)
                    {
                        this.scale = this.ZoomScaleTransform.ScaleX = this.ZoomScaleTransform.ScaleY = Double.Parse(config.AppSettings.Settings["Scale"].Value, System.Globalization.CultureInfo.InvariantCulture);
                    }
                }

                if (config.AppSettings.Settings["Topmost"] != null)
                {
                    if (config.AppSettings.Settings["Topmost"].Value.Length > 0)
                    {
                        this.Topmost = Boolean.Parse(config.AppSettings.Settings["Topmost"].Value);
                    }
                }

                if (config.AppSettings.Settings["ShowInTaskbar"] != null)
                {
                    if (config.AppSettings.Settings["ShowInTaskbar"].Value.Length > 0)
                    {
                        this.ShowInTaskbar = Boolean.Parse(config.AppSettings.Settings["ShowInTaskbar"].Value);
                    }
                }

                if (config.AppSettings.Settings["DropShadow"] != null)
                {
                    if (config.AppSettings.Settings["DropShadow"].Value.Length > 0)
                    {
                        if (Boolean.Parse(config.AppSettings.Settings["DropShadow"].Value))
                        {
                            DropShadowEffect dropShadowEffect = new DropShadowEffect();

                            dropShadowEffect.Color = Colors.Black;
                            dropShadowEffect.BlurRadius = 10;
                            dropShadowEffect.Direction = 270;
                            dropShadowEffect.ShadowDepth = 0;
                            dropShadowEffect.Opacity = 0.5;

                            if (dropShadowEffect.CanFreeze)
                            {
                                dropShadowEffect.Freeze();
                            }

                            this.Canvas.Effect = dropShadowEffect;
                        }
                    }
                }

                if (config.AppSettings.Settings["Mute"] != null)
                {
                    if (config.AppSettings.Settings["Mute"].Value.Length > 0)
                    {
                        this.isMute = Boolean.Parse(config.AppSettings.Settings["Mute"].Value);
                    }
                }

                if (config.AppSettings.Settings["FrameRate"] != null)
                {
                    if (config.AppSettings.Settings["FrameRate"].Value.Length > 0)
                    {
                        this.frameRate = Double.Parse(config.AppSettings.Settings["FrameRate"].Value, System.Globalization.CultureInfo.InvariantCulture);
                    }
                }
            }
            else
            {
                Agent agent = Application.Current.MainWindow as Agent;

                if (agent != null)
                {
                    this.opacity = agent.opacity;
                    this.scale = this.ZoomScaleTransform.ScaleX = this.ZoomScaleTransform.ScaleY = agent.scale;
                    this.Topmost = agent.Topmost;
                    this.ShowInTaskbar = agent.ShowInTaskbar;

                    if (agent.Canvas.Effect != null)
                    {
                        DropShadowEffect dropShadowEffect = new DropShadowEffect();

                        dropShadowEffect.Color = Colors.Black;
                        dropShadowEffect.BlurRadius = 10;
                        dropShadowEffect.Direction = 270;
                        dropShadowEffect.ShadowDepth = 0;
                        dropShadowEffect.Opacity = 0.5;

                        if (dropShadowEffect.CanFreeze)
                        {
                            dropShadowEffect.Freeze();
                        }

                        this.Canvas.Effect = dropShadowEffect;
                    }

                    this.isMute = agent.isMute;
                    this.frameRate = agent.frameRate;
                }
            }

            this.balloon = new Balloon();
            this.balloon.Title = this.Title;
            this.balloon.SizeChanged += new SizeChangedEventHandler(delegate (object s, SizeChangedEventArgs e)
            {
                foreach (Character character in from character in Script.Instance.Characters where character.Name.Equals(this.characterName) select character)
                {
                    this.balloon.Left = this.Left + (this.Width - e.NewSize.Width) / 2;
                    this.balloon.Top = this.Top - e.NewSize.Height + character.Origin.Y * this.ZoomScaleTransform.ScaleY;
                }
            });
            this.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate
            {
                Run();

                return null;
            }), null);

            Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(this.OnPowerModeChanged);
        }