aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Search/RegexSearchStrategy.cs
blob: e7ca7f8ce1f2d25dec938b9290e492576b3aa6c8 (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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// 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.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Documents;

using Tango.Scripting.Editors.Document;

namespace Tango.Scripting.Editors.Search
{
	class RegexSearchStrategy : ISearchStrategy
	{
		readonly Regex searchPattern;
		readonly bool matchWholeWords;
		
		public RegexSearchStrategy(Regex searchPattern, bool matchWholeWords)
		{
			if (searchPattern == null)
				throw new ArgumentNullException("searchPattern");
			this.searchPattern = searchPattern;
			this.matchWholeWords = matchWholeWords;
		}
		
		public IEnumerable<ISearchResult> FindAll(ITextSource document, int offset, int length)
		{
			int endOffset = offset + length;
			foreach (Match result in searchPattern.Matches(document.Text)) {
				int resultEndOffset = result.Length + result.Index;
				if (offset > result.Index || endOffset < resultEndOffset)
					continue;
				if (matchWholeWords && (!IsWordBorder(document, result.Index) || !IsWordBorder(document, resultEndOffset)))
					continue;
				yield return new SearchResult { StartOffset = result.Index, Length = result.Length, Data = result };
			}
		}
		
		static bool IsWordBorder(ITextSource document, int offset)
		{
			return TextUtilities.GetNextCaretPosition(document, offset - 1, LogicalDirection.Forward, CaretPositioningMode.WordBorder) == offset;
		}
		
		public ISearchResult FindNext(ITextSource document, int offset, int length)
		{
			return FindAll(document, offset, length).FirstOrDefault();
		}
		
		public bool Equals(ISearchStrategy other)
		{
			var strategy = other as RegexSearchStrategy;
			return strategy != null &&
				strategy.searchPattern.ToString() == searchPattern.ToString() &&
				strategy.searchPattern.Options == searchPattern.Options &&
				strategy.searchPattern.RightToLeft == searchPattern.RightToLeft;
		}
	}
	
	class SearchResult : TextSegment, ISearchResult
	{
		public Match Data { get; set; }
		
		public string ReplaceWith(string replacement)
		{
			return Data.Result(replacement);
		}
	}
}
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;

namespace Tango.MachineStudio.HardwareDesigner.ViewModels
{
    public class MainViewVM : ViewModel
    {
        private INotificationProvider _notification;
        private bool _isNew;

        private ObservablesEntitiesAdapter _adapter;
        public ObservablesEntitiesAdapter Adapter
        {
            get { return _adapter; }
            set { _adapter = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareMotorType> _motorTypes;
        public SelectedObjectCollection<HardwareMotorType> MotorTypes
        {
            get { return _motorTypes; }
            set { _motorTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareMotorType> _selectedMotorTypes;
        public ObservableCollection<HardwareMotorType> SelectedMotorTypes
        {
            get { return _selectedMotorTypes; }
            set { _selectedMotorTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareDancerType> _dancerTypes;
        public SelectedObjectCollection<HardwareDancerType> DancerTypes
        {
            get { return _dancerTypes; }
            set { _dancerTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareDancerType> _selectedDancerTypes;
        public ObservableCollection<HardwareDancerType> SelectedDancerTypes
        {
            get { return _selectedDancerTypes; }
            set { _selectedDancerTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwarePidControlType> _pidControlTypes;
        public SelectedObjectCollection<HardwarePidControlType> PidControlTypes
        {
            get { return _pidControlTypes; }
            set { _pidControlTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwarePidControlType> _selectedPidControlTypes;
        public ObservableCollection<HardwarePidControlType> SelectedPidControlTypes
        {
            get { return _selectedPidControlTypes; }
            set { _selectedPidControlTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareWinderType> _winderTypes;
        public SelectedObjectCollection<HardwareWinderType> WinderTypes
        {
            get { return _winderTypes; }
            set { _winderTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareWinderType> _selectedWinderTypes;
        public ObservableCollection<HardwareWinderType> SelectedWinderTypes
        {
            get { return _selectedWinderTypes; }
            set { _selectedWinderTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareSpeedSensorType> _speedSensorTypes;
        public SelectedObjectCollection<HardwareSpeedSensorType> SpeedSensorTypes
        {
            get { return _speedSensorTypes; }
            set { _speedSensorTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareSpeedSensorType> _selectedSpeedSensorTypes;
        public ObservableCollection<HardwareSpeedSensorType> SelectedSpeedSensorTypes
        {
            get { return _selectedSpeedSensorTypes; }
            set { _selectedSpeedSensorTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareBlowerType> _blowerTypes;
        public SelectedObjectCollection<HardwareBlowerType> BlowerTypes
        {
            get { return _blowerTypes; }
            set { _blowerTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareBlowerType> _selectedBlowerTypes;
        public ObservableCollection<HardwareBlowerType> SelectedBlowerTypes
        {
            get { return _selectedBlowerTypes; }
            set { _selectedBlowerTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<HardwareBreakSensorType> _breakSensorTypes;
        public SelectedObjectCollection<HardwareBreakSensorType> BreakSensorTypes
        {
            get { return _breakSensorTypes; }
            set { _breakSensorTypes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<HardwareBreakSensorType> _selectedBreakSensorTypes;
        public ObservableCollection<HardwareBreakSensorType> SelectedBreakSensorTypes
        {
            get { return _selectedBreakSensorTypes; }
            set { _selectedBreakSensorTypes = value; RaisePropertyChangedAuto(); }
        }

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

        private Object _selectedHardwareObjectType;
        public Object SelectedHardwareObjectType
        {
            get { return _selectedHardwareObjectType; }
            set
            {
                _selectedHardwareObjectType = null;
                RaisePropertyChangedAuto();
                _selectedHardwareObjectType = value;
                RaisePropertyChangedAuto();
                OnSelectedHardwareObjectTypeChanged();
            }
        }

        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;

            Adapter = ObservablesEntitiesAdapter.Instance;
            SaveCommand = new RelayCommand(Save, () => SelectedVersion != null);
            NewCommand = new RelayCommand(New);
            DeleteCommand = new RelayCommand(Delete, () => !_isNew && SelectedVersion != null);

            CurrentVersion = new HardwareVersion();
            CreateTemplate(CurrentVersion);

            CopyParametersCommand = new RelayCommand(CopyParameters, (x) => SelectedVersion != null && SelectedHardwareObjectType != null);
            CloneCommand = new RelayCommand(CloneCurrentVersion, () => SelectedVersion != null);
        }

        private void CopyParameters(object obj)
        {
            IObservableEntity source = obj.GetType().GetProperty("Data").GetValue(obj) as IObservableEntity;
            IObservableEntity target = null;

            if (source is HardwareMotorType)
            {
                target = CurrentVersion.HardwareMotors.SingleOrDefault(x => x.HardwareMotorType == source);
            }
            else if (source is HardwareDancerType)
            {
                target = CurrentVersion.HardwareDancers.SingleOrDefault(x => x.HardwareDancerType == source);
            }
            else if (source is HardwarePidControlType)
            {
                target = CurrentVersion.HardwarePidControls.SingleOrDefault(x => x.HardwarePidControlType == source);
            }
            else if (source is HardwareWinderType)
            {
                target = CurrentVersion.HardwareWinders.SingleOrDefault(x => x.HardwareWinderType == source);
            }
            else if (source is HardwareSpeedSensorType)
            {
                target = CurrentVersion.HardwareSpeedSensors.SingleOrDefault(x => x.HardwareSpeedSensorType == source);
            }
            else if (source is HardwareBlowerType)
            {
                target = CurrentVersion.HardwareBlowers.SingleOrDefault(x => x.HardwareBlowerType == source);
            }
            else if (source is HardwareBreakSensorType)
            {
                target = CurrentVersion.HardwareBreakSensors.SingleOrDefault(x => x.HardwareBreakSensorType == source);
            }

            target.MapPrimitivesTo(SelectedHardwareObject);
        }

        private void OnSelectedHardwareObjectTypeChanged()
        {
            if (SelectedHardwareObjectType != null)
            {
                if (SelectedHardwareObjectType is SelectedObject<HardwareMotorType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareMotorType>).Data;
                    var hardwareObj = CurrentVersion.HardwareMotors.SingleOrDefault(x => x.HardwareMotorType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareMotor() { HardwareMotorType = type };
                        CurrentVersion.HardwareMotors.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwareDancerType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareDancerType>).Data;
                    var hardwareObj = CurrentVersion.HardwareDancers.SingleOrDefault(x => x.HardwareDancerType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareDancer() { HardwareDancerType = type };
                        CurrentVersion.HardwareDancers.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwarePidControlType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwarePidControlType>).Data;
                    var hardwareObj = CurrentVersion.HardwarePidControls.SingleOrDefault(x => x.HardwarePidControlType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwarePidControl() { HardwarePidControlType = type };
                        CurrentVersion.HardwarePidControls.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwareWinderType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareWinderType>).Data;
                    var hardwareObj = CurrentVersion.HardwareWinders.SingleOrDefault(x => x.HardwareWinderType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareWinder() { HardwareWinderType = type };
                        CurrentVersion.HardwareWinders.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwareSpeedSensorType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareSpeedSensorType>).Data;
                    var hardwareObj = CurrentVersion.HardwareSpeedSensors.SingleOrDefault(x => x.HardwareSpeedSensorType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareSpeedSensor() { HardwareSpeedSensorType = type };
                        CurrentVersion.HardwareSpeedSensors.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwareBlowerType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareBlowerType>).Data;
                    var hardwareObj = CurrentVersion.HardwareBlowers.SingleOrDefault(x => x.HardwareBlowerType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareBlower() { HardwareBlowerType = type };
                        CurrentVersion.HardwareBlowers.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
                else if (SelectedHardwareObjectType is SelectedObject<HardwareBreakSensorType>)
                {
                    var type = (SelectedHardwareObjectType as SelectedObject<HardwareBreakSensorType>).Data;
                    var hardwareObj = CurrentVersion.HardwareBreakSensors.SingleOrDefault(x => x.HardwareBreakSensorType == type);

                    if (hardwareObj != null)
                    {
                        SelectedHardwareObject = hardwareObj;
                    }
                    else
                    {
                        hardwareObj = new HardwareBreakSensor() { HardwareBreakSensorType = type };
                        CurrentVersion.HardwareBreakSensors.Add(hardwareObj);
                        SelectedHardwareObject = hardwareObj;
                    }
                }
            }
        }

        private void CreateTemplate(HardwareVersion version)
        {
            if (version == null)
            {
                SelectedMotorTypes = new ObservableCollection<HardwareMotorType>();
                SelectedDancerTypes = new ObservableCollection<HardwareDancerType>();
                SelectedPidControlTypes = new ObservableCollection<HardwarePidControlType>();
                SelectedWinderTypes = new ObservableCollection<HardwareWinderType>();
                SelectedSpeedSensorTypes = new ObservableCollection<HardwareSpeedSensorType>();
                SelectedBlowerTypes = new ObservableCollection<HardwareBlowerType>();
                SelectedBreakSensorTypes = new ObservableCollection<HardwareBreakSensorType>();
            }
            else
            {
                SelectedMotorTypes = version.HardwareMotors.Select(x => x.HardwareMotorType).ToObservableCollection();
                SelectedDancerTypes = version.HardwareDancers.Select(x => x.HardwareDancerType).ToObservableCollection();
                SelectedPidControlTypes = version.HardwarePidControls.Select(x => x.HardwarePidControlType).ToObservableCollection();
                SelectedWinderTypes = version.HardwareWinders.Select(x => x.HardwareWinderType).ToObservableCollection();
                SelectedSpeedSensorTypes = version.HardwareSpeedSensors.Select(x => x.HardwareSpeedSensorType).ToObservableCollection();
                SelectedBlowerTypes = version.HardwareBlowers.Select(x => x.HardwareBlowerType).ToObservableCollection();
                SelectedBreakSensorTypes = version.HardwareBreakSensors.Select(x => x.HardwareBreakSensorType).ToObservableCollection();
            }

            MotorTypes = new SelectedObjectCollection<HardwareMotorType>(Adapter.HardwareMotorTypes, SelectedMotorTypes);
            DancerTypes = new SelectedObjectCollection<HardwareDancerType>(Adapter.HardwareDancerTypes, SelectedDancerTypes);
            PidControlTypes = new SelectedObjectCollection<HardwarePidControlType>(Adapter.HardwarePidControlTypes, SelectedPidControlTypes);
            WinderTypes = new SelectedObjectCollection<HardwareWinderType>(Adapter.HardwareWinderTypes, SelectedWinderTypes);
            SpeedSensorTypes = new SelectedObjectCollection<HardwareSpeedSensorType>(Adapter.HardwareSpeedSensorTypes, SelectedSpeedSensorTypes);
            BlowerTypes = new SelectedObjectCollection<HardwareBlowerType>(Adapter.HardwareBlowerTypes, SelectedBlowerTypes);
            BreakSensorTypes = new SelectedObjectCollection<HardwareBreakSensorType>(Adapter.HardwareBreakSensorTypes, SelectedBreakSensorTypes);
        }

        private void OnSelectedVersionChanged()
        {
            if (SelectedVersion != null)
            {
                _isNew = false;
                CurrentVersion = SelectedVersion.Clone();
                CreateTemplate(CurrentVersion);
            }

            InvalidateRelayCommands();
        }

        private bool CheckCurrentVersionNull()
        {
            if (CurrentVersion == null)
            {
                _notification.ShowInfo("Please select a hardware version before attempting to insert any components.");
                return true;
            }

            return false;
        }

        private void New()
        {
            String name = _notification.ShowTextInput("Enter hardware version name", "Name");

            if (!String.IsNullOrWhiteSpace(name))
            {
                SelectedVersion = null;
                CurrentVersion = new HardwareVersion();
                CurrentVersion.Version = Adapter.HardwareVersions.Max(x => x.Version) + 1;
                CurrentVersion.Name = name;
                CreateTemplate(CurrentVersion);
                _isNew = true;
                InvalidateRelayCommands();
            }
        }

        private async void Save()
        {
            if (CurrentVersion != null)
            {
                using (_notification.PushTaskItem("Saving hardware version..."))
                {
                    await Task.Factory.StartNew(() =>
                    {
                        HardwareVersion realVersion = null;

                        if (_isNew)
                        {
                            realVersion = CurrentVersion.Clone();

                            realVersion.HardwareMotors.ToList().Where(x => !SelectedMotorTypes.Contains(x.HardwareMotorType)).ToList().ForEach(x => realVersion.HardwareMotors.Remove(x));
                            realVersion.HardwareDancers.ToList().Where(x => !SelectedDancerTypes.Contains(x.HardwareDancerType)).ToList().ForEach(x => realVersion.HardwareDancers.Remove(x));
                            realVersion.HardwarePidControls.ToList().Where(x => !SelectedPidControlTypes.Contains(x.HardwarePidControlType)).ToList().ForEach(x => realVersion.HardwarePidControls.Remove(x));
                            realVersion.HardwareWinders.ToList().Where(x => !SelectedWinderTypes.Contains(x.HardwareWinderType)).ToList().ForEach(x => realVersion.HardwareWinders.Remove(x));
                            realVersion.HardwareSpeedSensors.ToList().Where(x => !SelectedSpeedSensorTypes.Contains(x.HardwareSpeedSensorType)).ToList().ForEach(x => realVersion.HardwareSpeedSensors.Remove(x));
                            realVersion.HardwareBlowers.ToList().Where(x => !SelectedBlowerTypes.Contains(x.HardwareBlowerType)).ToList().ForEach(x => realVersion.HardwareBlowers.Remove(x));
                            realVersion.HardwareBreakSensors.ToList().Where(x => !SelectedBreakSensorTypes.Contains(x.HardwareBreakSensorType)).ToList().ForEach(x => realVersion.HardwareBreakSensors.Remove(x));
                        }
                        else
                        {
                            realVersion = Adapter.HardwareVersions.SingleOrDefault(x => x.Guid == SelectedVersion.Guid);

                            realVersion.Version = CurrentVersion.Version;
                            realVersion.Name = CurrentVersion.Name;

                            realVersion.HardwareDancers.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwareMotors.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwarePidControls.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwareWinders.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwareSpeedSensors.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwareBlowers.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));
                            realVersion.HardwareBreakSensors.ToList().ForEach(x => x.DefferedDelete(Adapter.Context));

                            realVersion.HardwareDancers.Clear();
                            realVersion.HardwareMotors.Clear();
                            realVersion.HardwarePidControls.Clear();
                            realVersion.HardwareWinders.Clear();
                            realVersion.HardwareSpeedSensors.Clear();
                            realVersion.HardwareBlowers.Clear();
                            realVersion.HardwareBreakSensors.Clear();

                            foreach (var type in SelectedDancerTypes)
                            {
                                var item = CurrentVersion.HardwareDancers.SingleOrDefault(x => x.HardwareDancerType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareDancers.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareDancers.Add(new HardwareDancer()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareDancerType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedMotorTypes)
                            {
                                var item = CurrentVersion.HardwareMotors.SingleOrDefault(x => x.HardwareMotorType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareMotors.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareMotors.Add(new HardwareMotor()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareMotorType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedPidControlTypes)
                            {
                                var item = CurrentVersion.HardwarePidControls.SingleOrDefault(x => x.HardwarePidControlType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwarePidControls.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwarePidControls.Add(new HardwarePidControl()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwarePidControlType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedWinderTypes)
                            {
                                var item = CurrentVersion.HardwareWinders.SingleOrDefault(x => x.HardwareWinderType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareWinders.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareWinders.Add(new HardwareWinder()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareWinderType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedSpeedSensorTypes)
                            {
                                var item = CurrentVersion.HardwareSpeedSensors.SingleOrDefault(x => x.HardwareSpeedSensorType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareSpeedSensors.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareSpeedSensors.Add(new HardwareSpeedSensor()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareSpeedSensorType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedBlowerTypes)
                            {
                                var item = CurrentVersion.HardwareBlowers.SingleOrDefault(x => x.HardwareBlowerType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareBlowers.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareBlowers.Add(new HardwareBlower()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareBlowerType = type
                                    });
                                }
                            }

                            foreach (var type in SelectedBreakSensorTypes)
                            {
                                var item = CurrentVersion.HardwareBreakSensors.SingleOrDefault(x => x.HardwareBreakSensorType == type);
                                if (item != null)
                                {
                                    item.HardwareVersionGuid = realVersion.Guid;
                                    realVersion.HardwareBreakSensors.Add(item);
                                }
                                else
                                {
                                    realVersion.HardwareBreakSensors.Add(new HardwareBreakSensor()
                                    {
                                        HardwareVersionGuid = realVersion.Guid,
                                        HardwareBreakSensorType = type
                                    });
                                }
                            }
                        }



                        if (_isNew)
                        {
                            Adapter.Context.HardwareVersions.Add(realVersion);
                        }

                        realVersion.Save(Adapter.Context);

                        SelectedVersion = Adapter.HardwareVersions.SingleOrDefault(x => x.Guid == realVersion.Guid);
                    });
                }
            }
        }

        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..."))
                    {
                        await Task.Factory.StartNew(() =>
                        {
                            var realVersion = CurrentVersion.Clone();
                            realVersion.Name = name;
                            realVersion.Version = 1;

                            realVersion.HardwareMotors.ToList().Where(x => !SelectedMotorTypes.Contains(x.HardwareMotorType)).ToList().ForEach(x => realVersion.HardwareMotors.Remove(x));
                            realVersion.HardwareDancers.ToList().Where(x => !SelectedDancerTypes.Contains(x.HardwareDancerType)).ToList().ForEach(x => realVersion.HardwareDancers.Remove(x));
                            realVersion.HardwarePidControls.ToList().Where(x => !SelectedPidControlTypes.Contains(x.HardwarePidControlType)).ToList().ForEach(x => realVersion.HardwarePidControls.Remove(x));
                            realVersion.HardwareWinders.ToList().Where(x => !SelectedWinderTypes.Contains(x.HardwareWinderType)).ToList().ForEach(x => realVersion.HardwareWinders.Remove(x));
                            realVersion.HardwareSpeedSensors.ToList().Where(x => !SelectedSpeedSensorTypes.Contains(x.HardwareSpeedSensorType)).ToList().ForEach(x => realVersion.HardwareSpeedSensors.Remove(x));
                            realVersion.HardwareBlowers.ToList().Where(x => !SelectedBlowerTypes.Contains(x.HardwareBlowerType)).ToList().ForEach(x => realVersion.HardwareBlowers.Remove(x));
                            realVersion.HardwareBreakSensors.ToList().Where(x => !SelectedBreakSensorTypes.Contains(x.HardwareBreakSensorType)).ToList().ForEach(x => realVersion.HardwareBreakSensors.Remove(x));

                            realVersion.HardwareMotors.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwareDancers.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwarePidControls.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwareWinders.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwareSpeedSensors.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwareBlowers.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);
                            realVersion.HardwareBreakSensors.ToList().ForEach(x => x.HardwareVersionGuid = realVersion.Guid);

                            realVersion.HardwareMotors.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwareDancers.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwarePidControls.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwareWinders.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwareSpeedSensors.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwareBlowers.ToList().ForEach(x => x.HardwareVersion = realVersion);
                            realVersion.HardwareBreakSensors.ToList().ForEach(x => x.HardwareVersion = realVersion);

                            Adapter.Context.HardwareVersions.Add(realVersion);
                            realVersion.Save(Adapter.Context);

                            SelectedVersion = Adapter.HardwareVersions.SingleOrDefault(x => x.Guid == realVersion.Guid);
                        });
                    }
                }
            }
        }

        private void Delete()
        {
            if (_notification.ShowQuestion("Are you sure you want to delete this hardware version?"))
            {
                using (_notification.PushTaskItem("Deleting hardware version..."))
                {
                    SelectedVersion.DeleteAsync(Adapter.Context);
                    SelectedVersion = null;
                    CurrentVersion = null;
                }
            }
        }

        protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
        {
            base.RaisePropertyChangedAuto(caller);
            InvalidateRelayCommands();
        }
    }
}