/// <summary>
        /// Sets the commands, column order and event handlers.
        /// After this the VM is ready for operation
        /// </summary>
        /// <param name="column"></param>
        private void InitializeColumn(ColumnDefinitionVM column)
        {
            int nonZeroOrderColumns = ColumnDefinitions.Count(c => c.ColumnOrder > 0);

            if (column.ColumnOrder == 0)
            {
                column.ColumnOrder = nonZeroOrderColumns + 1;
            }

            column.RemoveCommand = new DelegateCommand((parameter) =>
            {
                int order = (int)parameter;

                List <ColumnDefinitionVM> higherOrder = ColumnDefinitions.Where(cd => cd.ColumnOrder > order).ToList();
                List <ColumnDefinitionVM> lowerOrder  = ColumnDefinitions.Where(cd => cd.ColumnOrder < order).ToList();

                foreach (ColumnDefinitionVM cdVM in higherOrder)
                {
                    cdVM.ColumnOrder--;
                }

                ColumnDefinitions = lowerOrder.Concat(higherOrder).ToArray();
            });

            column.MoveLeft  = MoveColumnLeft;
            column.MoveRight = MoveColumnRight;
            MoveColumnLeft.RaiseCanExecuteChanged();
            MoveColumnRight.RaiseCanExecuteChanged();
        }
        public ColumnSettingsVM(
            ILayersTemplateSource layersTemplateSource,
            ILayerRankNamesSource layerRankNameSource,
            IColumnSettingsPersistence settingsPersister)
        {
            this.layersTemplateSource  = layersTemplateSource;
            this.layerRankNameSource   = layerRankNameSource;
            this.colSettingPersistence = settingsPersister;
            ColumnDefinitions          = new ColumnDefinitionVM[0];
            ColumnDefinitionVM[] settings = null;
            if (settingsPersister.LoadDefaults(out settings))
            {
                ColumnDefinitions = settings;
                Initialize();
                foreach (var col in columnDefinitions)
                {
                    InitializeColumn(col);
                }
            }
            else
            {
                //default column set
                Initialize();
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>();
                var ranks = layerRankNameSource.InstrumentalMultipleNames.Reverse().ToArray();
                foreach (string rank in ranks)
                {
                    LayerEditColumnDefinitionVM column = new LayerEditColumnDefinitionVM(layerRankNameSource);
                    column.Selected = rank;
                    result.Add(column);
                    ColumnDefinitions = result.ToArray(); // As InitializeColumn uses ColumnDefinitions
                    InitializeColumn(column);
                }

                AddDepthCommand.Execute(null);
                AddPhotoCommand.Execute(null);
            }
        }
        protected virtual void Initialize()
        {
            AddDepthCommand = new DelegateCommand(() =>
            {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new DepthColumnDefinitionVM();
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddLayerLengthCommand = new DelegateCommand(() =>
            {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new LayerLengthColumnDefinitionVM();
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddPhotoCommand = new DelegateCommand(() =>
            {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new PhotoColumnDefinitionVM();
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddLayerPropCommand = new DelegateCommand(() =>
            {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new LayeredTextColumnDefinitionVM(layersTemplateSource);
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddLayerBoundsCommand = new DelegateCommand(() => {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new LayerEditColumnDefinitionVM(layerRankNameSource);
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddLayerSamplesCommand = new DelegateCommand(() => {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new LayerSamplesDefinitionVM();
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddVisualCommand = new DelegateCommand(() => {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new VisualColumnDefinitionVM(layersTemplateSource);
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            AddIconsCommand = new DelegateCommand(() => {
                List <ColumnDefinitionVM> result = new List <ColumnDefinitionVM>(ColumnDefinitions);
                ColumnDefinitionVM column        = new IconsColumnDefinitionVM(layersTemplateSource);
                InitializeColumn(column);
                result.Add(column);
                ColumnDefinitions = result.ToArray();
            });

            MoveColumnLeft = new DelegateCommand((parameter) =>
            {
                int order = (int)parameter;

                ColumnDefinitionVM target = ColumnDefinitions.Where(cd => cd.ColumnOrder == order).Single();
                ColumnDefinitionVM toSwap = ColumnDefinitions.Where(cd => cd.ColumnOrder == order - 1).Single();
                target.ColumnOrder        = order - 1;
                toSwap.ColumnOrder        = order;
                RaisePropertyChanged(nameof(ColumnDefinitions));
                RaisePropertyChanged(nameof(OrderedColumnDefinitions));
                MoveColumnLeft.RaiseCanExecuteChanged();
                MoveColumnRight.RaiseCanExecuteChanged();
            }, (parameter) =>
            {
                if (parameter != null)
                {
                    int order = (int)parameter;
                    if (order > 1)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            });

            MoveColumnRight = new DelegateCommand((parameter) =>
            {
                int order = (int)parameter;

                ColumnDefinitionVM target = ColumnDefinitions.Where(cd => cd.ColumnOrder == order).Single();
                ColumnDefinitionVM toSwap = ColumnDefinitions.Where(cd => cd.ColumnOrder == order + 1).Single();
                target.ColumnOrder        = order + 1;
                toSwap.ColumnOrder        = order;
                RaisePropertyChanged(nameof(ColumnDefinitions));
                RaisePropertyChanged(nameof(OrderedColumnDefinitions));
                MoveColumnLeft.RaiseCanExecuteChanged();
                MoveColumnRight.RaiseCanExecuteChanged();
            }, (parameter) =>
            {
                if (parameter != null)
                {
                    int order = (int)parameter;
                    if (order < ColumnDefinitions.Length)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            });
            ImportFromFileCommnad = new DelegateCommand(() =>
            {
                ColumnDefinitionVM[] settings;
                if (colSettingPersistence.Load(out settings))
                {
                    ColumnDefinitions = settings;
                    foreach (var col in ColumnDefinitions)
                    {
                        InitializeColumn(col);
                    }
                }
            });
            ExportToFileCommand = new DelegateCommand(() => {
                colSettingPersistence.Persist(OrderedColumnDefinitions);
            });
        }