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.BL.Entities; using Tango.MachineStudio.Common.Notifications; using Tango.SharedUI; using SimpleValidator.Extensions; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Common; using Tango.BL; using Tango.AutoComplete.Editors; using System.Data.Entity; namespace Tango.MachineStudio.MachineDesigner.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; private ObservablesContext _db; private Configuration _original_configuration; #region Properties private ObservablesStaticCollections _adapter; /// /// Gets or sets the db static adapter. /// public ObservablesStaticCollections Adapter { get { return _adapter; } set { _adapter = value; RaisePropertyChangedAuto(); } } private bool _canWork; /// /// Gets or sets a value indicating whether this instance can work. /// public bool CanWork { get { return _canWork; } set { _canWork = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } 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 { if (_selectedMachine != value) { _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(); } } /// /// Gets or sets the machines provider. /// public ISuggestionProvider MachinesProvider { get; set; } #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; } /// /// Gets or sets the set version configuration command. /// public RelayCommand SetVersionConfigurationCommand { get; set; } /// /// Gets or sets the set as default command. /// public RelayCommand SetAsDefaultCommand { get; set; } /// /// Gets or sets the reset command. /// public RelayCommand ResetCommand { get; set; } #endregion #region Constructors public MainViewVM() { } /// /// Initializes a new instance of the class. /// public MainViewVM(INotificationProvider notification) { CanWork = true; _notification = notification; Configuration = new Configuration(); Configuration.Name = "Untitled"; Machine = new Machine(); Machine.Configuration = Configuration; SaveCommand = new RelayCommand(Save, (x) => CanWork); AddIdsCommand = new RelayCommand(AddIds, (x) => CanWork && Configuration.IdsPacks.Count < 8); RemoveIdsCommand = new RelayCommand(RemoveIds, (x) => CanWork && SelectedIds != null); SetVersionConfigurationCommand = new RelayCommand(SetVersionConfiguration, (x) => CanWork); SetAsDefaultCommand = new RelayCommand(SetAsDefaultConfiguration, (x) => CanWork); ResetCommand = new RelayCommand(Reset, () => CanWork); MachinesProvider = new SuggestionProvider((filter) => { return _db.Machines.Where(x => x.SerialNumber.StartsWith(filter)).ToList(); }); } #endregion #region Application Ready public async override void OnApplicationReady() { base.OnApplicationReady(); await InitCollections(); } #endregion private Task InitCollections() { return Task.Factory.StartNew(() => { CanWork = false; _db = ObservablesContext.CreateDefault(); _db.Configuration.LazyLoadingEnabled = false; Adapter = new ObservablesStaticCollections(); Adapter.ApplicationDisplayPanelVersions = _db.ApplicationDisplayPanelVersions.ToObservableCollection(); Adapter.ApplicationFirmwareVersions = _db.ApplicationFirmwareVersions.ToObservableCollection(); Adapter.ApplicationOsVersions = _db.ApplicationOsVersions.ToObservableCollection(); Adapter.EmbeddedFirmwareVersions = _db.EmbeddedFirmwareVersions.ToObservableCollection(); Adapter.DispenserTypes = _db.DispenserTypes.ToObservableCollection(); Adapter.LiquidTypes = _db.LiquidTypes.ToObservableCollection(); Adapter.MidTankTypes = _db.MidTankTypes.ToObservableCollection(); Adapter.CartridgeTypes = _db.CartridgeTypes.ToObservableCollection(); Adapter.IdsPackFormulas = _db.IdsPackFormulas.ToObservableCollection(); Adapter.HardwareVersions = _db.HardwareVersions.ToObservableCollection(); Adapter.MachineVersions = _db.MachineVersions.ToObservableCollection(); Adapter.Organizations = _db.Organizations.ToObservableCollection(); Adapter.InitCollectionSources(); CanWork = true; }); } private void Reset() { using (_notification.PushTaskItem("Resetting designer...")) { SelectedMachine = null; Machine = new Machine(); Configuration = new Configuration(); History = new ObservableCollection(); SelectedHistoryConfiguration = null; Filter = String.Empty; InitCollections(); } } #region Virtual Methods /// /// Called when the selected machine has changed. /// protected virtual void OnSelectedMachineChanged() { if (SelectedMachine != null) { CanWork = false; using (_notification.PushTaskItem("Loading machine configuration...")) { Task.Factory.StartNew(() => { InitCollections().Wait(); Machine = _db.Machines.Where(x => x.Guid == SelectedMachine.Guid).Include(x => x.Organization).SingleOrDefault(x => x.Guid == SelectedMachine.Guid); Configuration = _db.GetConfiguration(x => x.Guid == Machine.ConfigurationGuid); SetHistory(); _original_configuration = Configuration.Clone(); }); } CanWork = true; } else { History = new ObservableCollection(); } } /// /// Called when the history configuration has been selected /// protected virtual void OnHistoryConfigurationSelected() { if (SelectedHistoryConfiguration != null && CanWork) { using (_notification.PushTaskItem("Loading Configuration...")) { Task.Factory.StartNew(() => { CanWork = false; SelectedHistoryConfiguration = _db.GetConfiguration(x => x.Guid == SelectedHistoryConfiguration.Guid); Configuration = SelectedHistoryConfiguration; Machine.Configuration = Configuration; CanWork = true; }); } } } /// /// Called when the filter has changed /// protected virtual void OnFilterChanged() { List collections = new List(); collections.Add(Adapter.ApplicationFirmwareVersionsViewSource); collections.Add(Adapter.ApplicationDisplayPanelVersionsViewSource); collections.Add(Adapter.ApplicationOsVersionsViewSource); collections.Add(Adapter.EmbeddedFirmwareVersionsViewSource); collections.Add(Adapter.DispenserTypesViewSource); 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 && Filter != 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.ApplicationDisplayPanelVersion = applicationDisplayPanelVersion; Configuration.ApplicationDisplayPanelVersionGuid = applicationDisplayPanelVersion.Guid; } /// /// Drops the application firmware version. /// /// The application firmware version. public void DropApplicationFirmwareVersion(ApplicationFirmwareVersion applicationFirmwareVersion) { Configuration.ApplicationFirmwareVersion = applicationFirmwareVersion; Configuration.ApplicationFirmwareVersionGuid = applicationFirmwareVersion.Guid; } /// /// Drops the hardware version. /// /// The hardware version. public void DropHardwareVersion(HardwareVersion hardwareVersion) { Configuration.HardwareVersion = hardwareVersion; Configuration.HardwareVersionGuid = hardwareVersion.Guid; } /// /// Drops the embedded firmware. /// /// The embedded firmware version. public void DropEmbeddedFirmware(EmbeddedFirmwareVersion embeddedFirmwareVersion) { Configuration.EmbeddedFirmwareVersion = embeddedFirmwareVersion; Configuration.EmbeddedFirmwareVersionGuid = embeddedFirmwareVersion.Guid; } /// /// Drops the application os version. /// /// The application os version. public void DropApplicationOsVersion(ApplicationOsVersion applicationOsVersion) { Configuration.ApplicationOsVersion = applicationOsVersion; Configuration.ApplicationOsVersionGuid = applicationOsVersion.Guid; } /// /// Drops the type of the cartridge. /// /// Type of the cartridge. /// The ids pack. public void DropCartridgeType(CartridgeType cartridgeType, IdsPack idsPack) { idsPack.CartridgeType = cartridgeType; idsPack.CartridgeTypeGuid = cartridgeType.Guid; } /// /// Drops the dispenser. /// /// The dispenser. /// The ids pack. public void DropDispenserType(DispenserType dispenserType, IdsPack idsPack) { idsPack.DispenserType = dispenserType; idsPack.DispenserTypeGuid = dispenserType.Guid; } /// /// Drops the type of the mid tank. /// /// Type of the mid tank. /// The ids pack. public void DropMidTankType(MidTankType midTankType, IdsPack idsPack) { idsPack.MidTankType = 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.LiquidType = liquidType; idsPack.LiquidTypeGuid = liquidType.Guid; } /// /// Drops the ids formula. /// /// The ids pack formula. /// The ids pack. /// public void DropIdsFormula(IdsPackFormula idsPackFormula, IdsPack idsPack) { idsPack.IdsPackFormula = idsPackFormula; idsPack.IdsPackFormulaGuid = idsPackFormula.Guid; } #endregion #region Private Methods /// /// Removes the selected IDS pack. /// private void RemoveIds() { _db.IdsPacks.Remove(SelectedIds); SelectedIds = null; } /// /// Adds a new IDS pack. /// private void AddIds() { _db.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.MachineVersion == 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.ApplicationDisplayPanelVersion == null) { errors.Add("Touch Panel is required."); } if (Configuration.ApplicationFirmwareVersion == null) { errors.Add("Application firmware is required."); } if (Configuration.ApplicationOsVersion == null) { errors.Add("Application operation system is required."); } if (Configuration.EmbeddedFirmwareVersion == null) { errors.Add("Embedded firmware is required."); } if (Configuration.HardwareVersion == null) { errors.Add("Hardware version is required."); } foreach (var pack in Configuration.IdsPacks) { if (pack.LiquidType != null || pack.CartridgeType != null || pack.DispenserType != null || pack.IdsPackFormula != null || pack.MidTankType != null) { if (pack.Name.IsNullOrWhiteSpace()) { errors.Add(String.Format("Name is required on IDS pack number '{0}'.", Configuration.IdsPacks.IndexOf(pack) + 1)); continue; } if (pack.CartridgeType == null) { errors.Add(String.Format("Cartridge type is required on IDS pack '{0}'.", pack.Name)); } if (pack.DispenserType == null) { errors.Add(String.Format("Dispenser type is required on IDS pack '{0}'.", pack.Name)); } if (pack.LiquidType == null) { errors.Add(String.Format("Liquid type is required on IDS pack '{0}'.", pack.Name)); } if (pack.MidTankType == null) { errors.Add(String.Format("Mid Tank type is required on IDS pack '{0}'.", pack.Name)); } if (pack.IdsPackFormula == null) { errors.Add(String.Format("Formula type is required on IDS pack '{0}'.", pack.Name)); } pack.IsEmpty = false; } else { pack.IsEmpty = true; pack.Name = String.Empty; } } 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 try { CanWork = false; using (_notification.PushTaskItem("Saving Machine Configuration...")) { if (!_db.Machines.Any(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?")) { CanWork = true; return; } else { Machine.Configuration = Configuration; Configuration.CreationDate = DateTime.UtcNow; Machine.ProductionDate = DateTime.UtcNow; _db.Machines.Add(Machine); _db.MachinesConfigurations.Add(new MachinesConfiguration() { Configuration = Configuration, Machine = Machine, }); } } else { bool add_history = History.Count == 0 || _original_configuration.Name != Configuration.Name; if (add_history) { _db.Configurations.Add(_original_configuration); _db.MachinesConfigurations.Add(new MachinesConfiguration() { Configuration = _original_configuration, Machine = Machine }); } } await _db.SaveChangesAsync(); OnSelectedMachineChanged(); } } catch (Exception ex) { _notification.ShowError("An error occurred while trying to save the configuration" + Environment.NewLine + ex.Message); } finally { CanWork = true; InvalidateRelayCommands(); } } /// /// Sets the specified machine history. /// /// The machine. private void SetHistory() { History = _db.MachinesConfigurations.Where(x => x.MachineGuid == Machine.Guid).Select(x => x.Configuration).ToObservableCollection(); //History.Insert(0, Machine.Configuration); } /// /// Sets the current configuration to the selected machine version default configuration. /// private async void SetVersionConfiguration() { if (Machine.MachineVersion != null) { using (_notification.PushTaskItem("Applying default configuration...")) { CanWork = false; await Task.Factory.StartNew(() => { var version = _db.MachineVersions.Where(x => x.Guid == Machine.MachineVersion.Guid).Include(x => x.DefaultConfiguration).FirstOrDefault(); var version_config = _db.GetConfiguration(x => x.Guid == version.DefaultConfiguration.Guid); Configuration = version_config.Clone(); Machine.Configuration = Configuration; }); CanWork = true; } } else { _notification.ShowError("No machine version selected."); } } /// /// Sets the current configuration as a default machine version configuration. /// private void SetAsDefaultConfiguration() { _notification.ShowModalDialog(async (vm) => { CanWork = false; try { using (_notification.PushTaskItem("Saving Default Configuration...")) { if (vm.SelectedVersion != null) { var version = _db.MachineVersions.Where(x => x.Guid == vm.SelectedVersion.Guid).Include(x => x.DefaultConfiguration).SingleOrDefault(x => x.Guid == vm.SelectedVersion.Guid); _db.Configurations.Remove(version.DefaultConfiguration); var cloned = Configuration.Clone(); _db.Configurations.Add(cloned); version.DefaultConfiguration = cloned; await _db.SaveChangesAsync(); } else { MachineVersion newVersion = new MachineVersion(); newVersion.Version = vm.Version; newVersion.Name = vm.VersionName; var cloned = Configuration.Clone(); _db.Configurations.Add(cloned); newVersion.DefaultConfiguration = cloned; _db.MachineVersions.Add(newVersion); await _db.SaveChangesAsync(); } } } catch (Exception ex) { _notification.ShowError(ex.Message); } finally { CanWork = true; } }, () => { }); } #endregion #region IStudioModuleVM public override void OnModuleRequest(params object[] args) { //SelectedMachine = Adapter.Machines.SingleOrDefault(x => x.Guid == (args[0] as Machine).Guid); } #endregion } }