aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Automation
ModeNameSize
-rw-r--r--Developer.cs1067logstatsplain
-rw-r--r--UI.cs282logstatsplain
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Core.Threading;
using Tango.SharedUI;
using System.Windows;
using System.Windows.Media;
using System.Collections.Specialized;
using System.Reflection;
using Tango.BL.Enumerations;
using System.Diagnostics;
using Tango.Core.Commands;
using Tango.PPC.Jobs.UndoRedoCommands;
using Newtonsoft.Json;

namespace Tango.PPC.Jobs.Models
{
    public class SegmentModel : ExtendedObject, ISegmentModel
    {
        private double _lastLength;
        private LinearGradientBrush _brush;
        private ActionTimer _brushStopCollectionChangedActionTimer;

        #region Properties

        public string GUID { get; set; }
        
        protected String _name;
        /// <summary>
        /// Gets or sets the SegmentModel name.
        /// </summary>
        public String Name
        {
            get
            {
                return _name;
            }

            set
            {
                if (_name != value)
                {
                    _name = value;
                    RaisePropertyChangedAuto();
                }
            }
        }
        protected double _length;
        /// <summary>
        /// Gets or sets the length.
        /// </summary>
        public double Length
        {
            get
            {
                return _length;
            }
            set
            {
                if (_length != value)
                {
                    _length = value;
                    OnLengthChanged(value);
                    RaisePropertyChangedAuto();
                }
            }
        }

        public bool IsGroupSegment
        {
            get
            {
                return SegmentsGroupModel != null;
            }
        }
        
        public void LengthBeforeChange(double value)
        {
            _lastLength = Length;
        }

        public void LengthChanged(double value)
        {
            UndoRedoManager.Instance.InsertAndExecuteCommand(new ChangeLengthCommand(this, _lastLength, value));
            _lastLength = Length;
        }
        
        protected Int32 _segmentindex;
        /// <summary>
        /// Gets or sets the index of the segment.
        /// </summary>
        public Int32 SegmentIndex
        {
            get
            {
                return _segmentindex;
            }
            set
            {
                if (_segmentindex != value)
                {
                    _segmentindex = value;
                    RaisePropertyChangedAuto();
                }
            }
        }
        private bool _isInterSegment;
        /// <summary>
        /// Gets or sets a value indicating whether this segment is an inter segment.
        /// </summary>
        public bool IsInterSegment
        {
            get { return _isInterSegment; }
            set { _isInterSegment = value;
                RaisePropertyChangedAuto(); }
        }

        protected Boolean _enableintersegment;
        public Boolean EnableInterSegment
        {
            get { return _enableintersegment; }
            set
            {
                if (_enableintersegment != value)
                {
                    _enableintersegment = value;
                    RaisePropertyChangedAuto();
                    
                }
                RaisePropertyChanged(nameof(LengthWithInterSegment));
                RaisePropertyChanged(nameof(InterSegmentLength));
                RaisePropertyChanged(nameof(ShowGap));
            }
        }

        [JsonIgnore]
        public bool ShowGap
        {
            get
            {
                return EnableInterSegment && !IsLast;
            }
        }

        public double LengthWithInterSegment
        {
            get
            {
                if (Job != null && !IsInterSegment)
                {
                    // var length = Length;// + Length * (Job.LengthPercentageFactor / 100);
                    return EnableInterSegment ? (Length + Job.InterSegmentLength) : Length;
                }
                return Length;
                // return Job != null && !IsInterSegment ? (Length + Length * (Job.LengthPercentageFactor / 100)) : Length; 
            }
        }

        public double InterSegmentLength
        {
            get { return Job == null ? 0 : Job.InterSegmentLength; }
        }

        public double LengthWithFactor
        {
            get { return Job != null && !IsInterSegment ? (Length + Length * (Job.LengthPercentageFactor / 100)) : Length; }
        }

        protected SynchronizedObservableCollection<BrushStopModel> _brushstops;

        /// <summary>
        /// Gets or sets the segmentbase brush stops.
        /// </summary>

