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; namespace Tango.MachineStudio.HardwareDesigner.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; private bool _isNew; private ObservablesContext _db; 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 = 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 MainViewVM(INotificationProvider notification) { _notification = notification; 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); } public override void OnApplicationReady() { Task.Factory.StartNew(() => { RefreshVersions(); CreateDefaultView(); }); } private void CopyParameters(object obj) { obj.MapPrimitivesTo(SelectedHardwareObject, (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 }).ToSynchronizedObservableCollection(); CurrentVersion.HardwareDancers = _db.HardwareDancerTypes.ToList().Select(x => new HardwareDancer() { HardwareDancerType = x }).ToSynchronizedObservableCollection(); CurrentVersion.HardwarePidControls = _db.HardwarePidControlTypes.ToList().Select(x => new HardwarePidControl() { HardwarePidControlType = x }).ToSynchronizedObservableCollection(); CurrentVersion.HardwareWinders = _db.HardwareWinderTypes.ToList().Select(x => new HardwareWinder() { HardwareWinderType = x }).ToSynchronizedObservableCollection(); CurrentVersion.HardwareSpeedSensors = _db.HardwareSpeedSensorTypes.ToList().Select(x => new HardwareSpeedSensor() { HardwareSpeedSensorType = x }).ToSynchronizedObservableCollection(); CurrentVersion.HardwareBlowers = _db.HardwareBlowerTypes.ToList().Select(x => new HardwareBlower() { HardwareBlowerType = x }).ToSynchronizedObservableCollection(); CurrentVersion.HardwareBreakSensors = _db.HardwareBreakSensorTypes.ToList().Select(x => new HardwareBreakSensor() { HardwareBreakSensorType = x }).ToSynchronizedObservableCollection(); } private void RefreshVersions() { using (var db = ObservablesContext.CreateDefault()) { _hardwareVersions = db.HardwareVersions.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(); }); } private async void OnSelectedVersionChanged() { if (SelectedVersion != null) { using (_notification.PushTaskItem("Loading hardware version...")) { 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)); }); }); 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(); 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(() => { _db.SaveChanges(); 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(); 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); 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; } } } } protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null) { base.RaisePropertyChangedAuto(caller); InvalidateRelayCommands(); } } }