using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Emulations.Emulators;
using Tango.Logging;
using Tango.SharedUI;
using Tango.Core.Commands;
using Tango.Transport.Adapters;
using Tango.Transport.Servers;
using Tango.Transport.Transporters;
using Tango.Core;
using Tango.Settings;
using Tango.PMR.ThreadLoading;
using Tango.PMR.DataStore;
using System.Windows;
namespace Tango.MachineEM.UI.ViewModels
{
public class MainViewVM : ExtendedObject
{
private TcpServer TcpServer;
private bool _running;
private LogManager logManager = LogManager.Default;
private bool _isThreadLoading;
#region Properties
private MachineEmulator _emulator;
///
/// Gets or sets the machine emulator.
///
public MachineEmulator Emulator
{
get { return _emulator; }
set { _emulator = value; RaisePropertyChanged(nameof(Emulator)); }
}
private String _log;
///
/// Gets or sets the log.
///
public String Log
{
get { return _log; }
set { _log = value; RaisePropertyChanged(nameof(Log)); }
}
private List _ports;
///
/// Gets or sets the ports.
///
public List Ports
{
get { return _ports; }
set { _ports = value; RaisePropertyChanged(nameof(Ports)); }
}
private String _selectedPort;
///
/// Gets or sets the selected port.
///
public String SelectedPort
{
get { return _selectedPort; }
set { _selectedPort = value; RaisePropertyChanged(nameof(SelectedPort)); }
}
private ThreadLoadingState _threadLoadingState;
public ThreadLoadingState ThreadLoadingState
{
get { return _threadLoadingState; }
set { _threadLoadingState = value; OnThreadLoadingStateChanged(); }
}
#endregion
#region Private Methods
private void OnThreadLoadingStateChanged()
{
try
{
Emulator?.SetThreadLoadingState(ThreadLoadingState);
}
catch (Exception ex)
{
LogManager.Log(ex);
}
}
#endregion
#region Commands
///
/// Gets or sets the start command.
///
public RelayCommand StartCommand { get; set; }
///
/// Gets or sets the stop command.
///
public RelayCommand StopCommand { get; set; }
///
/// Gets or sets the run command.
///
public RelayCommand RunCommand { get; set; }
///
/// Gets or sets the cancel command.
///
public RelayCommand CancelCommand { get; set; }
///
/// Gets or sets the clear command.
///
public RelayCommand ClearCommand { get; set; }
///
/// Gets or sets the validate cartridge command.
///
public RelayCommand ValidateCartridgeCommand { get; set; }
///
/// Gets or sets the start thread loading sequence command.
///
public RelayCommand StartThreadLoadingCommand { get; set; }
///
/// Gets or sets the finalize thread loading command.
///
public RelayCommand FinalizeThreadLoadingCommand { get; set; }
///
/// Gets or sets the abort job.
///
public RelayCommand AbortJobCommand { get; set; }
public RelayCommand GetDataStoreItemCommand { get; set; }
public RelayCommand PutDataStoreItemCommand { get; set; }
public RelayCommand PerformDataStoreTestCommand { get; set; }
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
public MainViewVM()
{
CoreSettings settings = SettingsManager.Default.GetOrCreate();
settings.Save();
SimpleStringLogger logger = new SimpleStringLogger(LogCategory.Critical, LogCategory.Error, LogCategory.Info, LogCategory.Warning);
logger.LogReceived += (sedner, log) =>
{
Log += log.ToString() + Environment.NewLine;
};
logManager.RegisterLogger(logger);
logManager.Log("Embedded Emulator Started...");
Emulator = new MachineEmulator(new BasicTransporter());
StartCommand = new RelayCommand(Start, (x) => !Emulator.IsStarted);
StopCommand = new RelayCommand(Stop, (x) => Emulator.IsStarted);
CancelCommand = new RelayCommand(Cancel, (x) => _running);
ClearCommand = new RelayCommand(() => Log = String.Empty);
ValidateCartridgeCommand = new RelayCommand(ValidateCartridge, (x) => Emulator.IsStarted);
StartThreadLoadingCommand = new RelayCommand(StartThreadLoading, (x) => Emulator.IsStarted && !_isThreadLoading);
FinalizeThreadLoadingCommand = new RelayCommand(FinalizeThreadLoading, (x) => Emulator.IsStarted && _isThreadLoading);
AbortJobCommand = new RelayCommand(() => Emulator?.AbortJob(), (x) => Emulator.IsStarted);
Ports = new List()
{
"TCP",
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
};
SelectedPort = Ports.First();
PerformDataStoreTestCommand = new RelayCommand(Emulator.PerformDataStoreTest);
GetDataStoreItemCommand = new RelayCommand(GetDataStoreItem);
PutDataStoreItemCommand = new RelayCommand(PutDataStoreItem);
}
#endregion
#region Event Handlers
///
/// Handles the ClientConnected event of the TcpServer control.
///
/// The source of the event.
/// The instance containing the event data.
private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
{
Emulator.Transporter.Adapter = new TcpTransportAdapter(e.Socket);
}
#endregion
#region Command Handlers
///
/// Stops the TCP server and emulator.
///
private async void Start()
{
if (SelectedPort == Ports.First())
{
TcpServer = new TcpServer(9999);
TcpServer.ClientConnected += TcpServer_ClientConnected;
TcpServer.Start();
}
else
{
Emulator.Transporter.Adapter = new UsbTransportAdapter(SelectedPort);
}
await Emulator.Start();
InvalidateRelayCommands();
}
///
/// Starts the TCP server/USB and emulator.
///
private async void Stop()
{
if (TcpServer != null)
{
TcpServer.Stop();
}
await Emulator.Stop();
InvalidateRelayCommands();
}
private void Cancel()
{
}
private async void ValidateCartridge()
{
LogManager.Log("Sending cartridge validation request...");
try
{
var index = await Emulator.ValidateCartridge();
LogManager.Log($"Cartridge validation response received: '{index}'.");
}
catch (Exception ex)
{
LogManager.Log(ex, "Cartridge validation request failed.");
}
}
private async void StartThreadLoading()
{
LogManager.Log("Starting thread loading sequence...");
Emulator.StartThreadLoading();
_isThreadLoading = true;
InvalidateRelayCommands();
await Task.Delay(10000);
_isThreadLoading = false;
InvalidateRelayCommands();
}
private void FinalizeThreadLoading()
{
LogManager.Log("Finalizing thread loading sequence...");
Emulator.FinalizeThreadLoading();
_isThreadLoading = false;
InvalidateRelayCommands();
}
private void GetDataStoreItem()
{
try
{
var result = GetUserInput("Get Data Store Item", "Enter collection name", String.Empty);
if (!result.Confirmed) return;
var collectionName = result.Value;
result = GetUserInput("Get Data Store Item", "Enter item key", String.Empty);
if (!result.Confirmed) return;
var key = result.Value;
Emulator.GetDataStoreItem(new PMR.DataStore.GetDataStoreItemRequest()
{
Collection = collectionName,
Key = key
});
}
catch { }
}
private void PutDataStoreItem()
{
try
{
var result = GetUserInput("Put Data Store Item", "Enter collection name", String.Empty);
if (!result.Confirmed) return;
var collectionName = result.Value;
result = GetUserInput("Put Data Store Item", "Enter item key", String.Empty);
if (!result.Confirmed) return;
var key = result.Value;
result = GetUserInput("Put Data Store Item", "Enter data type", "Int32");
if (!result.Confirmed) return;
DataType dataType = (DataType)Enum.Parse(typeof(DataType), result.Value);
result = GetUserInput("Put Data Store Item", "Enter value", "10");
if (!result.Confirmed) return;
var value = result.Value;
DataStoreItem item = new DataStoreItem();
item.DataType = dataType;
switch (dataType)
{
case DataType.Int32:
item.Int32Value = int.Parse(value);
break;
case DataType.Float:
item.FloatValue = float.Parse(value);
break;
case DataType.Double:
item.DoubleValue = double.Parse(value);
break;
case DataType.Boolean:
item.BooleanValue = bool.Parse(value);
break;
case DataType.String:
item.StringValue = value;
break;
default:
LogManager.Log("Data type not supported by this emulator.");
throw new NotSupportedException();
}
Emulator.PutDataStoreItem(new PutDataStoreItemRequest()
{
Collection = collectionName,
Key = key,
Item = item
});
}
catch { }
}
#endregion
#region Private Methods
private class InputResult
{
public bool Confirmed { get; set; }
public T Value { get; set; }
}
private InputResult GetUserInput(String title, String message, T defaultValue)
{
InputWindow window = new InputWindow();
window.Title = title;
window.Message = message;
window.Value = defaultValue.ToStringSafe();
window.Owner = Application.Current.MainWindow;
window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
window.WindowStyle = WindowStyle.ToolWindow;
try
{
if (window.ShowDialog().Value)
{
return new InputResult() { Confirmed = true, Value = (T)Convert.ChangeType(window.Value, typeof(T)) };
}
else
{
return new InputResult();
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error parsing input.");
throw ex;
}
}
#endregion
}
}