        public  SynchronizedObservableCollection<BrushStopModel> BrushStops
        {
            get
            {
                return _brushstops;
            }

            set
            {
                if (_brushstops != value)
                {
                    _brushstops = value;
                    OnBrushStopsChanged(_brushstops);
                    RaisePropertyChangedAuto();
                }
            }
        }

        private JobModel _job;
        [JsonIgnore]
        public JobModel Job
        {
            get
            {
                return _job;
            }

            set
            {
                if (_job != value)
                {
                    _job = value;
                }
            }
        }

        [JsonIgnore]
        public Brush SegmentBrush
        {
            get
            {
                return GetSegmentBrush();
            }
        }

        [JsonIgnore]
        public bool IsOffsetChanged { get; set; }
        
        public double LeftOffset
        {
            get { return FirstBrushStop != null? FirstBrushStop.OffsetPercent : 0; }
            set {
                if (FirstBrushStop != null && FirstBrushStop.OffsetPercent != value)
                {
                    FirstBrushStop.OffsetPercent = value;
                    RaisePropertyChangedAuto();
                    IsOffsetChanged = true;
                    RaisePropertyChanged(nameof(SegmentBrush));
                    RaisePropertyChanged(nameof(LeftOffsetLabel));
                    IsOffsetChanged = false;
                }
            }
        }

        private double _leftOffsetChangeComleted;

        [JsonIgnore]
        public double LeftOffsetChangeComleted
        {
            get { return _leftOffsetChangeComleted; }
            set {
                if(_leftOffsetChangeComleted != value)
                {
                    _leftOffsetChangeComleted = value;
                    RaisePropertyChangedAuto();
                    UndoRedoManager.Instance.InsertAndExecuteCommand(new ChangeOffsetCommand(this, LeftOffsetStartChanging, _leftOffsetChangeComleted, OffsetType.Left));
                    
                }
            }
        }

        private double _leftOffsetStartChanging;

        [JsonIgnore]
        public double LeftOffsetStartChanging
        {
            get { return _leftOffsetStartChanging; }
            set
            {
                _leftOffsetStartChanging = value;
                RaisePropertyChangedAuto();
            }
        }

        public double MiddleOffset
        {
            get { return (MiddleBrushStop != null) ? MiddleBrushStop.OffsetPercent : 50; }
            set { 
                
                if (MiddleBrushStop != null && MiddleBrushStop.OffsetPercent != value)
                {
                    MiddleBrushStop.OffsetPercent = value;
                   RaisePropertyChangedAuto();
                    IsOffsetChanged = true;
                    RaisePropertyChanged(nameof(SegmentBrush));
                    RaisePropertyChanged(nameof(MiddleOffsetLabel));
                    IsOffsetChanged = false;
                }
            }
        }

        private double _middleOffsetChangeComleted;

        [JsonIgnore]
        public double MiddleOffsetChangeComleted
        {
            get { return _middleOffsetChangeComleted; }
            set
            {
                if (_middleOffsetChangeComleted != value)
                {
                    _middleOffsetChangeComleted = value;
                    RaisePropertyChangedAuto();
                    UndoRedoManager.Instance.InsertAndExecuteCommand(new ChangeOffsetCommand(this, MiddleOffsetStartChanging, _middleOffsetChangeComleted, OffsetType.Middle));
                   
                }
            }
        }

        private double _middleOffsetStartChanging;

        [JsonIgnore]
        public double MiddleOffsetStartChanging
        {
            get { return _middleOffsetStartChanging; }
            set
            {
                _middleOffsetStartChanging = value;
                RaisePropertyChangedAuto();
            }
        }

        public double RightOffset
        {
            get { return SecondBrushStop != null ? SecondBrushStop.OffsetPercent: 100; }
            set { 
                
                if (SecondBrushStop != null && SecondBrushStop.OffsetPercent != value)
                {
                    SecondBrushStop.OffsetPercent = value;
                    RaisePropertyChangedAuto();
                    IsOffsetChanged = true;
                    RaisePropertyChanged(nameof(SegmentBrush));
                    RaisePropertyChanged(nameof(RightOffsetLabel));
                    IsOffsetChanged = false;
                }
            }
        }

