aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs
blob: 361608ef6b9ee374d59ca276626679694d9b0b22 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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 */
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:cc="clr-namespace:Tango.Scripting.Editors.CodeCompletion"
>
	<cc:InsightWindowTemplateSelector x:Key="templateSelector" />
	
	<!-- Template for InsightWindow. Based on the template for ToolTip. -->
	<Style TargetType="{x:Type cc:InsightWindow}">
		<Setter Property="SizeToContent" Value="WidthAndHeight" />
		
		<Setter Property="BorderThickness" Value="1" />
		<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" />
		<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" />
		<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}" />
		<Setter Property="FontFamily" Value="{DynamicResource {x:Static SystemFonts.StatusFontFamilyKey}}" />
		<Setter Property="FontSize" Value="{DynamicResource {x:Static SystemFonts.StatusFontSizeKey}}" />
		<Setter Property="FontStyle" Value="{DynamicResource {x:Static SystemFonts.StatusFontStyleKey}}" />
		<Setter Property="FontWeight" Value="{DynamicResource {x:Static SystemFonts.StatusFontWeightKey}}" />
		<Setter Property="Padding" Value="1,1,3,1" />
		<Setter Property="HorizontalContentAlignment" Value="Left" />
		<Setter Property="VerticalContentAlignment" Value="Center" />
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type cc:InsightWindow}">
					<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
					        Padding="{TemplateBinding Control.Padding}"
					        CornerRadius="2,2,2,2"
					        BorderBrush="{TemplateBinding Border.BorderBrush}"
					        Background="{TemplateBinding Panel.Background}">
						<AdornerDecorator>
							<ContentPresenter
								Content="{TemplateBinding ContentControl.Content}"
								ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
								ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
								HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
								VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
								SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
						</AdornerDecorator>
					</Border>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
	
	<!-- Template for OverloadViewer. -->
	<Style TargetType="{x:Type cc:OverloadViewer}">
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type cc:OverloadViewer}">
					<Grid>
						<Grid.Resources>
							<cc:CollapseIfSingleOverloadConverter x:Key="collapseIfSingleOverloadConverter"/>
							
							<!-- Style of the UpDownButton -->
							<Style TargetType="{x:Type Button}" x:Key="upDownButtonStyle">
								<Style.Setters>
									<Setter Property="Background" Value="LightGray"/>
									<Setter Property="Padding" Value="2,2,2,2"/>
									<Setter Property="Width" Value="9"/>
									<Setter Property="Height" Value="9"/>
									<Setter Property="SnapsToDevicePixels" Value="True"/>
									<Setter Property="OverridesDefaultStyle" Value="True"/>
									<Setter Property="Template">
										<Setter.Value>
											<ControlTemplate TargetType="{x:Type Button}">
												<Border Name="bd"
												        Background="{TemplateBinding Background}" CornerRadius="2">
													<ContentControl Margin="{TemplateBinding Padding}"
													                Content="{TemplateBinding Content}"/>
												</Border>
												<ControlTemplate.Triggers>
													<Trigger Property="IsMouseOver" Value="true">
														<Setter TargetName="bd" Property="Background" Value="LightBlue"/>
													</Trigger>
												</ControlTemplate.Triggers>
											</ControlTemplate>
										</Setter.Value>
									</Setter>
								</Style.Setters>
							</Style>
						
							<DataTemplate x:Key="TextBlockTemplate">
								<TextBlock TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
							</DataTemplate>
						</Grid.Resources>
						
						<Grid.ColumnDefinitions>
							<ColumnDefinition Width="Auto"/>
							<ColumnDefinition Width="1*"/>
						</Grid.ColumnDefinitions>
						<Grid.RowDefinitions>
							<RowDefinition Height="Auto"/>
							<RowDefinition Height="1*"/>
						</Grid.RowDefinitions>
						
						<StackPanel Grid.Row="0" Grid.Column="0"
						            Margin="0,0,4,0"
						            Orientation="Horizontal"
						            Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.Count, Converter={StaticResource collapseIfSingleOverloadConverter}}">
							<Button Name="PART_UP" Style="{StaticResource upDownButtonStyle}">
								<Path Stroke="Black" Fill="Black" Data="M 0,0.866 L 1,0.866 L 0.5,0 Z" Stretch="UniformToFill" />
							</Button>
							<TextBlock Margin="2,0,2,0"
							           Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentIndexText}"/>
							<Button Name="PART_DOWN" Style="{StaticResource upDownButtonStyle}">
								<Path Stroke="Black" Fill="Black" Data="M 0,0 L 1,0 L 0.5,0.866 Z" Stretch="UniformToFill" />
							</Button>
						</StackPanel>
						<ContentPresenter Grid.Row="0" Grid.Column="1" ContentTemplateSelector="{StaticResource templateSelector}"
						                  Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentHeader}" />
						<ContentPresenter Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ContentTemplateSelector="{StaticResource templateSelector}"
						                  Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Provider.CurrentContent}" />
					</Grid>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</ResourceDictionary>
