using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using DTS.Common.Events;
using DTS.Common.Events.TTSImport;
using DTS.Common.Interface.DataRecorders;
using DTS.Common.Interface.TestSetups.Imports.TTS.DIChannels;
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
using Prism.Events;
using Unity;
using DTS.Common.Interactivity;
using Prism.Regions;
using Prism.Commands;
using TTSImport.Model;
using TTSImport.Resources;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace TTSImport
{
///
/// this class handles Level Trigger edit/create functionality
///
[PartCreationPolicy(CreationPolicy.Shared)]
public class DigitalInputChannelsViewModel : IDigitalInputChannelsViewModel
{
///
/// The Hardware Scan view
///
public IDigitalInputChannelsView View { get; set; }
private IEventAggregator _eventAggregator { get; }
private IRegionManager _regionManager;
private IUnityContainer UnityContainer { get; }
public InteractionRequest NotificationRequest { get; }
public InteractionRequest ConfirmationRequest { get; }
///
/// Creates a new instance of the TechnologyDomainEditViewModel.
///
/// The IDigitalInputChannelsView.
/// The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.
/// The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.
/// The unityContainer.
public DigitalInputChannelsViewModel(IDigitalInputChannelsView view, IRegionManager regionManager,
IEventAggregator eventAggregator, IUnityContainer unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest();
ConfirmationRequest = new InteractionRequest();
_eventAggregator = eventAggregator;
UnityContainer = unityContainer;
_regionManager = regionManager;
_eventAggregator.GetEvent().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent()
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
_eventAggregator.GetEvent().Subscribe(OnAssignedChannelsChangedEvent,
ThreadOption.PublisherThread, true);
_eventAggregator.GetEvent()
.Subscribe(OnHardwareScanComplete, ThreadOption.PublisherThread, true);
}
#region Methods
private void OnHardwareScanComplete(List hardware)
{
_hardware = hardware;
}
private void OnAssignedChannelsChangedEvent(ITTSSetup setup)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
OnAssignedChannelsChangedEvent(setup);
}));
return;
}
_setup = setup;
if (null == _hardware || null == _setup) { return; }
var channels = new ObservableCollection();
var remainingChannels = new ObservableCollection();
var channelIdToChannelRecord = new Dictionary();
foreach (var das in _hardware)
{
var ichannels = das.GetIHardwareChannels();
foreach (var ch in ichannels)
{
if (!ch.IsDigitalIn) { continue; }
var newChannel = new DASChannel(ch);
channels.Add(newChannel);
channelIdToChannelRecord[ch.GetId()] = newChannel;
}
}
foreach (var channelRecord in _setup.Channels)
{
if (channelRecord.IsEmptyRecord)
{
continue;
}
if (!channelRecord.IsDigitalInput)
{
continue;
}
if (!channelRecord.IsChannelCodeValid)
{
continue;
}
if (channelRecord.ChannelCode == TTSChannelRecord.NONE)
{
continue;
}
if (null != channelRecord.HardwareChannel &&
channelIdToChannelRecord.ContainsKey(channelRecord.HardwareChannel.GetId()))
{
channelIdToChannelRecord[channelRecord.HardwareChannel.GetId()].SetITTSChannelRecord(channelRecord);
}
else
{
remainingChannels.Add(channelRecord);
}
}
DASChannels = channels;
RemainingChannels = remainingChannels;
OnPropertyChanged("DASChannels");
OnPropertyChanged("RemainingChannels");
}
public void Cleanup()
{
}
public Task CleanupAsync()
{
return Task.CompletedTask;
}
public void Initialize()
{
}
public void Initialize(object parameter)
{
}
public void Initialize(object parameter, object model)
{
}
public Task InitializeAsync()
{
return Task.CompletedTask;
}
public Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
public void Activated()
{
}
///
/// Private Event handler for RaiseNotification event.
///
private void OnBusyIndicatorNotification(bool eventArg)
{
IsBusy = eventArg;
}
///
/// Private Event handler for RaiseNotification event.
///
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
{
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
eventArgsWithTitle.Image, string.Empty);
NotificationRequest.Raise(new Notification
{
Content = eventArgsWithoutTitle,
Title = eventArgsWithTitle.Title
});
}
#endregion
#region Properties
private ITTSSetup _setup;
private IList _hardware;
public bool IsDirty { get; private set; }
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
private bool _isMenuIncluded;
public bool IsMenuIncluded
{
get => _isMenuIncluded;
set
{
_isMenuIncluded = value;
OnPropertyChanged("IsMenuIncluded");
}
}
private bool _isNavigationIncluded;
public bool IsNavigationIncluded
{
get => _isNavigationIncluded;
set
{
_isNavigationIncluded = value;
OnPropertyChanged("IsNavigationIncluded");
}
}
public bool AssignEnabled { get; set; }
public bool RemoveEnabled { get; set; }
public bool EnableOrDisableEnabled { get; set; }
public ObservableCollection DASChannels { get; set; } = new ObservableCollection();
public ObservableCollection RemainingChannels { get; set; } =
new ObservableCollection();
private ITTSChannelRecord _selectedRemainingChannel;
public ITTSChannelRecord SelectedRemainingChannel
{
get => _selectedRemainingChannel;
set
{
_selectedRemainingChannel = value;
if (null == _selectedRemainingChannel || null == SelectedDASChannel) return;
AssignEnabled = true;
OnPropertyChanged("AssignEnabled");
}
}
private DASChannel _selectedDASChannel;
public DASChannel SelectedDASChannel
{
get => _selectedDASChannel;
set
{
_selectedDASChannel = value;
DetermineRemoveEnableStatus();
}
}
private void DetermineRemoveEnableStatus()
{
if (_selectedDASChannel?.Channel != null)
{
if (!string.IsNullOrWhiteSpace(_selectedDASChannel.EID) &&
_selectedDASChannel.EID == _selectedDASChannel.Channel.SensorEID)
{
//can only be replaced, can't be removed
RemoveEnabled = false;
}
RemoveEnabled = true;
}
else
{
RemoveEnabled = false;
}
OnPropertyChanged("RemoveEnabled");
AssignEnabled = null != _selectedDASChannel && null != _selectedRemainingChannel;
OnPropertyChanged("AssignEnabled");
EnableOrDisableEnabled = _selectedDASChannel?.Channel != null;
OnPropertyChanged("EnableOrDisableEnabled");
OnPropertyChanged("EnableOrDisableText");
}
public string EnableOrDisableText
{
get
{
if (SelectedDASChannel?.Channel == null)
{
return StringResources.Analog_Enable;
}
return SelectedDASChannel.Channel.Disabled
? StringResources.Analog_Enable
: StringResources.Analog_Disable;
}
}
#endregion Properties
#region Commands
#region assign
///
/// Assign a channel code to a channel
///
private DelegateCommand _assignCommand;
public DelegateCommand AssignCommand => _assignCommand ?? (_assignCommand = new DelegateCommand(Assign));
private void Assign()
{
if (SelectedRemainingChannel == null) { return; }
_eventAggregator.GetEvent().Publish(_setup);
//BEFORE we go any further, check the state of sensor ids
//if the channel has a sensor id AND there's a sensor on the channel with the same id
//then prompt on replacing the id
//IF the channel has a sensor id and there's no sensor on the channel BUT the new sensor has a different id
//then prompt on replacing the id
var bReplacingID = false;
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
{
if (null != SelectedRemainingChannel && SelectedRemainingChannel.SensorEID != SelectedDASChannel.EID)
{
bReplacingID = true;
}
//if existing channel has this ID, we will need to clear out the old id and assign a new one...
if (null != SelectedDASChannel.Channel && SelectedDASChannel.Channel.SensorEID == SelectedDASChannel.EID)
{
bReplacingID = true;
}
}
if (bReplacingID)
{
Task.Run(() =>
{
var dialogResult = MessageBox.Show(StringResources.AssignSensorPrompt, StringResources.UserFeedbackRequired, MessageBoxButton.YesNo);
if (dialogResult == MessageBoxResult.Yes)
{
Application.Current.Dispatcher.BeginInvoke(new Action(AssignWork));
}
});
return;
}
AssignWork();
}
///
/// assigns a channel record to a physical channel
///
private void AssignWork()
{
if (null != SelectedDASChannel.Channel)
{
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
{
SelectedDASChannel.Channel.SensorEID = "";
}
RemainingChannels.Add(SelectedDASChannel.Channel);
}
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
{
SelectedRemainingChannel.SensorEID = SelectedDASChannel.EID;
}
SelectedRemainingChannel.DigitalInputMode = DTS.Common.Enums.DigitalInputModes.CCNO;
SelectedDASChannel.SetITTSChannelRecord(SelectedRemainingChannel);
var channel = SelectedRemainingChannel;
var index = RemainingChannels.IndexOf(channel);
SelectedRemainingChannel = null;
RemainingChannels.Remove(channel);
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
if (index < RemainingChannels.Count)
{
SelectedRemainingChannel = RemainingChannels[index];
OnPropertyChanged("SelectedRemainingChannel");
}
else if (RemainingChannels.Count > 0)
{
SelectedRemainingChannel = RemainingChannels[index - 1];
OnPropertyChanged("SelectedRemainingChannel");
}
index = DASChannels.IndexOf(SelectedDASChannel);
for (var i = index; i < DASChannels.Count; i++)
{
var dasChannel = DASChannels[i];
if (null != dasChannel.Channel) { continue; }
SelectedDASChannel = dasChannel;
OnPropertyChanged("SelectedDASChannel");
return;
}
//didn't find a match, start from the beginning?
for (var i = 0; i < index; i++)
{
var dasChannel = DASChannels[i];
if (null != dasChannel.Channel)
{
continue;
}
SelectedDASChannel = dasChannel;
OnPropertyChanged("SelectedDASChannel");
return;
}
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
OnPropertyChanged("SelectedDASChannel");
DetermineRemoveEnableStatus();
}
#endregion
#region remove
private DelegateCommand _removeCommand;
public DelegateCommand RemoveCommand => _removeCommand ?? (_removeCommand = new DelegateCommand(Remove));
///
/// remove a hardware channel assignment (does not remove the channel from the test setup though?)
///
private void Remove()
{
if (null == SelectedDASChannel || null == SelectedDASChannel.Channel) { return; }
_eventAggregator.GetEvent().Publish(_setup);
RemainingChannels.Add(SelectedDASChannel.Channel);
SelectedDASChannel.SetITTSChannelRecord(null);
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
var index = DASChannels.IndexOf(SelectedDASChannel);
for (var i = index; i < DASChannels.Count; i++)
{
if (null == DASChannels[i].Channel) { continue; }
SelectedDASChannel = DASChannels[i];
OnPropertyChanged("SelectedDASChannel");
return;
}
for (var i = 0; i < index; i++)
{
if (null == DASChannels[i].Channel) { continue; }
SelectedDASChannel = DASChannels[i];
OnPropertyChanged("SelectedDASChannel");
return;
}
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
OnPropertyChanged("SelectedDASChannel");
DetermineRemoveEnableStatus();
}
#endregion
#region enableordisable
private DelegateCommand _enableOrDisableCommand;
public DelegateCommand EnableOrDisableCommand =>
_enableOrDisableCommand ?? (_enableOrDisableCommand = new DelegateCommand(EnableOrDisable));
///
/// enables or disables a channel in the test.
///
private void EnableOrDisable()
{
if (SelectedDASChannel?.Channel == null) { return; }
SelectedDASChannel.Channel.Disabled = !SelectedDASChannel.Channel.Disabled;
SelectedDASChannel.Disabled = SelectedDASChannel.Channel.Disabled;
OnPropertyChanged("EnableOrDisableText");
_eventAggregator.GetEvent().Publish(_setup);
}
#endregion
#endregion
///
///
/// Occurs when a property value changes.
///
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}