        private double _rightOffsetChangeComleted;
        [JsonIgnore]
        public double RightOffsetChangeComleted
        {
            get { return _rightOffsetChangeComleted; }
            set
            {
                if (_rightOffsetChangeComleted != value)
                {
                    _rightOffsetChangeComleted = value;
                    RaisePropertyChangedAuto();
                    UndoRedoManager.Instance.InsertAndExecuteCommand(new ChangeOffsetCommand(this, RightOffsetStartChanging, _rightOffsetChangeComleted, OffsetType.Right));
                    
                }
            }
        }

        private double _rightOffsetStartChanging;
        [JsonIgnore]
        public double RightOffsetStartChanging
        {
            get { return _rightOffsetStartChanging; }
            set
            {
                _rightOffsetStartChanging = value;
                RaisePropertyChangedAuto();
            }
        }

        [JsonIgnore]
        public String LeftOffsetLabel
        {
            get
            {
                double length = Math.Round( LeftOffset * Length / 100, 1);
                return String.Format($"{Math.Round(LeftOffset,0)}%({length}m)" );
            }
        }

        [JsonIgnore]
        public String RightOffsetLabel
        {
            get
            {
                double length = Math.Round((100-RightOffset) * Length / 100, 1);
                return String.Format($"{Math.Round(RightOffset, 0)}%({length}m)");
            }
        }

        [JsonIgnore]
        public String MiddleOffsetLabel
        {
            get
            {
                double offset = Math.Abs(MiddleOffset - 50);
                double length = Math.Round(offset * Length / 100, 1);
                double roundValue = Math.Round(MiddleOffset, 0);
                return String.Format($"{Math.Round(MiddleOffset, 0)}%({length}m)");
            }
        }

        [JsonIgnore]
        public bool HasColors
        {
            get
            {
                return BrushStops.Count > 0;
            }
        }

        [JsonIgnore]
        public bool IsGradient
        {
            get
            {
                return BrushStops.Count > 1;
            }
        }

        /// <summary>
        /// Gets the second brush stop.
        /// </summary>
        [JsonIgnore]
        public BrushStopModel SecondBrushStop
        {
            get
            {
                if (BrushStops.Count > 1)
                    return BrushStops.Where(x => x.Position == BrushStopModel.PositionStatus.SecondColor).FirstOrDefault();

                return null;
            }
        }

        /// <summary>
        /// Gets the first brush stop.
        /// </summary>
        [JsonIgnore]
        public BrushStopModel FirstBrushStop
        {
            get
            {
                if(BrushStops.Count > 0)
                {
                    var brushStop = BrushStops.Where(x => x.Position == BrushStopModel.PositionStatus.FirstColor).FirstOrDefault();
                    return brushStop;
                }
                
                return null;
            }

        }

        /// <summary>
        /// Gets the middle brush stop.
        /// </summary>
        [JsonIgnore]
        public BrushStopModel MiddleBrushStop
        {
            get
            {
                if (BrushStops.Count > 1)
                    return BrushStops.Where(x => x.Position == BrushStopModel.PositionStatus.Middle).FirstOrDefault();

                return null;
            }
        }

        [JsonIgnore]
        public bool HasOutOfGamutBrush
        {
            get
            {
                bool hasError = (FirstBrushStop != null && FirstBrushStop.IsOutOfGamut)
                    || (SecondBrushStop != null && SecondBrushStop.IsOutOfGamut);
                
                return hasError;
            }
        }

