/// <summary>
        ///     Process single alarm message.
        /// </summary>
        /// <param name="alarmInfoViewModel"></param>
        /// <returns></returns>
        private bool OnAlarmNotification(AlarmInfoViewModelBase alarmInfoViewModel)
        {
            bool listsChanged = false;

            // Add alarm to general alarm list
            var newAlarm = new AlarmInfoViewModel(alarmInfoViewModel);

            if (ProcessAlarm(_alarms, newAlarm))
            {
                listsChanged = true;
            }

            if (newAlarm.Priority > 2)
            {
                // Add alarm to high priority alarm list
                // We have to create separate variable for each particular alarm lists
                var highPriorityAlarm = new AlarmInfoViewModel(alarmInfoViewModel);
                if (ProcessAlarm(_highPriorityAlarms, highPriorityAlarm))
                {
                    listsChanged = true;
                }
            }

            return(listsChanged);
        }
        public void OnAlarmNotification(IEnumerable <AlarmInfoViewModelBase> alarmInfoViewModels)
        {
            bool listsChanged = false;

            foreach (AlarmInfoViewModelBase alarmInfoViewModel in alarmInfoViewModels)
            {
                if (OnAlarmNotification(alarmInfoViewModel))
                {
                    listsChanged = true;
                }
            }

            if (listsChanged)
            {
                int unackedAlarmsCount         = 0;
                int activeOrUnackedAlarmsCount = 0;
                for (int i = 0; i < _alarms.Count; i++)
                {
                    AlarmInfoViewModel alarm = _alarms[i];
                    alarm.Num = i + 1;
                    if (alarm.AlarmIsUnacked)
                    {
                        unackedAlarmsCount++;
                    }
                    if ((alarm.AlarmIsActive || alarm.AlarmIsUnacked) &&
                        alarm.CurrentAlarmCondition != AlarmCondition.None)
                    {
                        activeOrUnackedAlarmsCount++;
                    }
                }
                UnackedAlarmsCount         = unackedAlarmsCount;
                ActiveOrUnackedAlarmsCount = activeOrUnackedAlarmsCount;
                HasUnackedAlarms           = unackedAlarmsCount > 0;
                HasActiveOrUnackedAlarms   = activeOrUnackedAlarmsCount > 0;

                for (int i = 0; i < _highPriorityAlarms.Count; i++)
                {
                    _highPriorityAlarms[i].Num = i + 1;
                }

                AlarmInfoViewModel[] last5UnackedAlarms = _alarms.Where(a => a.AlarmIsUnacked && a.CategoryId > 0).Take(5).ToArray();
                if (!last5UnackedAlarms.SequenceEqual(_last5UnackedAlarms))
                {
                    _last5UnackedAlarms.Clear();
                    foreach (AlarmInfoViewModel row in last5UnackedAlarms)
                    {
                        _last5UnackedAlarms.Add(row);
                    }
                }
            }
        }
        /// <summary>
        ///     Process alarm list manipulation when new alarm message is arrived. Removed old alarmd (returned to normal) and so
        ///     on
        /// </summary>
        /// <param name="alarmsList">alarm list</param>
        /// <param name="newAlarm">new incomming alarm</param>
        /// <returns>true if alarms list had been changed</returns>
        private static bool ProcessAlarm(IList <AlarmInfoViewModel> alarmsList, AlarmInfoViewModel newAlarm)
        {
            IEnumerable <AlarmInfoViewModel> alarmsSameEventSourceObject = alarmsList.Where(a =>
                                                                                            String.Equals(a.Tag, newAlarm.Tag, StringComparison.InvariantCultureIgnoreCase)
                                                                                            ).ToArray();

            var alarmsToRemove = new List <AlarmInfoViewModel>();

            if (newAlarm.CurrentAlarmCondition == AlarmCondition.None)
            {
                if (newAlarm.AlarmIsUnacked)
                {
                    foreach (AlarmInfoViewModel a in alarmsSameEventSourceObject)
                    {
                        a.AlarmIsActive = false;
                    }
                }
                else
                {
                    alarmsToRemove.AddRange(alarmsSameEventSourceObject);
                }
            }
            else
            {
                alarmsToRemove.AddRange(alarmsSameEventSourceObject);

                var eventSourceObject = App.EventSourceModel.GetOrCreateEventSourceObject(newAlarm.Tag, newAlarm.Area);
                var activeConditions  = eventSourceObject.AlarmConditions.Where(kvp => kvp.Value.Active).ToArray();
                if (activeConditions.Length > 0)
                {
                    var kvp = activeConditions.OrderByDescending(i => i.Value.CategoryId).ThenByDescending(i => i.Value.ActiveOccurrenceTime).First();
                    newAlarm.CategoryId            = kvp.Value.CategoryId;
                    newAlarm.CurrentAlarmCondition = kvp.Key;
                    newAlarm.AlarmIsActive         = kvp.Value.Active;
                    newAlarm.AlarmIsUnacked        = kvp.Value.Unacked;

                    alarmsList.Insert(0, newAlarm);
                }
                else
                {
                    var unackedConditions = eventSourceObject.AlarmConditions.Where(kvp => kvp.Value.Unacked).ToArray();
                    if (unackedConditions.Length > 0)
                    {
                        var kvp = unackedConditions.OrderByDescending(i => i.Value.CategoryId).ThenByDescending(i => i.Value.ActiveOccurrenceTime).First();
                        newAlarm.CategoryId            = kvp.Value.CategoryId;
                        newAlarm.CurrentAlarmCondition = kvp.Key;
                        newAlarm.AlarmIsActive         = kvp.Value.Active;
                        newAlarm.AlarmIsUnacked        = kvp.Value.Unacked;

                        alarmsList.Insert(0, newAlarm);
                    }
                }
            }

            foreach (AlarmInfoViewModel a in alarmsToRemove)
            {
                alarmsList.Remove(a);
            }

            return(true);
        }