using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Commands; using Tango.BL.Entities; using Tango.MachineStudio.Common.Notifications; using Tango.SharedUI; using Tango.BL; using Tango.SharedUI.Components; using System.Runtime.CompilerServices; using Tango.MachineStudio.Common; using Tango.Core.ExtensionMethods; using Tango.MachineStudio.HardwareDesigner.Views; using Microsoft.Win32; using System.IO; using Tango.BL.ActionLogs; using Tango.MachineStudio.Common.Authentication; using Tango.BL.DTO; using Tango.BL.Enumerations; namespace Tango.MachineStudio.HardwareDesigner.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; private bool _isNew; private ObservablesContext _db; private IActionLogManager _actionLogManager; private IAuthenticationProvider _authentication; private HardwareVersionDTO _hwBeforeSave; private HardwareVersion _selectedVersion; public HardwareVersion SelectedVersion { get { return _selectedVersion; } set { _selectedVersion = value; RaisePropertyChangedAuto(); OnSelectedVersionChanged(); } } private HardwareVersion _currentVersion; public HardwareVersion CurrentVersion { get { return _currentVersion; } set { _currentVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private IObservableEntity _selectedHardwareObject; public IObservableEntity SelectedHardwareObject { get { return _selectedHardwareObject; } set { _selectedHardwareObject = null; RaisePropertyChangedAuto(); _selectedHardwareObject = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(SelectedHardwareObjectTypeName)); } } public String SelectedHardwareObjectTypeName { get { String name = String.Empty; if (SelectedHardwareObject is HardwareMotor) { name = (SelectedHardwareObject as HardwareMotor).HardwareMotorType.Description; } else if (SelectedHardwareObject is HardwareDancer) { name = (SelectedHardwareObject as HardwareDancer).HardwareDancerType.Description; } else if (SelectedHardwareObject is HardwareBlower) { name = (SelectedHardwareObject as HardwareBlower).HardwareBlowerType.Description; } else if (SelectedHardwareObject is HardwareBreakSensor) { name = (SelectedHardwareObject as HardwareBreakSensor).HardwareBreakSensorType.Description; } else if (SelectedHardwareObject is HardwarePidControl) { name = (SelectedHardwareObject as HardwarePidControl).HardwarePidControlType.Description; } else if (SelectedHardwareObject is HardwareSpeedSensor) { name = (SelectedHardwareObject as HardwareSpeedSensor).HardwareSpeedSensorType.Description; } else if (SelectedHardwareObject is HardwareWinder) { name = (SelectedHardwareObject as HardwareWinder).HardwareWinderType.Description; } return name; } } private ObservableCollection _hardwareVersions; public ObservableCollection HardwareVersions { get { return _hardwareVersions; } set { _hardwareVersions = value; RaisePropertyChangedAuto(); } } public RelayCommand SaveCommand { get; set; } public RelayCommand DeleteCommand { get; set; } public RelayCommand NewCommand { get; set; } public RelayCommand CloneCommand { get; set; } public RelayCommand CopyParametersCommand { get; set; } public RelayCommand OpenComparisonWizardCommand { get; set; } public RelayCommand ExportHardwareVersionCommand { get; set; } public RelayCommand ImportHardwareVersionCommand { get; set; } public MainViewVM(INotificationProvider notification, IActionLogManager actionLogManager, IAuthenticationProvider authentication) { _notification = notification; _actionLogManager = actionLogManager; _authentication = authentication; CurrentVersion = new HardwareVersion(); SaveCommand = new RelayCommand(Save, () => SelectedVersion != null && IsFree); NewCommand = new RelayCommand(New, () => IsFree); DeleteCommand = new RelayCommand(Delete, () => !_isNew && SelectedVersion != null && IsFree); CurrentVersion = new HardwareVersion(); CopyParametersCommand = new RelayCommand(CopyParameters, (x) => SelectedVersion != null && IsFree); CloneCommand = new RelayCommand(CloneCurrentVersion, () => SelectedVersion != null && IsFree); OpenComparisonWizardCommand = new RelayCommand(OpenComparisonWizard, () => IsFree); ExportHardwareVersionCommand = new RelayCommand(ExportHardwareVersion, () => IsFree && SelectedVersion != null && CurrentVersion != null); ImportHardwareVersionCommand = new RelayCommand(ImportHardwareVersion, () => IsFree); } private async void ExportHardwareVersion() { SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "Export hardware version"; dlg.DefaultExt = ".hv"; dlg.Filter = "Hardware Version Files|*.hv"; if (dlg.ShowDialog().Value) { try { var json = await CurrentVersion.ToHardwareVersionFile(); File.WriteAllText(dlg.FileName, json); } catch (Exception ex) { LogManager.Log(ex, "Error exporting hardware version."); _notification.ShowError($"An error occurred while trying to export the selected hardware version.\n{ex.FlattenMessage()}"); } } } private async void ImportHardwareVersion() { OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Import hardware version"; dlg.DefaultExt = ".hv"; dlg.Filter = "Hardware Version Files|*.hv"; if (dlg.ShowDialog().Value) { try { var hv = await HardwareVersion.FromHardwareVersionFile(File.ReadAllText(dlg.FileName)); String name = _notification.ShowTextInput("Enter hardware version name", "Name", hv.Name); if (!String.IsNullOrWhiteSpace(name)) { using (_notification.PushTaskItem("Importing hardware version...")) { try { IsFree = false; hv.Name = name; hv.Version = HardwareVersions.Max(x => x.Version) + 1; _db.HardwareVersions.Add(hv); await _db.SaveChangesAsync(); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionImported, _authentication.CurrentUser, CurrentVersion.Name, CurrentVersion, "New hardware version imported using Machine Studio."); RefreshVersions(); InvokeUI(() => { SelectedVersion = HardwareVersions.SingleOrDefault(x => x.Guid == hv.Guid); }); } catch (Exception ex) { LogManager.Log(ex, "Error importing hardware version."); _notification.ShowError($"An error occurred while trying to import the selected hardware version.\n{ex.FlattenMessage()}"); } finally { IsFree = true; } } } } catch (Exception ex) { LogManager.Log(ex, "Error importing hardware version."); _notification.ShowError($"An error occurred while trying to load the selected hardware version file.\n{ex.FlattenMessage()}"); } } } public override void OnApplicationReady() { Task.Factory.StartNew(() => { RefreshVersions(); CreateDefaultView(); }); } private void CopyParameters(object obj) { obj.MapPropertiesTo(SelectedHardwareObject, MappingFlags.ValueTypesOnly, (prop) => !prop.PropertyType.IsEnum && prop.Name.ToLower() != "guid" && prop.Name.ToLower() != "id"); } private void CreateDefaultView() { if (_db != null) _db.Dispose(); _db = ObservablesContext.CreateDefault(); CurrentVersion.HardwareMotors = _db.HardwareMotorTypes.ToList().Select(x => new HardwareMotor() { HardwareMotorType = x }).OrderByAlphaNumeric(x => x.HardwareMotorType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwareDancers = _db.HardwareDancerTypes.ToList().Select(x => new HardwareDancer() { HardwareDancerType = x }).OrderByAlphaNumeric(x => x.HardwareDancerType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwarePidControls = _db.HardwarePidControlTypes.ToList().Select(x => new HardwarePidControl() { HardwarePidControlType = x }).OrderByAlphaNumeric(x => x.HardwarePidControlType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwareWinders = _db.HardwareWinderTypes.ToList().Select(x => new HardwareWinder() { HardwareWinderType = x }).OrderByAlphaNumeric(x => x.HardwareWinderType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwareSpeedSensors = _db.HardwareSpeedSensorTypes.ToList().Select(x => new HardwareSpeedSensor() { HardwareSpeedSensorType = x }).OrderByAlphaNumeric(x => x.HardwareSpeedSensorType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwareBlowers = _db.HardwareBlowerTypes.ToList().Select(x => new HardwareBlower() { HardwareBlowerType = x }).OrderByAlphaNumeric(x => x.HardwareBlowerType.Description).ToSynchronizedObservableCollection(); CurrentVersion.HardwareBreakSensors = _db.HardwareBreakSensorTypes.ToList().Select(x => new HardwareBreakSensor() { HardwareBreakSensorType = x }).OrderByAlphaNumeric(x => x.HardwareBreakSensorType.Description).ToSynchronizedObservableCollection(); } private void RefreshVersions() { using (var db = ObservablesContext.CreateDefault()) { _hardwareVersions = db.HardwareVersions.OrderByDescending(x => x.Version).ToObservableCollection(); InvokeUI(() => { RaisePropertyChanged(nameof(HardwareVersions)); }); } } private void CreateVersionView(HardwareVersion selectedVersion) { if (_db != null) _db.Dispose(); _db = ObservablesContext.CreateDefault(); CurrentVersion = _db.Adapter.GetHardwareVersion(x => x.Guid == selectedVersion.Guid); InvokeUINow(() => { ObservablesStaticCollections.Instance.HardwareMotorTypes.Where(x => !CurrentVersion.HardwareMotors.ToList().Exists(y => y.HardwareMotorType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareMotors.Add(new HardwareMotor() { HardwareMotorType = _db.HardwareMotorTypes.SingleOrDefault(y => y.Code == x.Code), }); }); CurrentVersion.HardwareMotors = CurrentVersion.HardwareMotors.OrderBy(x => x.HardwareMotorType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwareDancerTypes.Where(x => !CurrentVersion.HardwareDancers.ToList().Exists(y => y.HardwareDancerType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareDancers.Add(new HardwareDancer() { HardwareDancerType = _db.HardwareDancerTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwareDancers = CurrentVersion.HardwareDancers.OrderBy(x => x.HardwareDancerType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwarePidControlTypes.Where(x => !CurrentVersion.HardwarePidControls.ToList().Exists(y => y.HardwarePidControlType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwarePidControls.Add(new HardwarePidControl() { HardwarePidControlType = _db.HardwarePidControlTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwarePidControls = CurrentVersion.HardwarePidControls.OrderBy(x => x.HardwarePidControlType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwareWinderTypes.Where(x => !CurrentVersion.HardwareWinders.ToList().Exists(y => y.HardwareWinderType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareWinders.Add(new HardwareWinder() { HardwareWinderType = _db.HardwareWinderTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwareWinders = CurrentVersion.HardwareWinders.OrderBy(x => x.HardwareWinderType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwareSpeedSensorTypes.Where(x => !CurrentVersion.HardwareSpeedSensors.ToList().Exists(y => y.HardwareSpeedSensorType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareSpeedSensors.Add(new HardwareSpeedSensor() { HardwareSpeedSensorType = _db.HardwareSpeedSensorTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwareSpeedSensors = CurrentVersion.HardwareSpeedSensors.OrderBy(x => x.HardwareSpeedSensorType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwareBlowerTypes.Where(x => !CurrentVersion.HardwareBlowers.ToList().Exists(y => y.HardwareBlowerType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareBlowers.Add(new HardwareBlower() { HardwareBlowerType = _db.HardwareBlowerTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwareBlowers = CurrentVersion.HardwareBlowers.OrderBy(x => x.HardwareBlowerType.Code).ToSynchronizedObservableCollection(); ObservablesStaticCollections.Instance.HardwareBreakSensorTypes.Where(x => !CurrentVersion.HardwareBreakSensors.ToList().Exists(y => y.HardwareBreakSensorType.Code == x.Code)).ToList().ForEach(x => { CurrentVersion.HardwareBreakSensors.Add(new HardwareBreakSensor() { HardwareBreakSensorType = _db.HardwareBreakSensorTypes.SingleOrDefault(y => y.Code == x.Code) }); }); CurrentVersion.HardwareBreakSensors = CurrentVersion.HardwareBreakSensors.OrderBy(x => x.HardwareBreakSensorType.Code).ToSynchronizedObservableCollection(); _hwBeforeSave = HardwareVersionDTO.FromObservable(CurrentVersion); }); } private async void OnSelectedVersionChanged() { if (SelectedVersion != null) { using (_notification.PushTaskItem("Loading hardware version...")) { try { IsFree = false; await Task.Factory.StartNew(() => { _isNew = false; var selectedVersion = SelectedVersion; RefreshVersions(); var version = _hardwareVersions.SingleOrDefault(X => X.Guid == selectedVersion.Guid); CreateVersionView(SelectedVersion); InvokeUI(() => { _selectedVersion = version; RaisePropertyChanged(nameof(SelectedVersion)); }); }); } catch (Exception ex) { LogManager.Log(ex, "Error loading hardware version."); _notification.ShowError($"Error loading the selected hardware version.\n{ex.FlattenMessage()}"); } finally { IsFree = true; } } } InvalidateRelayCommands(); } private async void New() { String name = _notification.ShowTextInput("Enter hardware version name", "Name"); if (!String.IsNullOrWhiteSpace(name)) { using (_notification.PushTaskItem("Creating new machine version...")) { IsFree = false; await Task.Factory.StartNew(() => { SelectedVersion = null; CurrentVersion = new HardwareVersion(); CurrentVersion.Version = HardwareVersions.Max(x => x.Version) + 1; CurrentVersion.Name = name; CreateDefaultView(); _db.HardwareVersions.Add(CurrentVersion); _db.SaveChanges(); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, CurrentVersion.Name, CurrentVersion, "New hardware version created using Machine Studio."); RefreshVersions(); InvokeUI(() => { _selectedVersion = HardwareVersions.SingleOrDefault(x => x.Guid == CurrentVersion.Guid); RaisePropertyChanged(nameof(SelectedVersion)); }); _isNew = true; InvalidateRelayCommands(); }); IsFree = true; } } } private async void Save() { using (_notification.PushTaskItem("Saving hardware version...")) { try { IsFree = false; await Task.Factory.StartNew(() => { CurrentVersion.LastUpdated = DateTime.UtcNow; CurrentVersion.UserName = _authentication.CurrentUser.Email; _db.SaveChanges(); var dtoAfter = HardwareVersionDTO.FromObservable(CurrentVersion); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionSaved, _authentication.CurrentUser, _hwBeforeSave.Name, _hwBeforeSave, dtoAfter, "Hardware Version saved using Machine Studio."); _hwBeforeSave = dtoAfter; RefreshVersions(); InvokeUI(() => { SelectedVersion = HardwareVersions.SingleOrDefault(x => x.Guid == CurrentVersion.Guid); }); }); } catch (Exception ex) { LogManager.Log(ex, "Could not save hardware version."); _notification.ShowError($"An error occurred while trying to save this hardware version.\n{ex.Message}"); } finally { IsFree = true; } } } private async void CloneCurrentVersion() { if (CurrentVersion != null) { String name = _notification.ShowTextInput("Enter new hardware configuration name", "Name", CurrentVersion.Name + " - Copy"); if (!String.IsNullOrWhiteSpace(name)) { using (_notification.PushTaskItem("Cloning hardware configuration...")) { try { IsFree = false; await Task.Factory.StartNew(() => { var cloned = CurrentVersion.Clone(); cloned.Name = name; cloned.Version = HardwareVersions.Max(x => x.Version) + 1; _db.HardwareVersions.Add(cloned); _db.SaveChanges(); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, cloned.Name, cloned, "New hardware version cloned using Machine Studio."); RefreshVersions(); InvokeUI(() => { SelectedVersion = HardwareVersions.SingleOrDefault(x => x.Guid == cloned.Guid); }); }); } catch (Exception ex) { LogManager.Log(ex, "Could not clone hardware version."); _notification.ShowError($"An error occurred while trying to clone this hardware version.\n{ex.Message}"); } finally { IsFree = true; } } } } } private async void Delete() { if (_notification.ShowQuestion("Are you sure you want to delete this hardware version?")) { using (_notification.PushTaskItem("Deleting hardware version...")) { try { IsFree = false; await CurrentVersion.DeleteCascadeAsync(_db); _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionDeleted, _authentication.CurrentUser, CurrentVersion.Name, _hwBeforeSave, "Hardware version deleted using Machine Studio.", true); await Task.Factory.StartNew(() => { SelectedVersion = null; RefreshVersions(); CurrentVersion = new HardwareVersion(); CreateDefaultView(); InvalidateRelayCommands(); }); } catch (Exception ex) { LogManager.Log(ex, "Could not delete hardware version."); _notification.ShowError($"An error occurred while trying to delete this hardware version.\n{ex.Message}"); } finally { IsFree = true; } } } } private void OpenComparisonWizard() { ComparisonWizardViewVM vm = new ComparisonWizardViewVM(HardwareVersions, SelectedVersion, _notification); _notification.ShowModalDialog(vm, (x) => { }, () => { }); } protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null) { base.RaisePropertyChangedAuto(caller); InvalidateRelayCommands(); } } }