using ComPDFKitViewer.PdfViewer;
using PDF_Office.EventAggregators;
using PDF_Office.Model;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using PDFSettings;
using PDF_Office.Model.EditTools.Watermark;
using PDF_Office.Helper;
using System.Windows.Media;
using System.Diagnostics;
using ComPDFKit.PDFDocument;
using PDF_Office.Model.EditTools.Background;
using PDF_Office.Model.EditTools.Bates;
using PDF_Office.Model.EditTools.HeaderFooter;
using PDF_Office.Properties;
using System.IO;

namespace PDF_Office.ViewModels.EditTools.Bates
{
    public class BatesCreateContentViewModel : BindableBase, INavigationAware
    {
        private CPDFViewer PDFViewer;

        public BatesInfo BatesInfo = new BatesInfo();

        public BatesHeaderFooterItem TemplateBatesItem;

        public enum EnumCreateOrEdit
        {
            None,
            StatusCreate,
            StatusEdit
        }

        private List<string> _fontNameList = new List<string>();
        public List<string> FontNameList
        {
            get { return _fontNameList; }
            set
            {
                SetProperty(ref _fontNameList, value);
            }
        }

        private void InitFontNameList()
        {
            FontNameList.Clear();
            FontNameList.Add("Courier");
            FontNameList.Add("Courier-Bold");
            FontNameList.Add("Courier-Oblique");
            FontNameList.Add("Courier-BoldOblique");
            FontNameList.Add("Helvetica");
            FontNameList.Add("Helvetica-Bold");
            FontNameList.Add("Helvetica-Oblique");
            FontNameList.Add("Helvetica-BoldOblique");
            FontNameList.Add("Times-Roman");
            FontNameList.Add("Times-Bold");
            FontNameList.Add("Times-Italic");
            FontNameList.Add("Times-BoldItalic");
        }

