using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MeterVision.Config
{
    public class ConfigItem2 : INotifyPropertyChanged
    {
        //全数字水表的List
        public static List<KeyValuePair<RulerDigitTypeEnum, string>> RulerDigitList = 
            new List<KeyValuePair<RulerDigitTypeEnum, string>>()
            {
                new KeyValuePair<RulerDigitTypeEnum, string>(RulerDigitTypeEnum.MatchAllDigit,
                    "匹配所有数字")
                //new KeyValuePair<RulerDigitTypeEnum, string>(RulerDigitTypeEnum.MatchAllDigitButLast,
                //    "匹配所有数字,最后一位半字误差不大于1")
            };

        public static List<KeyValuePair<RulerDigitPointerTypeEnum, string>> RulerDigitPointerList =
            new List<KeyValuePair<RulerDigitPointerTypeEnum, string>>()
            {
                new KeyValuePair<RulerDigitPointerTypeEnum, string>(RulerDigitPointerTypeEnum.MatchAllDigitPointer,
                    "匹配所有数字+所有指针"),
                new KeyValuePair<RulerDigitPointerTypeEnum, string>(RulerDigitPointerTypeEnum.MatchAllDigit,
                    "匹配所有数字"),
                //new KeyValuePair<RulerDigitPointerTypeEnum, string>(RulerDigitPointerTypeEnum.MatchAllDigitButLast,
                //    "匹配所有数字")
            };

        public static List<KeyValuePair<RulerPointerTypeEnum, string>> RulerPointerList =
            new List<KeyValuePair<RulerPointerTypeEnum, string>>()
            {
                new KeyValuePair<RulerPointerTypeEnum, string>(RulerPointerTypeEnum.MatchAllPointer,
                    "匹配所有指针"),
                new KeyValuePair<RulerPointerTypeEnum, string>(RulerPointerTypeEnum.MatchAllIntegerPointer,
                    "匹配整数指针")
            };

        public static bool IsValueInRulerDigitRange(int inputValue)
        {
            return RulerDigitList.Exists(item => (int)item.Key == inputValue);
        }

        public static bool IsValueInRulerDigitPointerRange(int inputValue)
        {
            return RulerDigitPointerList.Exists(item => (int)item.Key == inputValue);
        }

        public static bool IsValueInRulerPointerRange(int inputValue)
        {
            return RulerPointerList.Exists(item => (int)item.Key == inputValue);
        }

    
        public event EventHandler<PageSizeChangedEventArgs> OnStandPageSizeChanged;
        public event EventHandler<PageSizeChangedEventArgs> OnSinglePageSizeChanged;
        public event EventHandler<PageSizeChangedEventArgs> OnPatchPageSizeChanged;

        public event Action<int> OnStandCatalogPageSizeChanged;
        public event Action<int> OnPatchCatalogPageSizeChnaged;

        private string _onnxPath;
        public string OnnxPath
        {
            //get => _onnxPath;
            get
            {
                if (string.IsNullOrWhiteSpace(_onnxPath))
                {
                    _onnxPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                        "onnx" , "N_I_RP_RGB_ns_5PB_5d0_63c_240701_x_29_t1.05_0.48_v1.04_0.52.onnx");
                    //SaveOnnxPath(_onnxPath);
                }
                return _onnxPath;
            }
            set
            {
                //if(_onnxPath != value)
                {
                    _onnxPath = value;
                    OnPropertyChanged(nameof(OnnxPath));
                    ConfigItem2.SaveOnnxPath(value);
                }
            }
        }

        private string _aiDll;
        public string AiDll
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_aiDll))
                {
                    _aiDll = "freeAI.dll";
                    //SaveAiDll(_aiDll);
                }
                return _aiDll;
            }
            set
            {
                //if(_aiDll != value)
                {
                    _aiDll = value;
                    OnPropertyChanged(nameof(AiDll));
                    ConfigItem2.SaveAiDll(value);
                }
            }
        }

        private string _dstImgPath;
        public string DstImgPath
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_dstImgPath))
                {
                    _dstImgPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dst_img");
                    //SaveDstImgPath(_dstImgPath);
                }
                return _dstImgPath;
            }
            set
            {
                //if (_dstImgPath != value)
                {
                    _dstImgPath = value;
                    OnPropertyChanged(nameof(DstImgPath));
                    ConfigItem2.SaveDstImgPath(value);
                }
            }
        }

        private string _transImgPath;
        public string TransImgPath
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_transImgPath))
                {
                    _transImgPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "trans_img");
                    //SaveTransImgPath(_transImgPath);
                }
                return _transImgPath;
            }
            set
            {
                //if(_transImgPath != value)
                {
                    _transImgPath = value;
                    OnPropertyChanged(nameof(TransImgPath));
                    ConfigItem2.SaveTransImgPath(value);
                }
            }
        }

        private string _aiLogPath;
        public string AiLogPath
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_aiLogPath))
                {
                    _aiLogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ai_log");
                    //SaveAiLogPath(_aiLogPath);
                }
                return _aiLogPath;
            }
            set
            {
                //if (_aiLogPath != value)
                {
                    _aiLogPath = value;
                    OnPropertyChanged(nameof(AiLogPath));
                    ConfigItem2.SaveAiLogPath(value);
                }
            }
        }

        private int _standPageSize;
        public int StandPageSize
        {
            get => _standPageSize;
            set
            {
                if (_standPageSize != value)
                {
                    _standPageSize = value;
                    OnPropertyChanged(nameof(StandPageSize));
                    OnStandPageSizeChanged?.Invoke(this, new PageSizeChangedEventArgs(value));
                    ConfigItem2.SaveStandPageSize(value);
                }
            }
        }

        private int _singlePageSize;
        public int SinglePageSize
        {
            get => _singlePageSize;
            set
            {
                if (_singlePageSize != value)
                {
                    _singlePageSize = value;
                    OnPropertyChanged(nameof(SinglePageSize));
                    OnSinglePageSizeChanged?.Invoke(this, new PageSizeChangedEventArgs(value));
                    ConfigItem2.SaveSinglePageSize(value);
                }
            }
        }

        private int _patchPageSize;
        public int PatchPageSize
        {
            get => _patchPageSize;
            set
            {
                if (_patchPageSize != value)
                {
                    _patchPageSize = value;
                    OnPropertyChanged(nameof(PatchPageSize));
                    OnPatchPageSizeChanged?.Invoke(this, new PageSizeChangedEventArgs(value));
                    ConfigItem2.SavePatchPageSize(value);
                }
            }
        }

        private int _catalogPageSize;
        public int CatalogPageSize
        {
            get => _catalogPageSize;
            set
            {
                if (_catalogPageSize != value)
                {
                    _catalogPageSize = value;
                    OnPropertyChanged(nameof(CatalogPageSize));
                }
            }
        }

        private int _standCatalogPageSize;
        public int StandCatalogPageSize
        {
            get => _standCatalogPageSize;
            set
            {
                if(_standCatalogPageSize != value)
                {
                    _standCatalogPageSize = value;
                    OnPropertyChanged(nameof(StandCatalogPageSize));
                    OnStandCatalogPageSizeChanged?.Invoke(value);
                    ConfigItem2.SaveStandCatalogPageSize(value);
                }
            }
        }

        private int _patchCatalogPageSize;
        public int PatchCatalogPageSize
        {
            get => _patchCatalogPageSize;
            set
            {
                if (_patchCatalogPageSize != value)
                {
                    _patchCatalogPageSize = value;
                    OnPropertyChanged(nameof(PatchCatalogPageSize));
                    OnPatchCatalogPageSizeChnaged?.Invoke(value);
                    ConfigItem2.SavePatchCatalogPageSize(value);
                }
            }
        }

        private int _rulerDigitType;
        public int RulerDigitType
        {
            get => _rulerDigitType;
            set
            {
                if(_rulerDigitType != value)
                {
                    _rulerDigitType = value;
                    OnPropertyChanged(nameof(RulerDigitType));
                }
            }
        }

        private int _rulerDigitPointerType;
        public int RulerDigitPointerType
        {
            get => _rulerDigitPointerType;
            set
            {
                if (_rulerDigitPointerType != value)
                {
                    _rulerDigitPointerType = value;
                    OnPropertyChanged(nameof(RulerDigitPointerType));
                }
            }
        }

        private int _rulerPointerType;
        public int RulerPointerType
        {
            get => _rulerPointerType;
            set
            {
                if (_rulerPointerType != value)
                {
                    _rulerPointerType = value;
                    OnPropertyChanged(nameof(RulerPointerType));
                }
            }
        }


        public ConfigItem2()
        {

        }

        private static ConfigItem2 _configItem;

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public static ConfigItem2 GetConfigItem()
        {
            if(_configItem == null)
            {
                _configItem = new ConfigItem2();

                //string onnxPath = Properties.Settings.Default.onnx;
                int standPageSize = Properties.Settings.Default.stand_page_size;
                int singlePageSize = Properties.Settings.Default.single_page_size;
                int patchPageSize = Properties.Settings.Default.patch_page_size;
                int catalogPageSize = Properties.Settings.Default.catalog_page_size;

                _configItem.OnnxPath = Properties.Settings.Default.onnx;  //onnxPath;
                _configItem.AiDll = Properties.Settings.Default.ai_dll;
                _configItem.DstImgPath = Properties.Settings.Default.dstimg_path;
                _configItem.AiLogPath = Properties.Settings.Default.ai_log_path;
                _configItem.TransImgPath = Properties.Settings.Default.transimg_path;

                _configItem.StandPageSize = standPageSize;
                _configItem.SinglePageSize = singlePageSize;
                _configItem.PatchPageSize = patchPageSize;
                _configItem.CatalogPageSize = catalogPageSize;

                _configItem.StandCatalogPageSize = Properties.Settings.Default.stand_catalog_page_size;
                _configItem.PatchCatalogPageSize = Properties.Settings.Default.patch_catalog_page_size;

                _configItem.RulerDigitType = Properties.Settings.Default.ruler_digit_type;
                _configItem.RulerDigitPointerType = Properties.Settings.Default.ruler_digitpointer_type;
                _configItem.RulerPointerType = Properties.Settings.Default.ruler_pointer_type;
            }
            return _configItem;
        }

        public static void SaveOnnxPath(string onnxPath)
        {
            Properties.Settings.Default.onnx = onnxPath;
            Properties.Settings.Default.Save();
        }

        public static void SaveAiDll(String aiDll)
        {
            Properties.Settings.Default.ai_dll = aiDll;
            Properties.Settings.Default.Save();
        }

        public static void SaveDstImgPath(string dstImgPath)
        {
            Properties.Settings.Default.dstimg_path = dstImgPath;
            Properties.Settings.Default.Save();
        }

        public static void SaveTransImgPath(string transImgPath)
        {
            Properties.Settings.Default.transimg_path = transImgPath;
            Properties.Settings.Default.Save();
        }

        public static void  SaveAiLogPath(string aiLogPath)
        {
            Properties.Settings.Default.ai_log_path = aiLogPath;
            Properties.Settings.Default.Save();
        }

        public static void SaveStandPageSize(int pageSize)
        {
            Properties.Settings.Default.stand_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SaveSinglePageSize(int pageSize)
        {
            Properties.Settings.Default.single_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SavePatchPageSize(int pageSize)
        {
            Properties.Settings.Default.patch_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SaveCatalogPageSize(int pageSize)
        {
            Properties.Settings.Default.catalog_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SaveStandCatalogPageSize(int pageSize)
        {
            Properties.Settings.Default.stand_catalog_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SavePatchCatalogPageSize(int pageSize)
        {
            Properties.Settings.Default.patch_catalog_page_size = pageSize;
            Properties.Settings.Default.Save();
        }

        public static void SaveRulerDigitType(int type)
        {
            Properties.Settings.Default.ruler_digit_type = type;
            Properties.Settings.Default.Save();
        }

        public static void SaveRulerDigitPointerType(int type)
        {
            Properties.Settings.Default.ruler_digitpointer_type = type;
            Properties.Settings.Default.Save();
        }


        public static void SaveRulerPointerType(int type)
        {
            Properties.Settings.Default.ruler_pointer_type = type;
            Properties.Settings.Default.Save();
        }

        /////////////////////////////////////////
    }

    public class PageSizeChangedEventArgs : EventArgs
    {
        public int PageSize { get; }

        public PageSizeChangedEventArgs(int pageSize)
        {
            PageSize = pageSize;
        }
    }

    //全数字水表的枚举
    public enum RulerDigitTypeEnum
    {
        MatchAllDigit = 1,             //全部数字相等
        //MatchAllDigitButLast = 2      //除了最后一位所有的数字相同(最后1位误差不能大于1)
    }

    //数字+指针水表的枚举
    public enum RulerDigitPointerTypeEnum
    {
        MatchAllDigitPointer = 1,       //全部的数字和指针要相同
        MatchAllDigit = 2,              //匹配所有的数字
        //MatchAllDigitButLast = 3        //除最后一位匹配所有数字(最后一位误差不大于1)    
    }

    public enum RulerPointerTypeEnum
    {
        MatchAllPointer = 1,            //匹配所有指针
        MatchAllIntegerPointer = 2      //匹配所有整数指针
    }
}
