aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
blob: de9a8de4a0593d3f758e9ba0bf34d09e8832ce21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.Linq;

using Tango.Scripting.Editors.Document;

namespace Tango.Scripting.Editors.Xml
{
	/// <summary>
	/// Whitespace or character data
	/// </summary>
	public class AXmlText: AXmlObject
	{
		/// <summary> The context in which the text occured </summary>
		internal TextType Type { get; set; }
		/// <summary> The text exactly as in source </summary>
		public string EscapedValue { get; set; }
		/// <summary> The text with all entity references resloved </summary>
		public string Value { get; set; }
		/// <summary> True if the text contains only whitespace characters </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace",
		                                                 Justification = "System.Xml also uses 'Whitespace'")]
		public bool ContainsOnlyWhitespace { get; set; }
		
		/// <inheritdoc/>
		public override void AcceptVisitor(IAXmlVisitor visitor)
		{
			visitor.VisitText(this);
		}
		
		/// <inheritdoc/>
		internal override bool UpdateDataFrom(AXmlObject source)
		{
			if (!base.UpdateDataFrom(source)) return false;
			AXmlText src = (AXmlText)source;
			if (this.EscapedValue != src.EscapedValue ||
			    this.Value != src.Value)
			{
				OnChanging();
				this.EscapedValue = src.EscapedValue;
				this.Value = src.Value;
				OnChanged();
				return true;
			} else {
				return false;
			}
		}
		
		/// <inheritdoc/>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture, "[{0} Text.Length={1}]", base.ToString(), this.EscapedValue.Length);
		}
	}
}
ref='#n499'>499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
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;
        /// <summary>
        /// Gets or sets the db static adapter.
        /// </summary>
        public ObservablesStaticCollections Adapter
        {
            get { return _adapter; }
            set { _adapter = value; RaisePropertyChangedAuto(); }
        }

        private bool _canWork;
        /// <summary>
        /// Gets or sets a value indicating whether this instance can work.
        /// </summary>
        public bool CanWork
        {
            get { return _canWork; }
            set { _canWork = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
        }

        private Machine _machine;
        /// <summary>
        /// Gets or sets the current editable machine.
        /// </summary>
        public Machine Machine
        {
            get { return _machine; }
            set { _machine = value; RaisePropertyChangedAuto(); }
        }

        private Machine _selectedMachine;
        /// <summary>
        /// Gets or sets the selected machine from the drop down.
        /// </summary>
        public Machine SelectedMachine
        {
            get { return _selectedMachine; }
            set
            {
                if (_selectedMachine != value)
                {
                    _selectedMachine = value; RaisePropertyChangedAuto(); OnSelectedMachineChanged();
                }
            }
        }

        private Configuration _configuration;
        /// <summary>
        /// Gets or sets the editable machine configuration.
        /// </summary>
        public Configuration Configuration
        {
            get { return _configuration; }
            set { _configuration = value; RaisePropertyChangedAuto(); }
        }

        private IdsPack _selectedIds;
        /// <summary>
        /// Gets or sets the selected ids pack.
        /// </summary>
        public IdsPack SelectedIds
        {
            get { return _selectedIds; }
            set { _selectedIds = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
        }

        private ObservableCollection<Configuration> _history;
        /// <summary>
        /// Gets or sets the machine configuration history.
        /// </summary>
        public ObservableCollection<Configuration> History
        {
            get { return _history; }
            set { _history = value; RaisePropertyChangedAuto(); }
        }

        private Configuration _selectedHistoryConfiguration;
        /// <summary>
        /// Gets or sets the machine selected configuration from history.
        /// </summary>
        public Configuration SelectedHistoryConfiguration
        {
            get { return _selectedHistoryConfiguration; }
            set { _selectedHistoryConfiguration = value; RaisePropertyChangedAuto(); OnHistoryConfigurationSelected(); }
        }

        private String _filter;
        /// <summary>
        /// Gets or sets the configuration components filter.
        /// </summary>
        public String Filter
        {
            get { return _filter; }
            set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); }
        }

        /// <summary>
        /// Gets or sets the machines provider.
        /// </summary>
        public ISuggestionProvider MachinesProvider { get; set; }

        #endregion

        #region Commands

        /// <summary>
        /// Gets or sets the save command.
        /// </summary>
        public RelayCommand SaveCommand { get; set; }

        /// <summary>
        /// Gets or sets the add ids command.
        /// </summary>
        public RelayCommand AddIdsCommand { get; set; }

        /// <summary>
        /// Gets or sets the remove ids command.
        /// </summary>
        public RelayCommand RemoveIdsCommand { get; set; }

        /// <summary>
        /// Gets or sets the set version configuration command.
        /// </summary>
        public RelayCommand SetVersionConfigurationCommand { get; set; }

        /// <summary>
        /// Gets or sets the set as default command.
        /// </summary>
        public RelayCommand SetAsDefaultCommand { get; set; }

        /// <summary>
        /// Gets or sets the reset command.
        /// </summary>
        public RelayCommand ResetCommand { get; set; }

        #endregion

        #region Constructors

        public MainViewVM()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MainViewVM"/> class.
        /// </summary>
        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()
        {
            await InitCollections();
        }

        #endregion

        private Task InitCollections()
        {
            return Task.Factory.StartNew(() =>
            {
                CanWork = false;

                _db = ObservablesContext.CreateDefault();

                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<Configuration>();
                SelectedHistoryConfiguration = null;
                Filter = String.Empty;
                InitCollections();
            }
        }

        #region Virtual Methods

        /// <summary>
        /// Called when the selected machine has changed.
        /// </summary>
        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.Adapter.GetConfiguration(x => x.Guid == Machine.ConfigurationGuid);

                        SetHistory();

                        _original_configuration = Configuration.Clone();
                    });
                }

                CanWork = true;
            }
            else
            {
                History = new ObservableCollection<Configuration>();
            }
        }

        /// <summary>
        /// Called when the history configuration has been selected
        /// </summary>
        protected virtual void OnHistoryConfigurationSelected()
        {
            if (SelectedHistoryConfiguration != null && CanWork)
            {
                using (_notification.PushTaskItem("Loading Configuration..."))
                {
                    Task.Factory.StartNew(() =>
                    {
                        CanWork = false;

                        SelectedHistoryConfiguration = _db.Adapter.GetConfiguration(x => x.Guid == SelectedHistoryConfiguration.Guid);
                        Configuration = SelectedHistoryConfiguration;
                        Machine.Configuration = Configuration;

                        CanWork = true;
                    });
                }
            }
        }

        /// <summary>
        /// Called when the filter has changed
        /// </summary>
        protected virtual void OnFilterChanged()
        {
            List<ICollectionView> collections = new List<ICollectionView>();
            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

        /// <summary>
        /// Drops the ids pack.
        /// </summary>
        /// <param name="idsPack1">The ids pack1.</param>
        /// <param name="idsPack2">The ids pack2.</param>
        public void DropIdsPack(IdsPack idsPack1, IdsPack idsPack2)
        {
            Configuration.IdsPacks.Swap(idsPack1, idsPack2);
        }

        /// <summary>
        /// Drops the touch panel.
        /// </summary>
        /// <param name="applicationDisplayPanelVersion">The application display panel version.</param>
        public void DropTouchPanel(ApplicationDisplayPanelVersion applicationDisplayPanelVersion)
        {
            Configuration.ApplicationDisplayPanelVersion = applicationDisplayPanelVersion;
            Configuration.ApplicationDisplayPanelVersionGuid = applicationDisplayPanelVersion.Guid;
        }

        /// <summary>
        /// Drops the application firmware version.
        /// </summary>
        /// <param name="applicationFirmwareVersion">The application firmware version.</param>
        public void DropApplicationFirmwareVersion(ApplicationFirmwareVersion applicationFirmwareVersion)
        {
            Configuration.ApplicationFirmwareVersion = applicationFirmwareVersion;
            Configuration.ApplicationFirmwareVersionGuid = applicationFirmwareVersion.Guid;
        }

        /// <summary>
        /// Drops the hardware version.
        /// </summary>
        /// <param name="hardwareVersion">The hardware version.</param>
        public void DropHardwareVersion(HardwareVersion hardwareVersion)
        {
            Configuration.HardwareVersion = hardwareVersion;
            Configuration.HardwareVersionGuid = hardwareVersion.Guid;
        }

        /// <summary>
        /// Drops the embedded firmware.
        /// </summary>
        /// <param name="embeddedFirmwareVersion">The embedded firmware version.</param>
        public void DropEmbeddedFirmware(EmbeddedFirmwareVersion embeddedFirmwareVersion)
        {
            Configuration.EmbeddedFirmwareVersion = embeddedFirmwareVersion;
            Configuration.EmbeddedFirmwareVersionGuid = embeddedFirmwareVersion.Guid;
        }

        /// <summary>
        /// Drops the application os version.
        /// </summary>
        /// <param name="applicationOsVersion">The application os version.</param>
        public void DropApplicationOsVersion(ApplicationOsVersion applicationOsVersion)
        {
            Configuration.ApplicationOsVersion = applicationOsVersion;
            Configuration.ApplicationOsVersionGuid = applicationOsVersion.Guid;
        }

        /// <summary>
        /// Drops the type of the cartridge.
        /// </summary>
        /// <param name="cartridgeType">Type of the cartridge.</param>
        /// <param name="idsPack">The ids pack.</param>
        public void DropCartridgeType(CartridgeType cartridgeType, IdsPack idsPack)
        {
            idsPack.CartridgeType = cartridgeType;
            idsPack.CartridgeTypeGuid = cartridgeType.Guid;
        }

        /// <summary>
        /// Drops the dispenser.
        /// </summary>
        /// <param name="dispenserType">The dispenser.</param>
        /// <param name="idsPack">The ids pack.</param>
        public void DropDispenserType(DispenserType dispenserType, IdsPack idsPack)
        {
            idsPack.DispenserType = dispenserType;
            idsPack.DispenserTypeGuid = dispenserType.Guid;
        }

        /// <summary>
        /// Drops the type of the mid tank.
        /// </summary>
        /// <param name="midTankType">Type of the mid tank.</param>
        /// <param name="idsPack">The ids pack.</param>
        public void DropMidTankType(MidTankType midTankType, IdsPack idsPack)
        {
            idsPack.MidTankType = midTankType;
            idsPack.MidTankTypeGuid = midTankType.Guid;
        }

        /// <summary>
        /// Drops the type of the liquid.
        /// </summary>
        /// <param name="liquidType">Type of the liquid.</param>
        /// <param name="idsPack">The ids pack.</param>
        public void DropLiquidType(LiquidType liquidType, IdsPack idsPack)
        {
            idsPack.LiquidType = liquidType;
            idsPack.LiquidTypeGuid = liquidType.Guid;
        }

        /// <summary>
        /// Drops the ids formula.
        /// </summary>
        /// <param name="idsPackFormula">The ids pack formula.</param>
        /// <param name="idsPack">The ids pack.</param>
        /// <exception cref="NotImplementedException"></exception>
        public void DropIdsFormula(IdsPackFormula idsPackFormula, IdsPack idsPack)
        {
            idsPack.IdsPackFormula = idsPackFormula;
            idsPack.IdsPackFormulaGuid = idsPackFormula.Guid;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Removes the selected IDS pack.
        /// </summary>
        private void RemoveIds()
        {
            _db.IdsPacks.Remove(SelectedIds);
            SelectedIds = null;
        }

        /// <summary>
        /// Adds a new IDS pack.
        /// </summary>
        private void AddIds()
        {
            _db.IdsPacks.Add(new IdsPack() { Configuration = Configuration });
            InvalidateRelayCommands();
        }

        /// <summary>
        /// Saves the current machine configuration.
        /// </summary>
        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<String> errors = new List<string>();

            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();
            }
        }

        /// <summary>
        /// Sets the specified machine history.
        /// </summary>
        /// <param name="machine">The machine.</param>
        private void SetHistory()
        {
            History = _db.MachinesConfigurations.Where(x => x.MachineGuid == Machine.Guid).Select(x => x.Configuration).ToObservableCollection();
            //History.Insert(0, Machine.Configuration);
        }

        /// <summary>
        /// Sets the current configuration to the selected machine version default configuration.
        /// </summary>
        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.Adapter.GetConfiguration(x => x.Guid == version.DefaultConfiguration.Guid);
                        Configuration = version_config.Clone();
                        Machine.Configuration = Configuration;
                    });

                    CanWork = true;
                }
            }
            else
            {
                _notification.ShowError("No machine version selected.");
            }
        }

        /// <summary>
        /// Sets the current configuration as a default machine version configuration.
        /// </summary>
        private void SetAsDefaultConfiguration()
        {
            _notification.ShowModalDialog<MachineVersionDialogVM>(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
    }
}