        private int _fontNameSelectedIndex = 0;
        public int FontNameSelectedIndex
        {
            get { return _fontNameSelectedIndex; }
            set
            {
                SetProperty(ref _fontNameSelectedIndex, value);
                SetFontName(FontNameSelectedIndex);
                eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BatesInfo
                });

            }
        }

        private List<string> _fontSizeList = new List<string>();
        public List<string> FontSizeList
        {
            get { return _fontSizeList; }
            set
            {
                SetProperty(ref _fontSizeList, value);
            }
        }

        private void InitFontSizeList()
        {
            FontSizeList.Clear();
            for (int temp = 10; temp <= 15; temp += 1)
            {
                FontSizeList.Add(temp.ToString() + "pt");
            }
        }

        private int _fontSizeSelectedIndex = 0;
        public int FontSizeSelectedIndex
        {
            get { return _fontSizeSelectedIndex; }
            set
            {
                SetProperty(ref _fontSizeSelectedIndex, value);
                SetFontSize(FontSizeSelectedIndex);
                eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BatesInfo
                });
            }
        }

        private List<string> _starPagetNumberList = new List<string>();
        public List<string> StarPagetNumberList
        {
            get { return _starPagetNumberList; }
            set
            {
                SetProperty(ref _starPagetNumberList, value);
            }
        }

        private void InitStarPagetNumberList()
        {
            StarPagetNumberList.Clear();
            for (int temp = 10; temp <= 15; temp += 1)
            {
                StarPagetNumberList.Add(temp.ToString());
            }
        }

        private int _starPagetNumberIndex = 0;
        public int StarPagetNumberIndex
        {
            get { return _starPagetNumberIndex; }
            set
            {
                SetProperty(ref _starPagetNumberIndex, value);
                SetStarPagetNumber(StarPagetNumberIndex);
            }
        }

        public string _pageRangeText = "0";
        public string PageRangeText
        {
            get { return _pageRangeText; }
            set
            {
                _pageRangeText = value;
                BatesInfo.PageRange = PageRangeText;
                //EditToolsHelper.GetPageRange(PageRangeSelectIndex, PDFViewer.Document, ref BatesInfo.PageRange, PageRangeText);
                eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BatesInfo
                });
            }
        }

        private int _pageRangeSelectIndex = 0;
        public int PageRangeSelectIndex
        {
            get { return _pageRangeSelectIndex; }
            set
            {
                SetProperty(ref _pageRangeSelectIndex, value);
                BatesInfo.PageRangeIndex = PageRangeSelectIndex;
                //EditToolsHelper.GetPageRange(PageRangeSelectIndex, PDFViewer.Document, ref BatesInfo.PageRange, PageRangeText);
                eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BatesInfo
                });
            }
        }

        private SolidColorBrush _solidColorBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0x00, 0x00));
        public SolidColorBrush SolidColorBrush
        {
            get
            {
                return _solidColorBrush;
            }
            set
            {

                SetProperty(ref _solidColorBrush, value);

            }
        }

        private Color _stringColor = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
        public Color StringColor
        {
            get
            {
                return _stringColor;
            }
            set
            {
                SetProperty(ref _stringColor, value);
                SolidColorBrush = new SolidColorBrush(StringColor);
                for (int i = 0; i <= 5; i++)
                {
                    BatesInfo.TextData[i].Color = EditToolsHelper.ConvertColor(value);
                }
                eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                {
                    Unicode = Unicode,
                    Status = BatesInfo
                });

            }
        }


        private EnumCreateOrEdit _createOrEdit;
        public EnumCreateOrEdit CreateOrEdit
        {
            get { return _createOrEdit; }
            set
            {
                _createOrEdit = value;
                if (value == EnumCreateOrEdit.StatusEdit)
                {
                    EditBaseVisible = Visibility.Visible;
                    CreateBaseVisible = Visibility.Collapsed;
                }
                else if (value == EnumCreateOrEdit.StatusCreate)
                {
                    CreateBaseVisible = Visibility.Visible;
                    EditBaseVisible = Visibility.Collapsed;
                }
            }
        }

        private Visibility _createBaseVisible;
        public Visibility CreateBaseVisible
        {
            get => _createBaseVisible;
            set => SetProperty(ref _createBaseVisible, value);
        }

        private int maxPageRange = 0;
        public int MaxPageRange
        {
            get { return maxPageRange; }
            set
            {
                SetProperty(ref maxPageRange, value);
            }
        }

        private Visibility _editBaseVisible;
        public Visibility EditBaseVisible
        {
            get => _editBaseVisible;
            set => SetProperty(ref _editBaseVisible, value);
        }

        private string _marginTopValue = "3";
        public string MarginTopValue
        {
            get { return _marginTopValue; }
            set
            {
                SetProperty(ref _marginTopValue, value);
                bool ValueEQ = true;
                if (BatesInfo.margin[1] == float.Parse(MarginTopValue))
                {
                    ValueEQ = false;
                }
                BatesInfo.margin[1] = float.Parse(MarginTopValue);
                if (ValueEQ)
                {
                    eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                    {
                        Unicode = Unicode,
                        Status = BatesInfo
                    });
                }
            }
        }

        private string _marginDownValue = "3";
        public string MarginDownValue
        {
            get { return _marginDownValue; }
            set
            {
                SetProperty(ref _marginDownValue, value);
                bool ValueEQ = true;
                if (BatesInfo.margin[3] == float.Parse(MarginTopValue))
                {
                    ValueEQ = false;
                }
                BatesInfo.margin[3] = float.Parse(MarginDownValue);
                if (ValueEQ)
                {
                    eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                    {
                        Unicode = Unicode,
                        Status = BatesInfo
                    });
                }
            }
        }

        private string _marginLeftValue = "3";
        public string MarginLeftValue
        {
            get { return _marginLeftValue; }
            set
            {
                SetProperty(ref _marginLeftValue, value);
                bool ValueEQ = true;
                if (BatesInfo.margin[0] == float.Parse(MarginTopValue))
                {
                    ValueEQ = false;
                }
                BatesInfo.margin[0] = float.Parse(MarginLeftValue);
                if (ValueEQ)
                {
                    eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                    {
                        Unicode = Unicode,
                        Status = BatesInfo
                    });
                }
            }
        }

        private string _marginRightValue = "3";
        public string MarginRightValue
        {
            get { return _marginRightValue; }
            set
            {
                SetProperty(ref _marginRightValue, value);
                bool ValueEQ = true;
                if (BatesInfo.margin[2] == float.Parse(MarginTopValue))
                {
                    ValueEQ = false;
                }
                if (ValueEQ)
                {
                    BatesInfo.margin[2] = float.Parse(MarginRightValue);
                    eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                    {
                        Unicode = Unicode,
                        Status = BatesInfo
                    });
                }
            }
        }

        private string _digitNumberValue = "1";
        public string DigitNumberValue
        {
            get { return _digitNumberValue; }
            set
            {
                SetProperty(ref _digitNumberValue, value);
                BatesInfo.DigitNumber = int.Parse(DigitNumberValue);
            }
        }


        private string _textValue = "";
        public string TextValue
        {
            get { return _textValue; }
            set
            {
                SetProperty(ref _textValue, value);
            }
        }


        private string _prefixTextValue = "";
        public string PrefixTextValue
        {
            get { return _prefixTextValue; }
            set
            {

                _prefixTextValue = value;

            }
        }

        private string _surfixTextValue = "";
        public string SurfixTextValue
        {
            get { return _surfixTextValue; }
            set
            {
                _surfixTextValue = value;
            }
        }

        public int GetLocationIndex = 0;

        private Dictionary<string, string> _getTextValueFromNumber = new Dictionary<string, string>();
        public Dictionary<string, string> GetTextValueFromNumber
        {
            get { return _getTextValueFromNumber; }
            set
            {
                _getTextValueFromNumber = value;
            }
        }

        public IEventAggregator eventAggregator;

        public DelegateCommand<object> ChangeLocationCommand { get; set; }
        public DelegateCommand EnterTemplateListCommand { get; set; }
        public DelegateCommand SaveToTemplateListCommand { get; set; }
        public DelegateCommand SaveToCurrentTemplateListCommand { get; set; }
        public DelegateCommand<object> SelectedColorChangedCommand { get; set; }
        public DelegateCommand<object> TextValueChangedCommand { get; set; }
        public DelegateCommand ADDBatesCommand { get; set; }

        public string Unicode = null;

        public BatesCreateContentViewModel(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            Unicode = App.mainWindowViewModel.SelectedItem.Unicode;
            for (int i = 0; i <= 5; i++)
            {
                BatesInfo.TextData[i].Color = EditToolsHelper.ConvertColor(Color.FromArgb(0xFF, 0xFF, 0x00, 0x00));
            }
            InitList();
            InitBatesInfo();
            ChangeLocationCommand = new DelegateCommand<object>(ChangeLocation);
            SelectedColorChangedCommand = new DelegateCommand<object>(ChangedColor);
            EnterTemplateListCommand = new DelegateCommand(EnterTemplateList);
            SaveToTemplateListCommand = new DelegateCommand(SaveToTemplateList);
            SaveToCurrentTemplateListCommand = new DelegateCommand(SaveToCurrentTemplateList);
            TextValueChangedCommand = new DelegateCommand<object>(TextValueChanged);
            ADDBatesCommand = new DelegateCommand(ADDBates);
        }

        private void InitList()
        {

            InitFontNameList();
            InitFontSizeList();
            InitStarPagetNumberList();
            InitLocationButtonMatrix();

        }

        private void InitLocationButtonMatrix()
        {
            GetTextValueFromNumber.Clear();
            for (var temp = 0; temp <= 5; temp++)
            {
                GetTextValueFromNumber.Add(temp.ToString(), temp.ToString());
            }
        }

        private void InitBatesInfo()
        {
            for (int i = 0; i <= 5; i++)
            {
                BatesInfo.TextData[i].text = GetTextValueFromNumber[i.ToString()];
            }
            BatesInfo.margin[0] = float.Parse(MarginTopValue);
            BatesInfo.margin[1] = float.Parse(MarginRightValue);
            BatesInfo.margin[2] = float.Parse(MarginDownValue);
            BatesInfo.margin[3] = float.Parse(MarginLeftValue);
            BatesInfo.Prefix = PrefixTextValue;
            BatesInfo.Suffix = SurfixTextValue;
            BatesInfo.DigitNumber = int.Parse(DigitNumberValue);
            SetFontName(FontNameSelectedIndex);
            SetFontSize(FontSizeSelectedIndex);
            SetStarPagetNumber(StarPagetNumberIndex);
            StringColor = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
        }

        private void SetFontName(int Index)
        {
            for (int i = 0; i <= 5; i++) { BatesInfo.TextData[i].fontName = FontNameList[Index]; }
        }

        private void SetFontSize(int Index)
        {
            for (int i = 0; i <= 5; i++) { BatesInfo.TextData[i].fontSize = (Index + 7) * 1.33f; }
        }

        private void SetStarPagetNumber(int Index)
        {
            BatesInfo.StarPagetNumber = Index;
        }


        public void ChangeLocation(object e)
        {
            string args = e as string;
            if (args != null)
            {
                GetLocationIndex = int.Parse(args);
                TextValue = GetTextValueFromNumber[args];

            }
        }

        private void ChangedColor(object obj)
        {
            if (obj != null)
            {
                var colorValue = (Color)obj;
                if (colorValue != null)
                {

                    StringColor = colorValue;
                }
            }
        }

        public void EnterTemplateList()
        {
            this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode { Unicode = Unicode, Status = EnumTemplateListOrCreate.StatusTemplate });
        }

        public void SaveToTemplateList()
        {
            SaveCurrentTemplate();
        }

        public void SaveToCurrentTemplateList()
        {
            ConfirmEditBackgroundTemplateItem();
        }

        private void TextValueChanged(object obj)
        {
            if (obj != null)
            {
                var textValue = obj as System.Windows.Controls.TextBox;
                if (textValue != null)
                {
                    bool TextEQ = true;
                    switch (textValue.Name)
                    {
                        case "TextValueTextBox":

                            if (GetTextValueFromNumber[GetLocationIndex.ToString()] == textValue.Text)
                            {
                                TextEQ = false;
                            }
                            GetTextValueFromNumber[GetLocationIndex.ToString()] = textValue.Text;
                            BatesInfo.TextData[GetLocationIndex].text = GetTextValueFromNumber[GetLocationIndex.ToString()];

                            break;
                        case "PrefixTextValueTextBox":
                            if (BatesInfo.Prefix == textValue.Text)
                            {
                                TextEQ = false;
                            }
                            BatesInfo.Prefix = textValue.Text;
                            PrefixTextValue= textValue.Text;

                            break;
                        case "SuffixTextValueTextBox":
                            if (BatesInfo.Suffix == textValue.Text)
                            {
                                TextEQ = false;
                            }
                            BatesInfo.Suffix = textValue.Text;
                            SurfixTextValue = textValue.Text;
                            break;
                        default:
                            break;
                    }
                    if (TextEQ)
                    {
                        eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
                        {
                            Unicode = Unicode,
                            Status = BatesInfo
                        });
                    }

                }
            }
        }

        public void ADDBates()
        {
            if (PrefixTextValue == "" || SurfixTextValue == "")
            {
                if (SurfixTextValue == "" && PrefixTextValue == "")
                {
                    GetTextValueFromNumber[GetLocationIndex.ToString()] = GetTextValueFromNumber[GetLocationIndex.ToString()] + "<<" + "#" + DigitNumberValue + "#" + (StarPagetNumberIndex + 1).ToString() + ">>";
                }
                else if (SurfixTextValue == "")
                {
                    GetTextValueFromNumber[GetLocationIndex.ToString()] = GetTextValueFromNumber[GetLocationIndex.ToString()] + "<<" + "#" + DigitNumberValue + "#" + (StarPagetNumberIndex + 1).ToString() + "#" + PrefixTextValue + ">>";
                }
                else
                {
                    GetTextValueFromNumber[GetLocationIndex.ToString()] = GetTextValueFromNumber[GetLocationIndex.ToString()] + "<<" + "#" + DigitNumberValue + "#" + (StarPagetNumberIndex + 1).ToString() + "#" + "#" + SurfixTextValue + ">>";
                }
            }
            else
            {
                GetTextValueFromNumber[GetLocationIndex.ToString()] = GetTextValueFromNumber[GetLocationIndex.ToString()] + "<<" + "#" + DigitNumberValue + "#" + (StarPagetNumberIndex + 1).ToString() + "#" + PrefixTextValue + "#" + SurfixTextValue + ">>";
            }
            BatesInfo.TextData[GetLocationIndex].text = GetTextValueFromNumber[GetLocationIndex.ToString()];
            TextValue= GetTextValueFromNumber[GetLocationIndex.ToString()];
            eventAggregator.GetEvent<SetBatesEvent>().Publish(new BatesInfoUnicode
            {
                Unicode = Unicode,
                Status = BatesInfo
            });
        }

        public void ConvertInfoToItem(ref BatesHeaderFooterItem batesItem, BatesInfo batesInfo)
        {
            batesItem.TextData = batesInfo.TextData;
            batesItem.DigitNumber = batesInfo.DigitNumber;
            batesItem.ItemName = batesInfo.ItemName;
            batesItem.Prefix = batesInfo.Prefix;
            batesItem.Suffix = batesInfo.Suffix;
            batesItem.StarPagetNumber = batesInfo.StarPagetNumber;
            batesItem.margin = batesInfo.margin;
            batesItem.PageRange = PageRangeText;
            batesItem.PageRangeIndex = batesInfo.PageRangeIndex;

        }

        public void ConvertItemToInfo(BatesHeaderFooterItem batesItem, ref BatesInfo batesInfo)
        {
            batesInfo.TextData = batesItem.TextData;
            batesInfo.ItemName = batesItem.ItemName;
            batesInfo.DigitNumber = batesItem.DigitNumber;
            batesInfo.Prefix = batesItem.Prefix;
            batesInfo.Suffix = batesItem.Suffix;
            batesInfo.StarPagetNumber = batesItem.StarPagetNumber;
            batesInfo.margin = batesItem.margin;
            batesInfo.PageRangeIndex = batesItem.PageRangeIndex;
            batesInfo.PageRange=batesItem.PageRange;
            //EditToolsHelper.GetPageRange(batesInfo.PageRangeIndex, PDFViewer.Document, ref batesInfo.PageRange, batesItem.PageRange);

        }

        public void SaveCurrentTemplate()
        {
            var batesItem = new BatesHeaderFooterItem();
            ConvertInfoToItem(ref batesItem, BatesInfo);
            batesItem.ItemName += Settings.Default.BatesTemplateList.Count().ToString();
            try
            {
                //创建缓存文件夹
                string folderPath = Path.Combine(App.CurrentPath, "Bates");
                //有可能因为其他原因存在同名文件,导致创建文件夹失败,需要先删除同名文件
                //保险措施(猜测)
                if (File.Exists(folderPath))
                {
                    File.Delete(folderPath);
                }

                DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                if (!tempfolder.Exists)
                {
                    tempfolder.Create();
                }
                //预览图缓存
                string saveName = Guid.NewGuid().ToString();
                string savePath = Path.Combine(folderPath, saveName);
                Settings.Default.BatesTemplateList.Add(batesItem);
                Settings.Default.Save();
            }
            catch
            {

            }

            this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode
            {
                Unicode = Unicode,
                Status = EnumTemplateListOrCreate.StatusTemplate
            });
        }

        public void ConfirmEditBackgroundTemplateItem()
        {

            var batesItem = new BatesHeaderFooterItem();
            ConvertInfoToItem(ref batesItem, BatesInfo);
            try
            {
                //创建缓存文件夹
                string folderPath = Path.Combine(App.CurrentPath, "Background");
                //有可能因为其他原因存在同名文件,导致创建文件夹失败,需要先删除同名文件
                //保险措施(猜测)
                if (File.Exists(folderPath))
                {
                    File.Delete(folderPath);
                }

                DirectoryInfo tempfolder = new DirectoryInfo(folderPath);
                if (!tempfolder.Exists)
                {
                    tempfolder.Create();
                }
                Settings.Default.BatesTemplateList[TemplateBatesItem.listIndex] = batesItem;
                Settings.Default.Save();
            }
            catch
            {

            }
            this.eventAggregator.GetEvent<EnterTemplateListOrCreateEvent>().Publish(new EnumTemplateListOrCreateUnicode
            {
                Unicode = Unicode,
                Status = EnumTemplateListOrCreate.StatusTemplate
            });

        }

        public void InitComponentBySelectedInfo()
        {
            ConvertItemToInfo(TemplateBatesItem, ref BatesInfo);
            for (int i = 0; i <= 5; i++)
            {
                GetTextValueFromNumber[i.ToString()] = BatesInfo.TextData[i].text;
            }
            MarginTopValue = BatesInfo.margin[0].ToString();
            MarginRightValue = BatesInfo.margin[1].ToString();
            MarginDownValue = BatesInfo.margin[2].ToString();
            MarginLeftValue = BatesInfo.margin[3].ToString();
            PrefixTextValue = BatesInfo.Prefix;
            SurfixTextValue = BatesInfo.Suffix;
            DigitNumberValue = BatesInfo.DigitNumber.ToString();
            FontNameSelectedIndex = FontNameList.IndexOf(BatesInfo.TextData[0].fontName);
            FontSizeSelectedIndex = FontSizeList.IndexOf(BatesInfo.TextData[0].fontSize.ToString());
            StarPagetNumberIndex = StarPagetNumberList.IndexOf(BatesInfo.StarPagetNumber.ToString());
            StringColor = EditToolsHelper.ConvertColor(BatesInfo.TextData[0].Color);
            SolidColorBrush = new SolidColorBrush(StringColor);
            PageRangeSelectIndex = BatesInfo.PageRangeIndex;
            PageRangeText=BatesInfo.PageRange;
        }
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {

            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
            MaxPageRange = PDFViewer.Document.PageCount;
            
            if (navigationContext.Parameters.TryGetValue<BatesHeaderFooterItem>("BatesItem", out TemplateBatesItem))
            {
                CreateOrEdit = EnumCreateOrEdit.StatusEdit;
                BatesInfo.PageRange = TemplateBatesItem.PageRange;
                InitComponentBySelectedInfo();
                
            }
            else
            {
                CreateOrEdit = EnumCreateOrEdit.StatusCreate;
                EditToolsHelper.GetPageRange(PageRangeSelectIndex, PDFViewer.Document, ref BatesInfo.PageRange, PageRangeText);
            }
        }


    }
}