'#n502'>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
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Calibration;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.RML.Contracts;
using Tango.MachineStudio.RML.Models;
using Tango.MachineStudio.RML.Views;
using Tango.PMR.ColorLab;
using System.Data.Entity;

namespace Tango.MachineStudio.RML.ViewModels
{
    public class MainViewVM : StudioViewModel<IMainView>
    {
        private INotificationProvider _notification;

        private ObservablesContext _rmls_context;
        private ObservablesContext _active_context;

        private ObservableCollection<Rml> _rmls;
        public ObservableCollection<Rml> Rmls
        {
            get { return _rmls; }
            set { _rmls = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<MediaMaterial> _materials;
        public ObservableCollection<MediaMaterial> Materials
        {
            get { return _materials; }
            set { _materials = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<MediaPurpos> _purposes;
        public ObservableCollection<MediaPurpos> Purposes
        {
            get { return _purposes; }
            set { _purposes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<MediaCondition> _conditions;
        public ObservableCollection<MediaCondition> Conditions
        {
            get { return _conditions; }
            set { _conditions = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<LinearMassDensityUnit> _linearMassDensityUnits;
        public ObservableCollection<LinearMassDensityUnit> LinearMassDensityUnits
        {
            get { return _linearMassDensityUnits; }
            set { _linearMassDensityUnits = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<FiberShape> _fiberShapes;
        public ObservableCollection<FiberShape> FiberShapes
        {
            get { return _fiberShapes; }
            set { _fiberShapes = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<FiberSynth> _fiberSynths;
        public ObservableCollection<FiberSynth> FiberSynths
        {
            get { return _fiberSynths; }
            set { _fiberSynths = value; RaisePropertyChangedAuto(); }
        }

        private Rml _selectedRML;
        public Rml SelectedRML
        {
            get { return _selectedRML; }
            set { _selectedRML = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
        }

        private Rml _activeRML;
        public Rml ActiveRML
        {
            get { return _activeRML; }
            set { _activeRML = value; RaisePropertyChangedAuto(); }
        }

        private CalibrationDataViewVM _calibrationDataViewVM;
        public CalibrationDataViewVM CalibrationDataViewVM
        {
            get { return _calibrationDataViewVM; }
            set { _calibrationDataViewVM = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<LiquidTypesRml> _liquidTypesRmls;
        public ObservableCollection<LiquidTypesRml> LiquidTypesRmls
        {
            get { return _liquidTypesRmls; }
            set { _liquidTypesRmls = value; RaisePropertyChangedAuto(); }
        }

        private ProcessParametersTablesGroup _activeProcessParametersGroup;
        public ProcessParametersTablesGroup ActiveProcessParametersGroup
        {
            get { return _activeProcessParametersGroup; }
            set { _activeProcessParametersGroup = value; RaisePropertyChangedAuto(); }
        }

        private ICollectionView _activeProcessParametersTableView;
        public ICollectionView ActiveProcessParametersTableView
        {
            get { return _activeProcessParametersTableView; }
            set { _activeProcessParametersTableView = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<CctModel> _ccts;
        public ObservableCollection<CctModel> CCTS
        {
            get { return _ccts; }
            set { _ccts = value; RaisePropertyChangedAuto(); }
        }

        private CctModel _selectedCCT;
        public CctModel SelectedCCT
        {
            get { return _selectedCCT; }
            set { _selectedCCT = value; RaisePropertyChangedAuto(); OnSelectedCCTChanged(); InvalidateRelayCommands(); }
        }

        private ColorConversionViewVM _colorConversionViewVM;
        public ColorConversionViewVM ColorConversionViewVM
        {
            get { return _colorConversionViewVM; }
            set { _colorConversionViewVM = value; RaisePropertyChangedAuto(); }
        }

        /// <summary>
        /// Gets or sets the manage RML command.
        /// </summary>
        public RelayCommand ManageRmlCommand { get; set; }

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

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

        public RelayCommand ImportForwardDataCommand { get; set; }

        public RelayCommand ExportForwardDataCommand { get; set; }

        public RelayCommand AddProcessParametersTableCommand { get; set; }

        public RelayCommand<ProcessParametersTable> RemoveProcessParametersTableCommand { get; set; }

        public RelayCommand AddLiquidFactorCommand { get; set; }

        public RelayCommand<LiquidTypesRml> RemoveLiquidFactorCommand { get; set; }

        public RelayCommand CreateCalibrationDataExcelTemplateCommand { get; set; }

        /// <summary>
        /// Gets or sets the back to RMLS command.
        /// </summary>
        public RelayCommand BackToRmlsCommand { get; set; }

        public RelayCommand SaveCommand { get; set; }

        public MainViewVM(INotificationProvider notificationProvider)
        {
            _notification = notificationProvider;
            ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null);
            RemoveRmlCommand = new RelayCommand(RemoveSelectedRml);
            AddRmlCommand = new RelayCommand(AddNewRml);
            BackToRmlsCommand = new RelayCommand(BackToRmls, () => IsFree);
            AddProcessParametersTableCommand = new RelayCommand(AddProcessParametersTable, () => IsFree);
            RemoveProcessParametersTableCommand = new RelayCommand<ProcessParametersTable>(RemoveProcessParametersTable, () => IsFree);
            AddLiquidFactorCommand = new RelayCommand(AddLiquidFactor, () => IsFree);
            RemoveLiquidFactorCommand = new RelayCommand<LiquidTypesRml>(RemoveLiquidFactor, () => IsFree);
            CreateCalibrationDataExcelTemplateCommand = new RelayCommand(CreateCalibrationDataExcelTemplate);
            SaveCommand = new RelayCommand(Save, () => IsFree);

            ImportForwardDataCommand = new RelayCommand(ImportCCTData, () => ActiveRML != null && IsFree);

            ExportForwardDataCommand = new RelayCommand(ExportCCTData, () => ActiveRML != null && SelectedCCT != null && IsFree);
        }

        public override void OnApplicationReady()
        {
            LoadRmls();
        }

        private async void LoadRmls()
        {
            if (_rmls_context != null) _rmls_context.Dispose();

            _rmls_context = ObservablesContext.CreateDefault();
            Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync();
        }

        private async void LoadActiveRML(String guid)
        {
            using (_notification.PushTaskItem("Loading RML..."))
            {
                IsFree = false;

                if (_active_context != null)
                {
                    _active_context.Dispose();
                }

                _active_context = ObservablesContext.CreateDefault();

                CCTS = _active_context.Ccts
                    .Select(x => new CctModel()
                    {
                        Guid = x.Guid,
                        FileName = x.FileName,

                    }).ToObservableCollection();

                CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid);

                LoadRmlProperties();

                ActiveRML = await new RmlBuilder(_active_context)
                    .Set(guid)
                    .WithActiveParametersGroup()
                    .WithLiquidFactors()
                    .WithCCT()
                    .BuildAsync();

                if (ActiveRML.Cct != null)
                {
                    SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid);
                }

                if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0)
                {
                    if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?"))
                    {
                        _notification.ShowError("Cannot load an RML with no process group.");
                        IsFree = true;
                        return;
                    }
                    else
                    {
                        ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
                        group.Name = "Active Group";
                        group.Active = true;
                        group.ProcessParametersTables.Add(new ProcessParametersTable()
                        {
                            Name = "Process Table 1",
                        });

                        group.Rml = ActiveRML;

                        _active_context.ProcessParametersTablesGroups.Add(group);
                        _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]);
                        await _active_context.SaveChangesAsync();
                        LoadActiveRML(ActiveRML.Guid);
                        return;
                    }
                }

                ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault();
                ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables);
                ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending));

                CalibrationDataViewVM = new CalibrationDataViewVM(_notification);
                LiquidTypesRmls = ActiveRML.LiquidTypesRmls;

                foreach (var liquidTypeRml in LiquidTypesRmls)
                {
                    CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType);

                    if (liquidTypeRml.DefaultCatData != null)
                    {
                        catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection();
                    }

                    CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM);
                }

                ColorConversionViewVM = new ColorConversionViewVM(_notification)
                {
                    RML = ActiveRML,
                    CCT = SelectedCCT,
                    LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData,
                    LiquidTypesRmls = LiquidTypesRmls,
                };

                View.NavigateTo(RmlNavigationView.RmlView);

                InvalidateRelayCommands();

                IsFree = true;
            }
        }

        private async void OnSelectedCCTChanged()
        {
            if (SelectedCCT != null && !SelectedCCT.IsNew)
            {
                using (_notification.PushTaskItem("Loading CCT data..."))
                {
                    IsFree = false;

                    var cct = await _active_context.Ccts.SingleOrDefaultAsync(x => x.Guid == SelectedCCT.Guid);

                    if (cct != null)
                    {
                        SelectedCCT.Data = cct.Data;
                        ColorConversionViewVM.CCT = SelectedCCT;
                    }

                    IsFree = true;
                }
            }
        }

        private void LoadRmlProperties()
        {
            Materials = _active_context.MediaMaterials.ToObservableCollection();
            Purposes = _active_context.MediaPurposes.ToObservableCollection();
            Conditions = _active_context.MediaConditions.ToObservableCollection();
            LinearMassDensityUnits = _active_context.LinearMassDensityUnits.ToObservableCollection();
            FiberShapes = _active_context.FiberShapes.ToObservableCollection();
            FiberSynths = _active_context.FiberSynths.ToObservableCollection();
        }

        private async void AddNewRml()
        {
            var name = _notification.ShowTextInput("Please enter RML name", "Name");

            if (!String.IsNullOrWhiteSpace(name))
            {
                if (Rmls.ToList().Exists(x => x.Name == name))
                {
                    _notification.ShowError("The specified RML name already exists. Please select a different name.");
                    return;
                }

                using (_notification.PushTaskItem("Creating new RML..."))
                {
                    IsFree = false;

                    if (_active_context != null)
                    {
                        _active_context.Dispose();
                    }

                    _active_context = ObservablesContext.CreateDefault();

                    LoadRmlProperties();

                    Rml rml = new Rml();
                    rml.Name = name;
                    rml.Manufacturer = "Twine";
                    rml.Code = Rmls.Max(x => x.Code) + 1;
                    rml.MediaMaterial = Materials.FirstOrDefault();
                    rml.MediaPurpose = Purposes.FirstOrDefault();
                    rml.MediaCondition = Conditions.FirstOrDefault();
                    rml.LinearMassDensityUnit = LinearMassDensityUnits.FirstOrDefault();
                    rml.FiberShape = FiberShapes.FirstOrDefault();
                    rml.FiberSynth = FiberSynths.FirstOrDefault();

                    ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
                    group.Name = "Active Group";
                    group.Active = true;
                    group.ProcessParametersTables.Add(new ProcessParametersTable()
                    {
                        Name = "Process Table 1",
                    });

                    group.Rml = rml;

                    _active_context.ProcessParametersTablesGroups.Add(group);
                    _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]);
                    _active_context.Rmls.Add(rml);
                    await _active_context.SaveChangesAsync();
                    LoadActiveRML(rml.Guid);

                    IsFree = true;
                }
            }
        }

        private async void RemoveSelectedRml()
        {
            if (_notification.ShowQuestion("Removing the selected RML will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?"))
            {
                IsFree = false;

                using (_notification.PushTaskItem("Removing RML..."))
                {
                    try
                    {
                        await SelectedRML.DeleteCascadeAsync(_rmls_context);
                        LoadRmls();
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, $"Error removing selected RML {SelectedRML.Name}.");
                        _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.Message}");
                    }
                }

                IsFree = true;
            }
        }

        private void AddProcessParametersTable()
        {
            var name = _notification.ShowTextInput("Enter table name", "Name");

            if (!String.IsNullOrWhiteSpace(name))
            {
                _active_context.ProcessParametersTables.Add(new ProcessParametersTable()
                {
                    ProcessParametersTablesGroup = ActiveProcessParametersGroup,
                    Name = name,
                    TableIndex = ActiveProcessParametersGroup.ProcessParametersTables.Max(x => x.TableIndex) + 1,
                });
            }
        }

        public void OnProcessParametersTableDropped(ProcessParametersTable dragged, ProcessParametersTable dropped)
        {
            if (dragged.TableIndex > dropped.TableIndex)
            {
                dragged.TableIndex = dropped.TableIndex - 1;
            }
            else
            {
                dragged.TableIndex = dropped.TableIndex + 1;
            }

            int index = 0;

            foreach (var table in ActiveProcessParametersGroup.ProcessParametersTables.OrderBy(x => x.TableIndex))
            {
                table.TableIndex = index++;
            }

            ActiveProcessParametersTableView.Refresh();
        }

        private void RemoveLiquidFactor(LiquidTypesRml liquidFactor)
        {
            if (_notification.ShowQuestion("Removing this liquid factor will remove the liquid type association with the RML and will drop the calibration data. Are you sure?"))
            {
                var catVM = CalibrationDataViewVM.LiquidsCalibrationData.SingleOrDefault(x => x.LiquidType == liquidFactor.LiquidType);
                CalibrationDataViewVM.LiquidsCalibrationData.Remove(catVM);
                _active_context.LiquidTypesRmls.Remove(liquidFactor);
            }
        }

        private void AddLiquidFactor()
        {
            AddLiquidFactorViewVM vm = new AddLiquidFactorViewVM(_active_context);
            _notification.ShowModalDialog<AddLiquidFactorViewVM, AddLiquidFactorView>(vm, (_) =>
            {
                if (LiquidTypesRmls.ToList().Exists(x => x.LiquidType == vm.SelectedLiquidType))
                {
                    _notification.ShowError("The selected liquid type is already associated with this RML.");
                    return;
                }

                LiquidTypesRml liquidFactor = new LiquidTypesRml()
                {
                    LiquidType = vm.SelectedLiquidType,
                    Rml = ActiveRML,
                };

                _active_context.LiquidTypesRmls.Add(liquidFactor);

                CalibrationDataVM catVM = new CalibrationDataVM(liquidFactor.LiquidType);

                CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM);

            }, () => { });
        }

        private void RemoveProcessParametersTable(ProcessParametersTable processParametersTable)
        {
            if (ActiveProcessParametersGroup.ProcessParametersTables.Count == 1)
            {
                _notification.ShowError("The process group must contain at least one table.");
                return;
            }

            if (_notification.ShowQuestion("Are you sure you want to remove this process parameters table?"))
            {
                _active_context.ProcessParametersTables.Remove(processParametersTable);
            }
        }

        private void CreateCalibrationDataExcelTemplate()
        {
            SaveFileDialog dlg = new SaveFileDialog();
            try
            {
                dlg.Title = $"Create excel template file";
                dlg.Filter = "Excel Files|*.xlsx";
                dlg.DefaultExt = ".xlsx";
                dlg.FileName = "Calibration File Template";
                if (dlg.ShowDialog().Value)
                {
                    CalibrationHelper.CreateCalibrationDataExcelTemplate(dlg.FileName);
                }
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error generating excel calibration template file " + dlg.FileName);
                _notification.ShowError("An error occurred while trying to generate the calibration file.");
            }
        }

        private async void Save()
        {
            IsFree = false;

            try
            {
                using (_notification.PushTaskItem("Saving RML..."))
                {
                    foreach (var calDataVM in CalibrationDataViewVM.LiquidsCalibrationData)
                    {
                        var liquidTypeRml = LiquidTypesRmls.SingleOrDefault(x => x.LiquidType == calDataVM.LiquidType);
                        CalibrationData calData = new CalibrationData();
                        calData.LiquidType = (PMR.ColorLab.LiquidType)liquidTypeRml.LiquidType.Code;
                        calData.CalibrationPoints.AddRange(calDataVM.CalibrationPoints.Select(x => new CalibrationPoint() { X = x.X, Y = x.Y }));
                        liquidTypeRml.PutCalibrationData(calData);
                    }

                    ActiveRML.LastUpdated = DateTime.UtcNow;

                    if (SelectedCCT != null)
                    {
                        if (SelectedCCT.IsNew)
                        {
                            Cct cct = new Cct();
                            cct.Guid = SelectedCCT.Guid;
                            cct.FileName = SelectedCCT.FileName;
                            cct.Data = SelectedCCT.Data;
                            ActiveRML.Cct = cct;
                            SelectedCCT.IsNew = false;
                        }
                        else
                        {
                            ActiveRML.CctGuid = SelectedCCT.Guid;
                        }
                    }

                    await _active_context.SaveChangesAsync();
                }
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, $"Error saving RML {ActiveRML.Name}");
                _notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.Message}");
            }

