aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/FSE/Tango.FSE.UI/Events/DefaultEventsProvider.cs
blob: 4593f0aaf02f4196497e257ee81bf1305c86ffe8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83<
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL.Entities;
using Tango.Core;
using Tango.Core.DI;
using Tango.FSE.Common.Connection;
using Tango.FSE.Common.Events;
using Tango.FSE.Common.Navigation;
using Tango.FSE.Common.Notifications;
using Tango.FSE.Common.Threading;
using Tango.FSE.UI.ViewModels;
using Tango.FSE.UI.Views;

namespace Tango.FSE.UI.Events
{
    /// <summary>
    /// Represents the <see cref="IEventsProvider"/> default implementation.
    /// </summary>
    /// <seealso cref="Tango.Core.ExtendedObject" />
    /// <seealso cref="Tango.FSE.Common.Events.IEventsProvider" />
    public class DefaultEventsProvider : ExtendedObject, IEventsProvider
    {
        private Dictionary<MachinesEvent, SnackbarItem> _snackbarItems;
        private const int MAX_HISTORY = 100;

        private IMachineProvider MachineProvider { get; set; }

        [TangoInject]
        private IDispatcherProvider Dispatcher { get; set; }

        [TangoInject]
        private INotificationProvider NotificationProvider { get; set; }

        private INavigationManager NavigationManager { get; set; }

        /// <summary>
        /// Gets or sets the events history (resolved events).
        /// </summary>
        public ObservableCollection<MachinesEvent> EventsHistory { get; set; }

        /// <summary>
        /// Gets or sets the current active events.
        /// </summary>
        public ObservableCollection<MachinesEvent> ActiveEvents { get; set; }

        /// <summary>
        /// Gets or sets the active events view.
        /// </summary>
        public ICollectionView ActiveEventsView { get; set; }

        /// <summary>
        /// Gets or sets the events history view.
        /// </summary>
        public ICollectionView EventsHistoryView { get; set; }

        /// <summary>
        /// Gets a value indicating whether there are any active events currently.
        /// </summary>
        public bool HasActiveEvents
        {
            get { return ActiveEvents.Count > 0; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultEventsProvider"/> class.
        /// </summary>
        /// <param name="machineProvider">The machine provider.</param>
        public DefaultEventsProvider(IMachineProvider machineProvider, INavigationManager navigationManager)
        {
            _snackbarItems = new Dictionary<MachinesEvent, SnackbarItem>();

            //Active Events.
            ActiveEvents = new ObservableCollection<MachinesEvent>();
            ActiveEvents.CollectionChanged += ActiveEvents_CollectionChanged;

            ActiveEventsView = CollectionViewSource.GetDefaultView(ActiveEvents);
            ActiveEventsView.SortDescriptions.Add(new SortDescription(nameof(MachinesEvent.Category), ListSortDirection.Descending));

            //Events History
            EventsHistory = new ObservableCollection<MachinesEvent>();

            EventsHistoryView = CollectionViewSource.GetDefaultView(EventsHistory);
            EventsHistoryView.SortDescriptions.Add(new SortDescription(nameof(MachinesEvent.DateTime), ListSortDirection.Descending));

            MachineProvider = machineProvider;
            MachineProvider.MachineOperator.MachineEventsStateProvider.NewEvents += MachineEventsStateProvider_NewEvents;
            MachineProvider.MachineOperator.MachineEventsStateProvider.EventsResolved += MachineEventsStateProvider_EventsResolved;
            MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected;
            MachineProvider.MachineConnected += MachineProvider_MachineConnected;

            NavigationManager = navigationManager;
            NavigationManager.Navigating += NavigationManager_Navigating;
        }

        private void NavigationManager_Navigating(object sender, NavigationToEventArgs e)
        {
            if (e.ToVM != null && e.ToVM.GetType() == typeof(EventsViewVM))
            {
                foreach (var item in _snackbarItems.ToList())
                {
                    NotificationProvider.PopSnackbarItem(item.Value);
                    _snackbarItems.Remove(item.Key);
                }
            }
        }

        private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
        {
            if (e.DifferentFromPrevious)
            {
                Dispatcher.Invoke(() =>
                {
                    EventsHistory.Clear();
                });
            }
        }

        private void MachineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                ActiveEvents.Clear();
            });
        }

        private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable<MachinesEvent> events)
        {
            Dispatcher.Invoke(() =>
            {
                foreach (var ev in events.ToList())
                {
                    ActiveEvents.Remove(ev);
                    EventsHistory.Insert(0, ev);

                    if (EventsHistory.Count > MAX_HISTORY)
                    {
                        EventsHistory.Remove(EventsHistory.Last());
                    }

                    if (_snackbarItems.ContainsKey(ev))
                    {
                        NotificationProvider.PopSnackbarItem(_snackbarItems[ev]);
                        _snackbarItems.Remove(ev);
                    }
                }
            });
        }

        private void MachineEventsStateProvider_NewEvents(object sender, IEnumerable<MachinesEvent> events)
        {
            Dispatcher.Invoke(() =>
            {
                foreach (var ev in events.ToList())
                {
                    ActiveEvents.Insert(0, ev);

                    if (NavigationManager.CurrentVM != null && NavigationManager.CurrentVM.GetType() == typeof(EventsViewVM))
                    {
                        continue;
                    }

                    MessageType messageType = MessageType.Info;
                    TimeSpan timeout = TimeSpan.FromSeconds(10);

                    switch (ev.Category)
                    {
                        case Tango.BL.Enumerations.EventTypeCategories.Info:
                            messageType = MessageType.Info;
                            break;
                        case Tango.BL.Enumerations.EventTypeCategories.Warning:
                            messageType = MessageType.Warning;
                            break;
                        case Tango.BL.Enumerations.EventTypeCategories.Error:
                            messageType = MessageType.Error;
                            break;
                        case Tango.BL.Enumerations.EventTypeCategories.Critical:
                        case Tango.BL.Enumerations.EventTypeCategories.Safety:
                            messageType = MessageType.Error;
                            timeout = TimeSpan.FromSeconds(30);
                            break;
                    }

                    var item = NotificationProvider.PushSnackbarItem(
                        messageType,
                        ev.EventType.Title,
                        true,
                        ev.EventType.Name + "\n" + ev.EventType.Description,
                        timeout,
                        null,
                        () =>
                        {
                            NavigationManager.NavigateWithObject<InternalModule, EventsView, EventsViewVM.NavigationObject>(new EventsViewVM.NavigationObject()
                            {
                                SelectedEvent = ev
                            });
                        });

                    _snackbarItems[ev] = item;
                }
            });
        }

        private void ActiveEvents_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            RaisePropertyChanged(nameof(HasActiveEvents));
        }
    }
}