using MainShell.Hardware;
using MainShell.Models;
using MainShell.Recipe.Models;
using MainShell.Recipe.Models.SubstrateParameter;
using MaxwellFramework.Core.Common.Command;
using Stylet;
using System.Linq;
using System.Windows.Input;

namespace MainShell.Recipe.ViewModel
{
    public class SubstrateHeightMeasureViewModel : PropertyChangedBase
    {
        private readonly HardwareManager _hardwareManager;

        public SubstrateHeightMeasureViewModel(HardwareManager hardwareManager)
        {
            _hardwareManager = hardwareManager;
            AddPointCmd = new DelegateCommand(AddPoint);
            DeletePointCmd = new DelegateCommand(DeletePoint);
            TeachPointCmd = new DelegateCommand(TeachPoint);
            ApplyOffsetToAllCmd = new DelegateCommand(ApplyOffsetToAll);
        }

        private SubstrateRecipe _substrateRecipe;
        public SubstrateRecipe SubstrateRecipe
        {
            get { return _substrateRecipe; }
            set
            {
                if (SetAndNotify(ref _substrateRecipe, value))
                {
                    NotifyOfPropertyChange(() => HeightMeasureSetting);
                    NotifyOfPropertyChange(() => CommonOffsetCompensation);
                    NotifyOfPropertyChange(() => Points);
                    NotifyOfPropertyChange(() => Mode);
                    NotifyOfPropertyChange(() => IsTeachMode);
                    NotifyOfPropertyChange(() => IsRowColumnMode);
                }
            }
        }

        public SubstrateHeightMeasureSetting HeightMeasureSetting => SubstrateRecipe?.HeightMeasureSetting;

        public SubstrateHeightMeasureMode Mode
        {
            get { return HeightMeasureSetting == null ? SubstrateHeightMeasureMode.StandardTeachPosition : HeightMeasureSetting.Mode; }
            set
            {
                if (HeightMeasureSetting == null || HeightMeasureSetting.Mode == value)
                {
                    return;
                }

                HeightMeasureSetting.Mode = value;
                NotifyOfPropertyChange(() => Mode);
                NotifyOfPropertyChange(() => IsTeachMode);
                NotifyOfPropertyChange(() => IsRowColumnMode);
            }
        }

        public bool IsTeachMode
        {
            get { return Mode == SubstrateHeightMeasureMode.StandardTeachPosition; }
            set
            {
                if (value)
                {
                    Mode = SubstrateHeightMeasureMode.StandardTeachPosition;
                }
            }
        }

        public bool IsRowColumnMode
        {
            get { return Mode == SubstrateHeightMeasureMode.RowColumnOffset; }
            set
            {
                if (value)
                {
                    Mode = SubstrateHeightMeasureMode.RowColumnOffset;
                }
            }
        }

        public System.Collections.ObjectModel.ObservableCollection<SubstrateHeightMeasurePoint> Points => HeightMeasureSetting?.Points;
        public MPoint CommonOffsetCompensation => HeightMeasureSetting?.CommonOffsetCompensation;

        private SubstrateHeightMeasurePoint _selectedPoint;
        public SubstrateHeightMeasurePoint SelectedPoint
        {
            get { return _selectedPoint; }
            set { SetAndNotify(ref _selectedPoint, value); }
        }

        public ICommand AddPointCmd { get; }
        public ICommand DeletePointCmd { get; }
        public ICommand TeachPointCmd { get; }
        public ICommand ApplyOffsetToAllCmd { get; }

        private void ApplyOffsetToAll(object obj)
        {
            if (Points == null || CommonOffsetCompensation == null)
            {
                return;
            }

            foreach (var point in Points)
            {
                if (point.OffsetCompensation == null)
                {
                    point.OffsetCompensation = new MPoint();
                }

                point.OffsetCompensation.X = CommonOffsetCompensation.X;
                point.OffsetCompensation.Y = CommonOffsetCompensation.Y;
            }
        }

        private void AddPoint(object obj)
        {
            if (Points == null)
            {
                return;
            }

            var point = new SubstrateHeightMeasurePoint
            {
                PointName = $"Point{Points.Count + 1}",
                TeachPosition = new MPoint(),
                OffsetCompensation = new MPoint()
            };
            Points.Add(point);
            SelectedPoint = point;
        }

        private void DeletePoint(object obj)
        {
            if (Points == null || SelectedPoint == null)
            {
                return;
            }

            Points.Remove(SelectedPoint);
            SelectedPoint = Points.LastOrDefault();
        }

        private void TeachPoint(object obj)
        {
            if (SelectedPoint == null)
            {
                return;
            }

            var device = _hardwareManager.CameraAxisManager.TopCameraAxisDevices.FirstOrDefault();
            if (device == null)
            {
                return;
            }

            if (SelectedPoint.TeachPosition == null)
            {
                SelectedPoint.TeachPosition = new MPoint();
            }

            if (device.AxisX != null)
            {
                SelectedPoint.TeachPosition.X = device.AxisX.State.ActualPos;
            }

            if (device.AxisY != null)
            {
                SelectedPoint.TeachPosition.Y = device.AxisY.State.ActualPos;
            }
        }
    }
}
