using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace RealTimeGraphX
{
/// <summary>
/// Represents a blocking concurrent queue for graph data consumption.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <seealso cref="System.Collections.Concurrent.BlockingCollection{T}" />
public class GraphDataQueue<T> : BlockingCollection<T>
{
/// <summary>
/// Initializes a new instance of the GraphDataQueue, Use Add and TryAdd for Enqueue and TryEnqueue and Take and TryTake for Dequeue and TryDequeue functionality
/// </summausing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.Core.DI;
using Tango.Integration.Operation;
using Tango.PMR.ThreadLoading;
using Tango.PPC.Common;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.Notifications;
using Tango.Settings;
using Tango.SharedUI;
namespace Tango.PPC.UI.Dialogs
{
public class ThreadLoadingViewVM : DialogViewVM
{
public enum ThreadLoadingStage
{
Welcome,
Preparing,
ReadyForLoading,
Finalizing,
Completed,
PreparationError,
FinalizationError,
}
[TangoInject]
private IMachineProvider MachineProvider { get; set; }
[TangoInject]
private INotificationProvider NotificationProvider { get; set; }
private PPCSettings _settings;
private StartThreadLoadingResponse _status;
public StartThreadLoadingResponse Status
{
get { return _status; }
set { _status = value; RaisePropertyChangedAuto(); }
}
private List<Rml> _rmls;
public List<Rml> Rmls
{
get { return _rmls; }
set { _rmls = value; RaisePropertyChangedAuto(); }
}
private Rml _selectedRml;
public Rml SelectedRml
{
get { return _selectedRml; }
set { _selectedRml = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private ThreadLoadingStage _stage;
public ThreadLoadingStage Stage
{
get { return _stage; }
set { _stage = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private bool _isArcHead;
public bool IsArcHead
{
get { return _isArcHead; }
set { _isArcHead = value; RaisePropertyChangedAuto(); }
}
private String _error;
public String Error
{
get { return _error; }
set { _error = value; RaisePropertyChangedAuto(); }
}
public RelayCommand ContinueCommand { get; set; }
public RelayCommand AbortCommand { get; set; }
public ThreadLoadingViewVM(bool userInvoked = false)
{
CanClose = false;
TangoIOC.Default.Inject(this);
_settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged;
MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected;
IsArcHead = MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc;
ContinueCommand = new RelayCommand(Continue, CanContinue);
AbortCommand = new RelayCommand(Abort);
AdaptToState(userInvoked);
}
private void MachineProvider_MachineDisconnected(object sender, EventArgs e)
{
InvokeUI(() =>
{
Cancel();
});
}
private void AdaptToState(bool userInvoked = false)
{
var status = MachineProvider.MachineOperator.ThreadLoadingStatus;
if (status != null)
{
if (status.State == ThreadLoadingState.Preparing)
{
Stage = ThreadLoadingStage.Preparing;
}
else if (status.State == ThreadLoadingState.ReadyForLoading)
{
Stage = ThreadLoadingStage.ReadyForLoading;
}
else if (status.State == ThreadLoadingState.Finalizing)
{
Stage = ThreadLoadingStage.Finalizing;
}
else if (status.State == ThreadLoadingState.PreparationError)
{
OnPreparationError(status.ErrorReason);
}
else if (status.State == ThreadLoadingState.FinalizationError)
{
OnFinalizationError(status.ErrorReason);
}
else if (status.State == ThreadLoadingState.Completed)
{
if (userInvoked)
{
Stage = ThreadLoadingStage.Welcome;
}
else
{
Stage = ThreadLoadingStage.Completed;
}
}
}
}
private void MachineOperator_ThreadLoadingStatusChanged(object sender, StartThreadLoadingResponse e)
{
Status = e;
AdaptToState();
}
private void Continue()
{
if (Stage == ThreadLoadingStage.Welcome)
{
Stage = ThreadLoadingStage.Preparing;
StartPreparing();
}
else if (Stage == ThreadLoadingStage.ReadyForLoading)
{
ContinueThreadLoading();
}
else if (Stage == ThreadLoadingStage.Completed)
{
Accept();
}
else if (Stage == ThreadLoadingStage.PreparationError)
{
Stage = ThreadLoadingStage.Preparing;
StartPreparing();
}
else if (Stage == ThreadLoadingStage.FinalizationError)
{
ContinueThreadLoading();
}
}
private async void StartPreparing()
{
try
{
await MachineProvider.MachineOperator.StartThreadLoading();
}
catch (Exception ex)
{
OnPreparationError(ex.Message);
}
}
private async void ContinueThreadLoading()
{
try
{
Stage = ThreadLoadingStage.Finalizing;
await MachineProvider.MachineOperator.ContinueThreadLoading(SelectedRml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault());
}
catch (Exception ex)
{
OnFinalizationError(ex.Message);
}
}
private bool CanContinue()
{
bool canContinue = false;
if (Stage != ThreadLoadingStage.Preparing && Stage != ThreadLoadingStage.Finalizing)
{
canContinue = true;
}
if (Stage == ThreadLoadingStage.ReadyForLoading && SelectedRml == null)
{
canContinue = false;
}
return canContinue;
}
private void OnPreparationError(String error)
{
Error = error;
Stage = ThreadLoadingStage.PreparationError;
}
private void OnFinalizationError(String error)
{
Error = error;
Stage = ThreadLoadingStage.FinalizationError;
}
private void Abort()
{
Cancel();
}
public async override void OnShow()
{
base.OnShow();
LogManager.Log("Loading site RMLS...");
List<Rml> rmls = new List<Rml>();
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).WithActiveParametersGroup().BuildListAsync();
}
var selectedRml = rmls.SingleOrDefault(x => x.Guid == _settings.LoadedRmlGuid);
Rmls = rmls;
SelectedRml = selectedRml != null ? selectedRml : rmls.FirstOrDefault();
}
protected override void Cancel()
{
CleanUp();
base.Cancel();
}
protected override void Accept()
{
CleanUp();
base.Accept();
}
private void CleanUp()
{
MachineProvider.MachineOperator.ThreadLoadingStatusChanged -= MachineOperator_ThreadLoadingStatusChanged;
MachineProvider.MachineDisconnected -= MachineProvider_MachineDisconnected;
if (SelectedRml != null)
{
_settings.LoadedRmlGuid = SelectedRml.Guid;
_settings.Save();
}
}
}
}