using ComPDFKit.PDFDocument;
using ComPDFKit.PDFPage;
using ComPDFKitViewer.PdfViewer;
using Microsoft.Win32;
using PDF_Office.Helper;
using PDF_Office.Model;
using PDF_Office.Model.Dialog.ToolsDialogs;
using PDF_Office.Views.Dialog;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace PDF_Office.ViewModels.Dialog.ToolsDialogs
{
    class MergeDialogViewModel : BindableBase, IDialogAware
    {
        enum PageSizeType
        {
            kDefault = 0,
            A4 = 1,
            A3 = 2,
            Letter = 3,
            Legal = 4,
            Customized = 5,
        }
        string CurrentFilePath = "";

        #region 框架内容

        public string Title => "";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {

        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            CPDFViewer pdfViewer = null;
            parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out pdfViewer);
            if (pdfViewer != null)
            {
                CurrentFilePath = pdfViewer.Document.FilePath;
            }
        }

        #endregion
        #region 定义与初始化

        public ObservableCollection<MergeObject> MergeObjectlist { get; set; }

        public DelegateCommand CancelCommand { get; set; }
        public DelegateCommand MergeCommand { get; set; }
        public DelegateCommand<object> AddFilesCommand { get; set; }
        public DelegateCommand ClearCommand { get; set; }
        public DelegateCommand<object> SetPageSizeTypeCommand { get; set; }

        public IDialogService dialogs;

        private PageSizeType pageSizeType = PageSizeType.kDefault;

        private string inputWidth;

        public string InputWidth
        {
            get { return inputWidth; }
            set
            {
                SetProperty(ref inputWidth, value);
            }
        }

        private string inputHeight;

        public string InputHeight
        {
            get { return inputHeight; }
            set
            {
                SetProperty(ref inputHeight, value);
            }
        }


        public MergeDialogViewModel(IDialogService dialogService)
        {
            dialogs = dialogService;
            MergeObjectlist = new ObservableCollection<MergeObject>();
            CancelCommand = new DelegateCommand(Cancel);
            AddFilesCommand = new DelegateCommand<object>(ButtonAddFiles);
            MergeCommand = new DelegateCommand(Merge);
            ClearCommand = new DelegateCommand(Clear);
            SetPageSizeTypeCommand = new DelegateCommand<object>(SetPageSizeType);
        }

        #endregion

        #region 私有方法
        private void Cancel()
        {
            RequestClose.Invoke(new DialogResult(ButtonResult.Cancel));
        }

        public void ButtonAddFiles(object data)
        {
            int index = Convert.ToInt32(data);
            switch (index)
            {
                case 0:
                    AddFiles(OpenFile());
                    break;
                case 1:
                    AddFiles(OpenFileFolder());
                    break;
                case 2:
                    List<string> list = new List<string>();

                    int Fileindex = App.OpenedFileList.IndexOf(CurrentFilePath);
                    for (int i = 0; i < App.OpenedFileList.Count; i++)
                    {
                        if (i != Fileindex)
                        {
                            list.Add(App.OpenedFileList[i]);
                        }
                    }
                    AddFiles(list.ToArray());
                    break;
                default:
                    break;
            }
        }

        private string[] OpenFileFolder()
        {
            System.Windows.Forms.FolderBrowserDialog openFile = new System.Windows.Forms.FolderBrowserDialog();
            if (openFile.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
            {
                return null;
            }
            DirectoryInfo tempfolder = new DirectoryInfo(openFile.SelectedPath);
            FileInfo[] fileInfos = tempfolder.GetFiles();
            List<string> list = new List<string>();
            foreach (FileInfo item in fileInfos)
            {
                list.Add(item.FullName);
            }
            return list.ToArray();
        }
        private string[] OpenFile()
        {
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.Multiselect = true;
            openFile.Filter = "Files(*pdf;*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff)|*.pdf;*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tiff|" +
                "(*.pdf)|*.pdf|" +
                "(*.bmp)|*.bmp|" +
                "(*.gif)|*.gif|" +
                "(*.jpeg)|*.jpeg|" +
                "(*.jpg)|*.jpg|" +
                "(*.png)|*.png|" +
                "(*.tiff)|*.tiff";
            if (openFile.ShowDialog() == false)
            {
                return null;
            }
            return openFile.FileNames;
        }

        private void Merge()
        {
            bool result = true;
            CPDFDocument SaveDoc = CPDFDocument.CreateDocument();
            for (int i = 0; i < MergeObjectlist.Count; i++)
            {
                //图片
                if (Path.GetExtension(MergeObjectlist[i].FilePath).Trim().ToLower() != "pdf")
                {
                    BitmapSource frame = MergeObjectlist[i].DocThumbnail;
                    byte[] imageData = new byte[frame.PixelWidth * frame.PixelHeight * 4];
                    if (frame.Format != PixelFormats.Bgra32)
                    {
                        FormatConvertedBitmap covert = new FormatConvertedBitmap(frame, PixelFormats.Bgra32, frame.Palette, 0);
                        covert.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                    }
                    else
                    {
                        frame.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                    }
                    frame.CopyPixels(imageData, frame.PixelWidth * 4, 0);
                    result = SaveDoc.InsertPage(0, frame.PixelWidth, frame.PixelHeight, imageData, CPDFDocumentImageMode.CPDFDocumentImageModeScaleToFill);
                    if (!result)
                    {
                        SaveDoc.Release();
                        return;
                    }
                    continue;
                }
                else
                {
                    CPDFDocument tempDoc = CPDFDocument.InitWithFilePath(MergeObjectlist[i].FilePath);
                    if (!string.IsNullOrEmpty(MergeObjectlist[i].Password))
                    {
                        tempDoc.UnlockWithPassword(MergeObjectlist[i].Password);
                    }
                    result = SaveDoc.ImportPages(tempDoc, MergeObjectlist[i].SetPageRange);
                    if (!result)
                    {
                        SaveDoc.Release();
                        tempDoc.Release();
                        return;
                    }
                    tempDoc.Release();
                }
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.FileName = "Untitle";
            saveFileDialog.Filter = "PDF|*.pdf;";
            if (saveFileDialog.ShowDialog() == false)
            {
                return;
            }
            string path = saveFileDialog.FileName;

            System.Windows.Rect rect = new System.Windows.Rect();

            switch (pageSizeType)
            {
                case PageSizeType.kDefault:
                    break;
                case PageSizeType.A4:

                    rect.Width = CommonHelper.GetPageSizeFomrUnit(210);
                    rect.Height = CommonHelper.GetPageSizeFomrUnit(297);
                    break;
                case PageSizeType.A3:
                    rect.Width = CommonHelper.GetPageSizeFomrUnit(297);
                    rect.Height = CommonHelper.GetPageSizeFomrUnit(420);
                    break;
                case PageSizeType.Letter:
                    rect.Width = CommonHelper.GetPageSizeFomrUnit(216);
                    rect.Height = CommonHelper.GetPageSizeFomrUnit(279);
                    break;
                case PageSizeType.Legal:
                    rect.Width = CommonHelper.GetPageSizeFomrUnit(216);
                    rect.Height = CommonHelper.GetPageSizeFomrUnit(356);
                    break;
                case PageSizeType.Customized:
                    if (!string.IsNullOrEmpty(InputWidth) && !string.IsNullOrEmpty(InputHeight))
                    {
                        rect.Width = CommonHelper.GetPageSizeFomrUnit(Convert.ToInt32(InputWidth));
                        rect.Height = CommonHelper.GetPageSizeFomrUnit(Convert.ToInt32(InputHeight));
                    }
                    else
                    {
                        rect.Width = CommonHelper.GetPageSizeFomrUnit(595);
                        rect.Height = CommonHelper.GetPageSizeFomrUnit(841);
                    }
                    break;
                default:
                    break;
            }
            if (rect.Width > 0 && rect.Height > 0)
            {
                //裁剪
                for (int i = 0; i < SaveDoc.PageCount; i++)
                {
                    CPDFPage page = SaveDoc.PageAtIndex(i);
                    page.CropPage(CPDFDisplayBox.MediaBox, rect);
                }
            }

            bool saveResult = SaveDoc.WriteToFilePath(path);
            SaveDoc.Release();
            CommonHelper.ShowFileBrowser(path);
            DialogParameters valuePairs = new DialogParameters();
            valuePairs.Add(ParameterNames.FilePath, path);
            RequestClose.Invoke(new DialogResult(ButtonResult.OK, valuePairs));
        }

        private void Clear()
        {
            MergeObjectlist.Clear();
        }

        private void SetPageSizeType(object button)
        {
            if (button is RadioButton)
            {
                pageSizeType = (PageSizeType)Convert.ToInt32((button as RadioButton).Tag);
            }
        }

        #endregion

        #region 公开方法

        public void DeleteItem(MergeObject merge)
        {
            MergeObjectlist.Remove(merge);
        }

        public void MoveMerge(MergeObject targetNode, MergeObject soureNode)
        {
            int targetindex = MergeObjectlist.IndexOf(targetNode);
            MergeObjectlist.Remove(soureNode);
            if (targetNode.IsForward)
            {
                if (targetindex + 1 < MergeObjectlist.Count)
                {
                    MergeObjectlist.Insert(targetindex + 1, soureNode);
                }
                else
                {
                    MergeObjectlist.Add(soureNode);
                }
            }
            else
            {
                MergeObjectlist.Insert(targetindex, soureNode);
            }
        }

        public void AddFiles(string[] FilePath)
        {
            if (FilePath == null)
            {
                return;
            }
            bool result = true;
            for (int i = 0; i < FilePath.Length; i++)
            {
                MergeObject mergeObject = new MergeObject();
                mergeObject.FilePath = FilePath[i];

                //通过路径判断文件是否已添加
                bool IsExists = false;
                for (int j = 0; j < MergeObjectlist.Count; j++)
                {
                    if (MergeObjectlist[j].FilePath == mergeObject.FilePath)
                    {
                        IsExists = true;
                    }
                }
                if (IsExists)
                {
                    continue;
                }
                string FileType = Path.GetExtension(mergeObject.FilePath).Trim().ToLower();
                if (FileType != ".pdf")
                {
                    if (!Properties.Resources.imageex.Contains(FileType))
                    {
                        //图片格式不支持
                        continue;
                    };

                    mergeObject.DocName = Path.GetFileName(mergeObject.FilePath);
                    mergeObject.DocPageCount = 1 + "页";
                    mergeObject.SDKPageCount = 1;
                    mergeObject.DocSize = CommonHelper.GetFileSize(mergeObject.FilePath);
                    mergeObject.DocThumbnail = new BitmapImage(new Uri(mergeObject.FilePath)); ;
                }
                else
                {
                    CPDFDocument doc = CPDFDocument.InitWithFilePath(mergeObject.FilePath);
                    if (doc.IsLocked)
                    {
                        DialogParameters value = new DialogParameters();
                        value.Add(ParameterNames.PDFDocument, doc);
                        dialogs.ShowDialog(DialogNames.VerifyPassWordDialog, value, e =>
                        {
                            if (e.Result != ButtonResult.OK)
                            {
                                result = false;
                            }
                            else
                            {
                                mergeObject.Password = e.Parameters.GetValue<string>(ParameterNames.PassWord);
                            }

                        });
                        if (!result)
                        {
                            doc.Release();
                            continue;
                        }
                    }
                    mergeObject.DocName = doc.FileName;
                    mergeObject.DocPageCount = doc.PageCount.ToString() + "页";
                    mergeObject.SDKPageCount = doc.PageCount;
                    mergeObject.DocSize = CommonHelper.GetFileSize(mergeObject.FilePath);

                    //获取第一页缩略图
                    CPDFPage page = doc.PageAtIndex(0);
                    Size size = doc.GetPageSize(0);

                    byte[] bmpData = new byte[(int)(size.Width * size.Height * 4)];
                    WriteableBitmap WirteBitmap = new WriteableBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Bgra32, null);
                    page.RenderPageBitmap(0, 0, (int)size.Width, (int)size.Height, 0xFFFFFFFF, bmpData, 1);
                    WirteBitmap.WritePixels(new Int32Rect(0, 0, (int)size.Width, (int)size.Height), bmpData, WirteBitmap.BackBufferStride, 0);
                    WirteBitmap.Freeze();
                    mergeObject.DocThumbnail = WirteBitmap;

                    doc.Release();
                }
                MergeObjectlist.Add(mergeObject);
            }
        }
        #endregion
    }
}