using MainShell.Models;
using MainShell.ParaSetting.Model;
using MaxwellFramework.Core.Interfaces;
using MwFramework.ManagerService;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using StyletIoC;

namespace MainShell.ParaSetting.ViewModel
{
    public class ProcessParameterSettingViewModel : BaseScreen
    {
        private readonly IParamList _paramList;
        private ObservableCollection<MenuItemWrap> _processMenuItemWraps;
        private MenuItemWrap _selectedProcessMenuItem;
        private object _currentScreen;

        private ProductLoadProcessParameterViewModel _productLoadProcessParameterViewModel;
        [Inject]
        public ProductLoadProcessParameterViewModel ProductLoadProcessParameterViewModel
        {
            get { return _productLoadProcessParameterViewModel; }
            set { _productLoadProcessParameterViewModel = value; }
        }

        private ProductUnloadProcessParameterViewModel _productUnloadProcessParameterViewModel;
        [Inject]
        public ProductUnloadProcessParameterViewModel ProductUnloadProcessParameterViewModel
        {
            get { return _productUnloadProcessParameterViewModel; }
            set { _productUnloadProcessParameterViewModel = value; }
        }

        private ProductPositionProcessParameterViewModel _productPositionProcessParameterViewModel;
        [Inject]
        public ProductPositionProcessParameterViewModel ProductPositionProcessParameterViewModel
        {
            get { return _productPositionProcessParameterViewModel; }
            set { _productPositionProcessParameterViewModel = value; }
        }

        private ProductHeightMeasureProcessParameterViewModel _productHeightMeasureProcessParameterViewModel;
        [Inject]
        public ProductHeightMeasureProcessParameterViewModel ProductHeightMeasureProcessParameterViewModel
        {
            get { return _productHeightMeasureProcessParameterViewModel; }
            set { _productHeightMeasureProcessParameterViewModel = value; }
        }

        private WaferLoadProcessParameterViewModel _waferLoadProcessParameterViewModel;
        [Inject]
        public WaferLoadProcessParameterViewModel WaferLoadProcessParameterViewModel
        {
            get { return _waferLoadProcessParameterViewModel; }
            set { _waferLoadProcessParameterViewModel = value; }
        }

        private WaferUnloadProcessParameterViewModel _waferUnloadProcessParameterViewModel;
        [Inject]
        public WaferUnloadProcessParameterViewModel WaferUnloadProcessParameterViewModel
        {
            get { return _waferUnloadProcessParameterViewModel; }
            set { _waferUnloadProcessParameterViewModel = value; }
        }

        private WaferStraightenProcessParameterViewModel _waferStraightenProcessParameterViewModel;
        [Inject]
        public WaferStraightenProcessParameterViewModel WaferStraightenProcessParameterViewModel
        {
            get { return _waferStraightenProcessParameterViewModel; }
            set { _waferStraightenProcessParameterViewModel = value; }
        }

        private DieRecognizeProcessParameterViewModel _dieRecognizeProcessParameterViewModel;
        [Inject]
        public DieRecognizeProcessParameterViewModel DieRecognizeProcessParameterViewModel
        {
            get { return _dieRecognizeProcessParameterViewModel; }
            set { _dieRecognizeProcessParameterViewModel = value; }
        }

        private BondingProcessParameterViewModel _bondingProcessParameterViewModel;
        [Inject]
        public BondingProcessParameterViewModel BondingProcessParameterViewModel
        {
            get { return _bondingProcessParameterViewModel; }
            set { _bondingProcessParameterViewModel = value; }
        }

        private RecheckProcessParameterViewModel _recheckProcessParameterViewModel;
        [Inject]
        public RecheckProcessParameterViewModel RecheckProcessParameterViewModel
        {
            get { return _recheckProcessParameterViewModel; }
            set { _recheckProcessParameterViewModel = value; }
        }

        private RunSetting _runSetting;

        public RunSetting RunSetting
        {
            get { return _runSetting; }
            set
            {
                _runSetting = value;
                OnPropertyChanged(nameof(RunSetting));
            }
        }

        public ObservableCollection<MenuItemWrap> ProcessMenuItemWraps
        {
            get { return _processMenuItemWraps; }
            private set
            {
                _processMenuItemWraps = value;
                OnPropertyChanged(nameof(ProcessMenuItemWraps));
            }
        }

        public MenuItemWrap SelectedProcessMenuItem
        {
            get { return _selectedProcessMenuItem; }
            set
            {
                _selectedProcessMenuItem = value;
                CurrentScreen = value != null ? value.Tag : null;
                OnPropertyChanged(nameof(SelectedProcessMenuItem));
                OnPropertyChanged(nameof(CurrentProcessHeader));
            }
        }