        private bool _isSelected;
        [JsonIgnore]
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value;
                RaisePropertyChangedAuto();
            }
        }

        private bool _isLast;
        [JsonIgnore]
        public bool IsLast
        {
            get { return _isLast; }
            set
            {
                if (_isLast != value)
                {
                    _isLast = value;
                    RaisePropertyChangedAuto();
                    RaisePropertyChanged(nameof(ShowGap));
                }
            }
        }

        public SegmentsGroupModel SegmentsGroupModel { get; set; }

        #endregion

        #region command
        [JsonIgnore]
        public RelayCommand AddGapCommand { get; set; }
        [JsonIgnore]
        public RelayCommand DeleteGapCommand { get; set; }
        #endregion

        #region construction

        public SegmentModel(JobModel jobModel, string guid)
        {
            InitnewSegment();
            Job = jobModel;
            GUID = guid;
            IsLast = false;
            EnableInterSegment = jobModel.EnableInterSegment;
        }

        public SegmentModel()
        {
            GUID = "";
            InitnewSegment();
        }

        #endregion

        public void InitnewSegment()
        {
            BrushStops = new SynchronizedObservableCollection<BrushStopModel>();
            LeftOffset = 0;
            MiddleOffset = 50;
            RightOffset = 100;
            IsOffsetChanged = false;
            Length = 5;
            _lastLength = 5;
            IsSelected = false;
            IsLast = false;
            _enableintersegment = false;
            AddGapCommand = new RelayCommand(x => AddGap());
            DeleteGapCommand = new RelayCommand(x => DeleteGap());
        }

        #region Public Methods

        /// <summary>
        /// Gets the segment brush.
        /// </summary>
        /// <returns></returns>
        public LinearGradientBrush GetSegmentBrush()
        {
            if (_brush == null || _brush.GradientStops.Count != BrushStops.Count || IsOffsetChanged)
            {
                GradientStopCollection stops = new GradientStopCollection();
                foreach (var stop in BrushStops.ToList().OrderBy(x => x.StopIndex).ToList())
                {
                    //TODO test if displayed is valid stop.IsValid
                   
                    Color color = stop.BestMatchColor;
                     stops.Add(new GradientStop( color, stop.OffsetPercent / 100d));
                }

                LinearGradientBrush brush = new LinearGradientBrush();
                brush.StartPoint = new Point(0, 0);
                brush.EndPoint = new Point(1, 0);

                brush.GradientStops = stops;

                _brush = brush;
                return brush;
            }
            else
            {
                for (int i = 0; i < BrushStops.Count; i++)
                {
                    //TODO test if displayed is valid stop.IsValid
                    Color color = BrushStops[i].BestMatchColor;
                    _brush.GradientStops[i].Color =  color;
                    _brush.GradientStops[i].Offset = BrushStops[i].OffsetPercent / 100d;
                }

                return _brush;
            }
        }

        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns></returns>
        public SegmentModel Clone()
        {
            var cloned = new SegmentModel(Job, GUID);//(SegmentModel)Activator.CreateInstance(typeof(SegmentModel), this.Job);

            cloned.Name = Name;
            cloned.LeftOffset = LeftOffset;
            cloned.MiddleOffset = MiddleOffset;
            cloned.RightOffset = RightOffset;
            cloned.IsOffsetChanged = IsOffsetChanged;
            cloned.Length = Length;
            cloned.IsSelected = false;
            cloned.IsInterSegment = IsInterSegment;
            cloned.EnableInterSegment = EnableInterSegment;
            cloned.BrushStops = BrushStops.Select(x => x.Clone()).ToSynchronizedObservableCollection();
            cloned.BrushStops.ToList().ForEach(x => x.SegmentModel = cloned);
            
            cloned.SegmentIndex = SegmentIndex + 1;
            cloned.SegmentsGroupModel = SegmentsGroupModel;
            return cloned;
        }

        ISegmentModel ISegmentModel.Clone()
        {
            return Clone() as ISegmentModel;
        }

        public static SegmentModel CreateInterSegment(double length)
        {
            return new SegmentModel()
            {
                IsInterSegment = true,
                Length = length,
                Name = "Inter Segment",
                BrushStops = new SynchronizedObservableCollection<BrushStopModel>()
                            
            };
        }
        /// <summary>
        /// Creates the gradient brushes.
        /// </summary>
        public void CreateGradientBrushes(BrushStopModel firstBrush, BrushStopModel secondBrush)
        {
            BrushStops.Clear();
            BrushStopModel brushStop = firstBrush.Clone();
            brushStop.StopIndex = 1;
            brushStop.OffsetPercent = 0;
            brushStop.Position = BrushStopModel.PositionStatus.First;
            brushStop.IsOutOfGamut = false;
            BrushStops.Add(brushStop);

            BrushStopModel colorbrushStop = firstBrush;
            colorbrushStop.Position = BrushStopModel.PositionStatus.FirstColor;
            colorbrushStop.StopIndex = 2;
            colorbrushStop.OffsetPercent = 0;
            BrushStops.Add(colorbrushStop);
            
            BrushStopModel middleBrushStop = firstBrush.Clone();
            middleBrushStop.StopIndex = 3;
            middleBrushStop.Position = BrushStopModel.PositionStatus.Middle;
            middleBrushStop.OffsetPercent = 50;
            middleBrushStop.IsOutOfGamut = false;
            middleBrushStop.Color = BrushStopModel.GetRelativeRGB(firstBrush.Color, secondBrush.Color, 0, 1, 0.5);
            middleBrushStop.BestMatchColor = BrushStopModel.GetRelativeRGB(firstBrush.BestMatchColor, secondBrush.BestMatchColor, 0, 1, 0.5);
            BrushStops.Add(middleBrushStop);

            AddOrReplaceSecondBrush(secondBrush);
        }

        public void AddOrReplaceSecondBrush(BrushStopModel secondBrush)
        {
            RemoveSecondColorOfGradient();

            BrushStopModel secondbrushStop = secondBrush;
            secondbrushStop.StopIndex = 4;
            secondbrushStop.Position = BrushStopModel.PositionStatus.SecondColor;
            secondbrushStop.OffsetPercent = 100;
            BrushStops.Add(secondbrushStop);

            BrushStopModel lastSecondBrushStop = secondBrush.Clone();
            lastSecondBrushStop.StopIndex = 5;
            lastSecondBrushStop.OffsetPercent = 100;
            lastSecondBrushStop.IsOutOfGamut = false;
            lastSecondBrushStop.Position = BrushStopModel.PositionStatus.Last; ;
            BrushStops.Add(lastSecondBrushStop);
        }

        public void SetNewColor(BrushStopModel target, BrushStopModel source )
        {
            target.SetNewColor(source);
            target.IsOutOfGamut = source.IsOutOfGamut;
            if (target.Position == BrushStopModel.PositionStatus.FirstColor)
            {
                BrushStopModel first = BrushStops.Where(x => x.Position == BrushStopModel.PositionStatus.First).FirstOrDefault();
                if(first != null)
                {
                    first.SetNewColor(source);
                    first.IsOutOfGamut = source.IsOutOfGamut;
                } 
            }
            else if(target.Position == BrushStopModel.PositionStatus.SecondColor)
            {
                BrushStopModel last = BrushStops.Where(x => x.Position == BrushStopModel.PositionStatus.Last).FirstOrDefault();
                if(last != null)
                {
                    last.SetNewColor(source);
                    last.IsOutOfGamut = source.IsOutOfGamut;
                }
            }
            UpdateMiddleColorBrush();
            RaiseSegmentBrushChanged();
        }
        
        public void UpdateMiddleColorBrush()
        {
            if (MiddleBrushStop != null && SecondBrushStop != null && FirstBrushStop != null)
            {
                MiddleBrushStop.Color = BrushStopModel.GetRelativeRGB(FirstBrushStop.Color, SecondBrushStop.Color, 0, 1, 0.5);
                MiddleBrushStop.BestMatchColor = BrushStopModel.GetRelativeRGB(FirstBrushStop.BestMatchColor, SecondBrushStop.BestMatchColor, 0, 1, 0.5);
            }
        }
        
        public void RemoveSecondColorOfGradient()
        {
            if (BrushStops.Count < 5)
                return ;
           BrushStops.RemoveAt(4);
           BrushStops.RemoveAt(3);
        }

        public void ArrangeBrushStopsIndexes()
        {
            for (int i = 0; i < BrushStops.Count; i++)
            {
                BrushStops[i].StopIndex = i + 1;
            }
            ArrangeBrushStopsPosition();
        }

        public void ArrangeBrushStopsPosition()
        {
            if (BrushStops.Count == 1)
            {
                BrushStops.FirstOrDefault().Position = BrushStopModel.PositionStatus.FirstColor;
            }
            else if (BrushStops.Count > 1)
                BrushStops.ToList().ForEach(x => x.Position = (BrushStopModel.PositionStatus)x.StopIndex);
        }
        
        public void SwapBrushStops()
        {
            if (BrushStops.Count > 1)
            {
                int index = 0;
                int lastIndex = BrushStops.Count - 1;
                for (; index < lastIndex; index++, lastIndex--)
                {
                    var left_temp = BrushStops[index];
                    var right_stopIndex = BrushStops[lastIndex].StopIndex;
                    var right_offsetPercent = BrushStops[lastIndex].OffsetPercent;
                    
                    BrushStops[index] = BrushStops[lastIndex];
                    BrushStops[index].StopIndex = left_temp.StopIndex;
                    BrushStops[index].OffsetPercent = left_temp.OffsetPercent;
                    BrushStops[lastIndex] = left_temp;
                    BrushStops[lastIndex].StopIndex = right_stopIndex;
                    BrushStops[lastIndex].OffsetPercent = right_offsetPercent;
                }
                ArrangeBrushStopsIndexes();
                UpdateMiddleColorBrush();
            }
        }

        #endregion

        #region Brush Stops Collection Changed

        private void BrushStops_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (_brushStopCollectionChangedActionTimer == null)
            {
                _brushStopCollectionChangedActionTimer = new ActionTimer(TimeSpan.FromMilliseconds(100));
            }

            _brushStopCollectionChangedActionTimer.ResetReplace(() =>
            {
                foreach (var stop in BrushStops.ToList())
                {
                    stop.RaiseOffsetChanged();
                }
                RaiseSegmentBrushChanged();
            });
        }

        /// <summary>
        /// Raises the <see cref="SegmentBrush"/> property changed event.
        /// </summary>
        public void RaiseSegmentBrushChanged()
        {
            RaisePropertyChanged(nameof(SegmentBrush));
            RaisePropertyChanged(nameof(HasColors));
            RaisePropertyChanged(nameof(IsGradient));
            RaisePropertyChanged(nameof(FirstBrushStop));
            RaisePropertyChanged(nameof(SecondBrushStop));
            RaisePropertyChanged(nameof(HasOutOfGamutBrush));
            RaisePropertyChanged(nameof(Length));
        }
        #endregion

        #region Properties Changed

        /// <summary>
        /// Called when the Length has changed.
        /// </summary>
        /// <param name="length"></param>
        protected void OnLengthChanged(double length)
        {
            //if (_lastLength != length)
            {
                BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
                //_lastLength = Length;
                //RaisePropertyChanged(nameof(LengthWithFactor));
                RaisePropertyChanged(nameof(LengthWithInterSegment));
                RaisePropertyChanged(nameof(LeftOffsetLabel));
                RaisePropertyChanged(nameof(MiddleOffsetLabel));
                RaisePropertyChanged(nameof(RightOffsetLabel));
            }
        }

        /// <summary>
        /// Called when the BrushStops has changed.
        /// </summary>
        /// <param name="brushstops"></param>
        protected void OnBrushStopsChanged(SynchronizedObservableCollection<BrushStopModel> brushstops)
        {
            if (brushstops != null)
            {
                brushstops.CollectionChanged -= BrushStops_CollectionChanged;
                brushstops.CollectionChanged += BrushStops_CollectionChanged;

                foreach (var stop in brushstops.ToList())
                {
                    stop.RaiseOffsetChanged();
                }

                RaiseSegmentBrushChanged();
            }
        }

        private void AddGap()
        {
            EnableInterSegment = true;
        }

        private void DeleteGap()
        {
            EnableInterSegment = false;
        }

        public void UpdateBrushStops()
        {
            foreach (var stop in BrushStops.Where(x => x.ColorSpace == BL.Enumerations.ColorSpaces.RGB || x.ColorSpace == BL.Enumerations.ColorSpaces.LAB).ToList())
            {
                try
                {
                    stop.OnBrushStopFieldValueChanged();
                    stop.InitColorsFromBestmatch();
                    //TODO ASK ROY!!!!!!
                    //output.ApplyOnBrushStopVolumesOnly(stop);
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, $"Error updating stop volumes after changing thread on segment {stop.SegmentModel.SegmentIndex}, stop {stop.StopIndex}.");
                }
            }
        }
        
        #endregion
    }
}