using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using Tango.Core.Commands; using Tango.Core.Helpers; using Tango.DAL.Observables; using Tango.MachineStudio.Common.Notifications; using Tango.SharedUI; using SimpleValidator.Extensions; namespace Tango.MachineStudio.MachineDesigner.ViewModels { public class MainViewVM : ViewModel { private bool _isSaving; private INotificationProvider _notification; #region Properties private ObservablesEntitiesAdapter _adapter; /// /// Gets or sets the db adapter. /// public ObservablesEntitiesAdapter Adapter { get { return _adapter; } set { _adapter = value; RaisePropertyChangedAuto(); } } private Machine _machine; /// /// Gets or sets the current editable machine. /// public Machine Machine { get { return _machine; } set { _machine = value; RaisePropertyChangedAuto(); } } private Machine _selectedMachine; /// /// Gets or sets the selected machine from the drop down. /// public Machine SelectedMachine { get { return _selectedMachine; } set { _selectedMachine = value; RaisePropertyChangedAuto(); OnSelectedMachineChanged(); } } private Configuration _configuration; /// /// Gets or sets the editable machine configuration. /// public Configuration Configuration { get { return _configuration; } set { _configuration = value; RaisePropertyChangedAuto(); } } private IdsPack _selectedIds; /// /// Gets or sets the selected ids pack. /// public IdsPack SelectedIds { get { return _selectedIds; } set { _selectedIds = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private ObservableCollection _history; /// /// Gets or sets the machine configuration history. /// public ObservableCollection History { get { return _history; } set { _history = value; RaisePropertyChangedAuto(); } } private Configuration _selectedHistoryConfiguration; /// /// Gets or sets the machine selected configuration from history. /// public Configuration SelectedHistoryConfiguration { get { return _selectedHistoryConfiguration; } set { _selectedHistoryConfiguration = value; RaisePropertyChangedAuto(); OnHistoryConfigurationSelected(); } } private String _filter; /// /// Gets or sets the configuration components filter. /// public String Filter { get { return _filter; } set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } } #endregion #region Commands /// /// Gets or sets the save command. /// public RelayCommand SaveCommand { get; set; } /// /// Gets or sets the add ids command. /// public RelayCommand AddIdsCommand { get; set; } /// /// Gets or sets the remove ids command. /// public RelayCommand RemoveIdsCommand { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public MainViewVM(INotificationProvider notification) { _notification = notification; Adapter = ObservablesEntitiesAdapter.Instance; Configuration = new Configuration(); Configuration.Name = "Untitled"; Machine = new Machine(); Machine.Configuration = Configuration; SaveCommand = new RelayCommand(Save, (x) => !_isSaving); AddIdsCommand = new RelayCommand(AddIds, (x) => !_isSaving && Configuration.IdsPacks.Count < 8); RemoveIdsCommand = new RelayCommand(RemoveIds, (x) => !_isSaving && SelectedIds != null); } #endregion #region Virtual Methods /// /// Called when the selected machine has changed. /// protected virtual void OnSelectedMachineChanged() { if (SelectedMachine != null) { Machine = SelectedMachine.CloneEntity(); Configuration = Machine.Configuration.CloneConfiguration(); History = SelectedMachine.MachinesConfigurations.Select(x => x.Configuration).ToObservableCollection(); } else { History = new ObservableCollection(); } } /// /// Called when the history configuration has been selected /// protected virtual void OnHistoryConfigurationSelected() { if (SelectedHistoryConfiguration != null) { Configuration = SelectedHistoryConfiguration.CloneConfiguration(); } } /// /// Called when the filter has changed /// protected virtual void OnFilterChanged() { List collections = new List(); collections.Add(Adapter.ApplicationDisplayPanelVersionsViewSource); collections.Add(Adapter.ApplicationVersionsViewSource); collections.Add(Adapter.EmbeddedSoftwareVersionsViewSource); collections.Add(Adapter.EmbeddedFirmwareVersionsViewSource); collections.Add(Adapter.ApplicationOsVersionsViewSource); collections.Add(Adapter.ApplicationVersionsViewSource); collections.Add(Adapter.DispensersViewSource); collections.Add(Adapter.CartridgeTypesViewSource); collections.Add(Adapter.LiquidTypesViewSource); collections.Add(Adapter.MidTankTypesViewSource); collections.Add(Adapter.HardwareVersionsViewSource); foreach (var collection in collections) { collection.Filter = (x) => { foreach (var prop in x.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(y => y.PropertyType == typeof(String))) { String value = prop.GetValue(x).ToStringSafe(); if (value != null) { if (value.ToLower().Contains(Filter.ToLower())) { return true; } } } return false; }; } } #endregion #region Drag Drop Handlers /// /// Drops the ids pack. /// /// The ids pack1. /// The ids pack2. public void DropIdsPack(IdsPack idsPack1, IdsPack idsPack2) { Configuration.IdsPacks.Swap(idsPack1, idsPack2); } /// /// Drops the touch panel. /// /// The application display panel version. public void DropTouchPanel(ApplicationDisplayPanelVersion applicationDisplayPanelVersion) { Configuration.ApplicationDisplayPanelVersions = applicationDisplayPanelVersion; Configuration.ApplicationDisplayPanelVersionGuid = applicationDisplayPanelVersion.Guid; } /// /// Drops the application firmware version. /// /// The application firmware version. public void DropApplicationFirmwareVersion(ApplicationFirmwareVersion applicationFirmwareVersion) { Configuration.ApplicationFirmwareVersions = applicationFirmwareVersion; Configuration.ApplicationFirmwareVersionGuid = applicationFirmwareVersion.Guid; } /// /// Drops the application version. /// /// The application version. public void DropApplicationVersion(ApplicationVersion applicationVersion) { Configuration.ApplicationVersions = applicationVersion; Configuration.ApplicationVersionGuid = applicationVersion.Guid; } /// /// Drops the hardware version. /// /// The hardware version. public void DropHardwareVersion(HardwareVersion hardwareVersion) { Configuration.HardwareVersions = hardwareVersion; Configuration.HardwareVersionGuid = hardwareVersion.Guid; } /// /// Drops the embedded firmware. /// /// The embedded firmware version. public void DropEmbeddedFirmware(EmbeddedFirmwareVersion embeddedFirmwareVersion) { Configuration.EmbeddedFirmwareVersions = embeddedFirmwareVersion; Configuration.EmbeddedFirmwareVersionGuid = embeddedFirmwareVersion.Guid; } /// /// Drops the embedded software. /// /// The embedded software version. public void DropEmbeddedSoftware(EmbeddedSoftwareVersion embeddedSoftwareVersion) { Configuration.EmbeddedSoftwareVersions = embeddedSoftwareVersion; Configuration.EmbeddedSoftwareVersionGuid = embeddedSoftwareVersion.Guid; } /// /// Drops the application os version. /// /// The application os version. public void DropApplicationOsVersion(ApplicationOsVersion applicationOsVersion) { Configuration.ApplicationOsVersions = applicationOsVersion; Configuration.ApplicationVersionGuid = applicationOsVersion.Guid; } /// /// Drops the type of the cartridge. /// /// Type of the cartridge. /// The ids pack. public void DropCartridgeType(CartridgeType cartridgeType, IdsPack idsPack) { idsPack.CartridgeTypes = cartridgeType; idsPack.CartridgeTypeGuid = cartridgeType.Guid; } /// /// Drops the dispenser. /// /// The dispenser. /// The ids pack. public void DropDispenser(Dispenser dispenser, IdsPack idsPack) { idsPack.Dispenser = dispenser; idsPack.DispenserGuid = dispenser.Guid; } /// /// Drops the type of the mid tank. /// /// Type of the mid tank. /// The ids pack. public void DropMidTankType(MidTankType midTankType, IdsPack idsPack) { idsPack.MidTankTypes = midTankType; idsPack.MidTankTypeGuid = midTankType.Guid; } /// /// Drops the type of the liquid. /// /// Type of the liquid. /// The ids pack. public void DropLiquidType(LiquidType liquidType, IdsPack idsPack) { idsPack.LiquidTypes = liquidType; idsPack.LiquidTypeGuid = liquidType.Guid; } #endregion #region Private Methods /// /// Removes the selected IDS pack. /// private void RemoveIds() { Configuration.IdsPacks.Remove(SelectedIds); SelectedIds = null; } /// /// Adds a new IDS pack. /// private void AddIds() { Configuration.IdsPacks.Add(new IdsPack() { Configuration = Configuration }); InvalidateRelayCommands(); } /// /// Saves the current machine configuration. /// private async void Save() { foreach (var ids in Configuration.IdsPacks) { ids.PackIndex = Configuration.IdsPacks.IndexOf(ids); ids.Configuration = Configuration; ids.ConfigurationGuid = Configuration.Guid; } //Validate List errors = new List(); if (Machine.MachineVersions == null) { errors.Add("Machine version is required."); } if (Machine.Name.IsNullOrWhiteSpace()) { errors.Add("Machine name is required."); } if (Machine.Organization == null) { errors.Add("Machine organization is required."); } if (Machine.SerialNumber.IsNullOrWhiteSpace()) { errors.Add("Machine serial number is required."); } if (Configuration.Name.IsNullOrWhiteSpace()) { errors.Add("Configuration name is required."); } if (Configuration.ApplicationDisplayPanelVersions == null) { errors.Add("Touch Panel is required."); } if (Configuration.ApplicationFirmwareVersions == null) { errors.Add("Application firmware is required."); } if (Configuration.ApplicationOsVersions == null) { errors.Add("Application operation system is required."); } if (Configuration.ApplicationVersions == null) { errors.Add("Application version is required."); } if (Configuration.EmbeddedFirmwareVersions == null) { errors.Add("Embedded firmware is required."); } if (Configuration.EmbeddedSoftwareVersions == null) { errors.Add("Embedded software is required."); } if (Configuration.HardwareVersions == null) { errors.Add("Hardware version is required."); } foreach (var pack in Configuration.IdsPacks) { if (pack.Name.IsNullOrWhiteSpace()) { errors.Add(String.Format("Name is required on IDS pack number '{0}'.", Configuration.IdsPacks.IndexOf(pack) + 1)); continue; } if (pack.CartridgeTypes == null) { errors.Add(String.Format("Cartridge type is required on IDS pack '{0}'.", pack.Name)); } if (pack.Dispenser == null) { errors.Add(String.Format("Dispenser is required on IDS pack '{0}'.", pack.Name)); } if (pack.LiquidTypes == null) { errors.Add(String.Format("Liquid type is required on IDS pack '{0}'.", pack.Name)); } if (pack.MidTankTypes == null) { errors.Add(String.Format("Mid Tank type is required on IDS pack '{0}'.", pack.Name)); } var taken_ids = Adapter.Machines.Where(x => x.SerialNumber.ToLower() != Machine.SerialNumber).SelectMany(x => x.MachinesConfigurations).Select(x => x.Configuration).SelectMany(x => x.IdsPacks).ToList().FirstOrDefault(x => x.Dispenser.SerialNumber.ToLower() == pack.Dispenser.SerialNumber.ToLower()); if (taken_ids != null && taken_ids.Configuration.MachinesConfigurations.Count > 0) { if (!_notification.ShowQuestion(String.Format("The Dispenser '{1}' on IDS pack '{0}' is already taken by another machine ('{2}', '{3}'). Are you sure you want to assign it to this machine?", pack.Name, pack.Dispenser.SerialNumber, taken_ids.Configuration.MachinesConfigurations.First().Machine.Name, taken_ids.Configuration.MachinesConfigurations.First().Machine.SerialNumber))) { return; } } } if (errors.Count > 0) { String errorsString = "Please fix the following validation errors before trying to save." + Environment.NewLine + Environment.NewLine; errorsString += String.Join(Environment.NewLine, errors); _notification.ShowError(errorsString); return; } //Validate _isSaving = true; InvalidateRelayCommands(); try { using (_notification.PushTaskItem("Saving Machine Configuration...")) { if (!Adapter.Machines.ToList().Exists(x => x.SerialNumber.ToLower() == Machine.SerialNumber.ToLower())) { if (!_notification.ShowQuestion("The specified machine serial number does not exist. Do you wish to create a new machine?")) { return; } else { Machine.Configuration = Configuration; Configuration.CreationDate = DateTime.UtcNow; Machine.ProductionDate = DateTime.UtcNow; Machine.MachinesConfigurations.Add(new MachinesConfiguration() { Configuration = Configuration, Machine = Machine, }); await Machine.SaveAsync(); Machine = Adapter.Machines.SingleOrDefault(x => x.Guid == Machine.Guid); Configuration = Machine.Configuration.CloneConfiguration(); } } else { var machine = Adapter.Machines.Single(x => x.SerialNumber.ToLower() == Machine.SerialNumber.ToLower()); //Set 'Real machine' parameters... bool add_history = History.Count == 0 || History.First().Name != Configuration.Name; machine.Name = Machine.Name; machine.SerialNumber = Machine.SerialNumber; machine.Configuration = Configuration; machine.Organization = Machine.Organization; if (add_history) { machine.MachinesConfigurations.Add(new MachinesConfiguration() { Configuration = Configuration, Machine = machine }); } await machine.SaveAsync(); Machine = Adapter.Machines.SingleOrDefault(x => x.Guid == machine.Guid); Configuration = Machine.Configuration.CloneConfiguration(); } SetHistory(Machine); Machine = Machine.CloneEntity(); } } catch (Exception ex) { _notification.ShowError("An error occurred while trying to save the configuration" + Environment.NewLine + ex.Message); } finally { _isSaving = false; InvalidateRelayCommands(); } } /// /// Sets the specified machine history. /// /// The machine. private void SetHistory(Machine machine) { History = machine.MachinesConfigurations.Select(x => x.Configuration).ToObservableCollection(); History.Insert(0, machine.Configuration); } #endregion } }