            LoadActiveRML(ActiveRML.Guid);

            IsFree = true;
        }

        private void BackToRmls()
        {
            View.NavigateTo(RmlNavigationView.RmlsView);
            LoadRmls();
        }

        #region Import / Export Color Conversion Data

        private void ImportCCTData()
        {
            String file = GetCCTFileOpen();
            if (file != null)
            {
                CctModel cctModel = new CctModel();
                cctModel.Guid = Guid.NewGuid().ToString();
                cctModel.IsNew = true;

                cctModel.FileName = Path.GetFileName(file);
                cctModel.Data = File.ReadAllBytes(file);

                CCTS.Insert(0, cctModel);
                SelectedCCT = cctModel;

                ColorConversionViewVM.CCT = SelectedCCT;
            }
        }

        private void ExportCCTData()
        {
            if (SelectedCCT != null)
            {
                String file = GetCCTFileSave(ActiveRML.Cct.FileName);
                if (file != null)
                {
                    using (_notification.PushTaskItem("Exporting CCT file..."))
                    {
                        try
                        {
                            IsFree = false;

                            if (SelectedCCT.IsNew)
                            {
                                File.WriteAllBytes(file, SelectedCCT.Data);
                            }
                            else
                            {
                                var cct = _active_context.Ccts.SingleOrDefault(x => x.Guid == SelectedCCT.Guid);

                                if (cct != null)
                                {
                                    File.WriteAllBytes(file, cct.Data);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Log(ex, "Error exporting CCT file.");
                            _notification.ShowError($"An error occurred while trying to export the CCT file.\n{ex.Message}");
                        }
                        finally
                        {
                            IsFree = true;
                        }
                    }
                }
            }
        }

        private String GetCCTFileOpen()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Title = "Select color adjustment file";
            dlg.Filter = "Color Conversion Table|*.cct";
            if (dlg.ShowDialogCenter())
            {
                return dlg.FileName;
            }

            return null;
        }

        private String GetCCTFileSave(String fileName)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Title = "Select color adjustment file";
            dlg.Filter = "Color Conversion Table|*.cct";
            dlg.FileName = fileName;
            dlg.DefaultExt = ".cct";
            if (dlg.ShowDialogCenter())
            {
                return dlg.FileName;
            }

            return null;
        }

        #endregion
    }
}