        public object CurrentScreen
        {
            get { return _currentScreen; }
            private set
            {
                _currentScreen = value;
                OnPropertyChanged(nameof(CurrentScreen));
            }
        }

        public string CurrentProcessHeader
        {
            get { return SelectedProcessMenuItem != null ? SelectedProcessMenuItem.Header : string.Empty; }
        }

        public ProcessParameterSettingViewModel(IParameterManager parameterManager)
        {
            _paramList = parameterManager as IParamList;
            if (_paramList == null)
            {
                throw new ArgumentNullException(nameof(parameterManager));
            }

            ProcessMenuItemWraps = new ObservableCollection<MenuItemWrap>();
        }

        protected override void OnViewLoaded()
        {
            base.OnViewLoaded();
            RunSetting = _paramList.GetParameter<RunSetting>();
            BindSectionParameters();
            InitializeProcessMenuItems();
        }

        private void BindSectionParameters()
        {
            if (RunSetting == null)
            {
                return;
            }

            ProductLoadProcessParameterViewModel.SetParameter(RunSetting.ProductLoadProcessParameter);
            ProductUnloadProcessParameterViewModel.SetParameter(RunSetting.ProductUnloadProcessParameter);
            ProductPositionProcessParameterViewModel.SetParameter(RunSetting.ProductPositionProcessParameter);
            ProductHeightMeasureProcessParameterViewModel.SetParameter(RunSetting.ProductHeightMeasureProcessParameter);
            WaferLoadProcessParameterViewModel.SetParameter(RunSetting.WaferLoadProcessParameter);
            WaferUnloadProcessParameterViewModel.SetParameter(RunSetting.WaferUnloadProcessParameter);
            WaferStraightenProcessParameterViewModel.SetParameter(RunSetting.WaferStraightenProcessParameter);
            DieRecognizeProcessParameterViewModel.SetParameter(RunSetting.DieRecognizeProcessParameter);
            BondingProcessParameterViewModel.SetParameter(RunSetting.BondingProcessParameter);
            RecheckProcessParameterViewModel.SetParameter(RunSetting.RecheckProcessParameter);

            RunSetting.WaferStraightenProcessParameter.PropertyChanged -= OnWaferStraightenProcessParameterChanged;
            RunSetting.WaferStraightenProcessParameter.PropertyChanged += OnWaferStraightenProcessParameterChanged;
        }

        private void InitializeProcessMenuItems()
        {
            ProcessMenuItemWraps.Clear();
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabProductLoad", ProductLoadProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabProductUnload", ProductUnloadProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabProductPosition", ProductPositionProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabProductHeightMeasure", ProductHeightMeasureProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabWaferLoad", WaferLoadProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabWaferUnload", WaferUnloadProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabWaferStraighten", WaferStraightenProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabDieRecognize", DieRecognizeProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabBonding", BondingProcessParameterViewModel));
            ProcessMenuItemWraps.Add(CreateProcessMenuItem("ProcessTabRecheck", RecheckProcessParameterViewModel));

            if (ProcessMenuItemWraps.Count > 0)
            {
                SelectedProcessMenuItem = ProcessMenuItemWraps[0];
            }
        }

        private MenuItemWrap CreateProcessMenuItem(string resourceKey, object screen)
        {
            MenuItemWrap menuItemWrap = new MenuItemWrap();
            menuItemWrap.Header = ResolveResourceText(resourceKey);
            menuItemWrap.Tag = screen;
            return menuItemWrap;
        }

        private string ResolveResourceText(string resourceKey)
        {
            if (Application.Current == null)
            {
                return resourceKey;
            }

            object resource = Application.Current.TryFindResource(resourceKey);
            string text = resource as string;
            if (string.IsNullOrWhiteSpace(text))
            {
                return resourceKey;
            }

            return text;
        }

        private void OnWaferStraightenProcessParameterChanged(object sender, PropertyChangedEventArgs e)
        {
            if (RunSetting == null)
            {
                return;
            }

            if (e.PropertyName == nameof(WaferStraightenProcessParameter.UseSingleStraighten))
            {
                bool useSingleStraighten = RunSetting.WaferStraightenProcessParameter.UseSingleStraighten;
                if (RunSetting.DieRecognizeProcessParameter.UseSingleWaferPosition != useSingleStraighten)
                {
                    RunSetting.DieRecognizeProcessParameter.UseSingleWaferPosition = useSingleStraighten;
                }
            }
        }

        public void BtnSave()
        {
            if (RunSetting != null)
            {
                RunSetting.Write();
            }
        }
    }
}