using ComPDFKit.Measure;
using ComPDFKit.PDFAnnotation;
using ComPDFKit.Tool;
using Compdfkit_Tools.Helper;
using Compdfkit_Tools.PDFControl;
using ComPDFKitViewer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ComPDFKit.Tool.Help;
using ComPDFKit.Viewer.Annot;
using ComPDFKitViewer.BaseObject;


namespace Compdfkit_Tools.Measure
{
    /// <summary>
    /// MeasureControl.xaml 的交互逻辑
    /// </summary>
    public partial class MeasureControl : UserControl
    {
        public MeasurePropertyControl measurePropertyControl = new MeasurePropertyControl();
        private CPDFDisplaySettingsControl displaySettingsControl;

        private PDFViewControl PdfViewControl = new PDFViewControl();

        private PanelState panelState = PanelState.GetInstance();
        
        private CPDFAnnotation currentAnnot = null;

        public event EventHandler ExpandEvent;

        public MeasureControl()
        {
            InitializeComponent();
            //MeasureSetting.MeasureChanged += MeasureSetting_MeasureChanged;
        }

        //private void MeasureSetting_MeasureChanged(object sender, MeasureEventArgs e)
        //{
        //    InfoPanel.SetMeasureType(e.Type);
        //    InfoPanel.SetMeasureInfo(e);

        //    switch (e.Type)
        //    {
        //        case CPDFMeasureType.CPDF_DISTANCE_MEASURE:
        //        case CPDFMeasureType.CPDF_PERIMETER_MEASURE:
        //            SettingPanel.ShowAreaAndLength(Visibility.Collapsed);
        //            break;
        //        case CPDFMeasureType.CPDF_AREA_MEASURE:
        //            SettingPanel.ShowAreaAndLength(Visibility.Visible);
        //            break;
        //        default:
        //            break;
        //    }

        //    SettingPanel.BindMeasureSetting(e);
        //}
        #region Init PDFViewer

        public void InitWithPDFViewer(PDFViewControl pdfViewControl)
        {
            PdfViewControl = pdfViewControl;
            //PdfViewControl.PDFView = pdfViewer;
            PDFMeasureTool.InitWithPDFViewer(pdfViewControl, measurePropertyControl, this);
            FloatPageTool.InitWithPDFViewer(pdfViewControl);
            PDFGrid.Child = PdfViewControl;

            panelState.PropertyChanged -= PanelState_PropertyChanged;
            panelState.PropertyChanged += PanelState_PropertyChanged; 
            PdfViewControl.MouseLeftButtonDownHandler -= PDFToolManager_MouseLeftButtonDownHandler;
            PdfViewControl.MouseLeftButtonUpHandler -= PDFToolManager_MouseLeftButtonUpHandler;
            PdfViewControl.MouseMoveHandler -= PDFToolManager_MouseMoveHandler;

            PdfViewControl.MouseLeftButtonDownHandler += PDFToolManager_MouseLeftButtonDownHandler;
            PdfViewControl.MouseLeftButtonUpHandler += PDFToolManager_MouseLeftButtonUpHandler;
            PdfViewControl.MouseMoveHandler += PDFToolManager_MouseMoveHandler;
            //pdfViewControl.PDFView.AnnotActiveHandler -= PDFView_AnnotActiveHandler;
            //pdfViewControl.PDFView.AnnotActiveHandler += PDFView_AnnotActiveHandler;
            //pdfViewControl.PDFView.AnnotCommandHandler -= PDFView_AnnotCommandHandler;
            //pdfViewControl.PDFView.AnnotCommandHandler += PDFView_AnnotCommandHandler;
            SetInfoPanelVisble(false, false);
            SettingPanel.PdfViewControl= pdfViewControl;
        }

        private void PDFToolManager_MouseMoveHandler(object sender, MouseEventObject e)
        {
        }

        private void PDFToolManager_MouseLeftButtonUpHandler(object sender, MouseEventObject e)
        {
            
        }

        private void PDFToolManager_MouseLeftButtonDownHandler(object sender, MouseEventObject e)
        {
            BaseAnnot baseAnnot = PdfViewControl.GetCacheHitTestAnnot();
            if (baseAnnot != null)
            {
                AnnotData annotData = baseAnnot.GetAnnotData();
                AnnotParam annotParam = ParamConverter.CPDFDataConverterToAnnotParam(
                    PdfViewControl.GetCPDFViewer().GetDocument(), annotData.PageIndex, annotData.Annot);
                measurePropertyControl.SetPropertyForMeasureCreate(annotParam, annotData.Annot, PdfViewControl);
                SetMeasureInfoPanel(annotData.Annot, annotParam);
                currentAnnot = annotData.Annot;
            }

            panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
            // measurePropertyControl.SetPropertyForMeasureCreate(LineArgs, e);
            SetInfoPanelVisble(true, false);
        }

        //private void PDFView_AnnotCommandHandler(object sender, AnnotCommandArgs e)
        //{
        //    switch (e.CommandType)
        //    {
        //        case CommandType.Context:
        //            if (e.CommandTarget == TargetType.Annot && e.PressOnAnnot)
        //            {
        //                e.Handle = true;
        //                e.PopupMenu = new ContextMenu();
        //                e.PopupMenu.Items.Add(new MenuItem() { Header = LanguageHelper.CommonManager.GetString("Menu_Delete"), Command = ApplicationCommands.Delete, CommandTarget = (UIElement)sender });
        //                MenuItem menuItem = new MenuItem();
        //                menuItem.Header = "Measurement Settings";
        //                menuItem.Click += (item, param) =>
        //                {
        //                    SettingPanel.UpdateArgsList = e.AnnotEventArgsList;
        //                    SettingPanel.BindMeasureSetting();
        //                    SetInfoPanelVisble(false, true);
        //                };

        //                MenuItem propertyItem = new MenuItem();
        //                propertyItem.Header = "Properties";
        //                propertyItem.Click += (item, param) =>
        //                {
        //                    ExpandEvent?.Invoke(this, new EventArgs());
        //                };
        //                e.PopupMenu.Items.Add(menuItem);
        //                e.PopupMenu.Items.Add(propertyItem);
        //            }
        //            break;

        //        case CommandType.Delete:
        //            e.DoCommand();
        //            break;
        //        default:
        //            break;
        //    }
        //}

        //private void PDFView_AnnotActiveHandler(object sender, AnnotAttribEvent e)
        //{
        //    if (e == null || e.IsAnnotCreateReset)
        //    {
        //        if (e == null)
        //        {
        //            measurePropertyControl?.ClearMeasurePanel();
        //            if(PDFMeasureTool.ToolChecked()==false)
        //            {
        //                SetInfoPanelVisble(false, false);
        //            }
        //        }
        //        return;
        //    }
        //    else
        //    {
        //        switch (e.GetAnnotTypes())
        //        {
        //            case AnnotArgsType.LineMeasure:
        //                LineMeasureArgs LineArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.LineMeasure).First() as LineMeasureArgs;
        //                panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
        //                measurePropertyControl.SetPropertyForMeasureCreate(LineArgs, e);
        //                SetInfoPanelVisble(true, false);
        //                SetMeasureInfoPanel(LineArgs.GetPDFAnnot(), LineArgs);
        //                break;
        //            case AnnotArgsType.PolygonMeasure:
        //                PolygonMeasureArgs polygonArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.PolygonMeasure).First() as PolygonMeasureArgs;
        //                panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
        //                measurePropertyControl.SetPropertyForMeasureCreate(polygonArgs, e);
        //                SetInfoPanelVisble(true, false);
        //                SetMeasureInfoPanel(polygonArgs.GetPDFAnnot(),polygonArgs);
        //                break;

        //            case AnnotArgsType.PolyLineMeasure:
        //                PolyLineMeasureArgs polyLineArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.PolyLineMeasure).First() as PolyLineMeasureArgs;
        //                panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
        //                measurePropertyControl.SetPropertyForMeasureCreate(polyLineArgs, e);
        //                SetInfoPanelVisble(true, false);
        //                SetMeasureInfoPanel(polyLineArgs.GetPDFAnnot(),polyLineArgs);
        //                break;
        //        }
        //    }
        //}

        private void SetMeasureInfoPanel(CPDFAnnotation annot,AnnotParam param = null)
        {
            if (annot == null)
            {
                return;
            }
            try
            {
                if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
                {
                    CPDFLineAnnotation lineAnnot = annot as CPDFLineAnnotation;
                    if (lineAnnot.IsMersured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
                    {
                        InfoPanel.SetMeasureInfo(lineAnnot);
                        SetMeasureInfoType(CPDFMeasureType.CPDF_DISTANCE_MEASURE);
                    }
                }

                if (annot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
                {
                    CPDFPolylineAnnotation polylineAnnot = annot as CPDFPolylineAnnotation;
                    if (polylineAnnot.IsMersured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
                    {
                        InfoPanel.SetMeasureInfo(polylineAnnot);
                        SetMeasureInfoType(CPDFMeasureType.CPDF_PERIMETER_MEASURE);
                    }
                }
                
                if(annot.Type== C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
                {
                    CPDFPolygonAnnotation Annot = annot as CPDFPolygonAnnotation;
                    CPDFAreaMeasure polygonMeasure = Annot.GetAreaMeasure();
                    CPDFMeasureInfo measureInfo = polygonMeasure.MeasureInfo;
                    CPDFCaptionType CaptionType = measureInfo.CaptionType;
                    bool IsArea = false;
                    bool IsLength = false;
                    if ((CaptionType& CPDFCaptionType.CPDF_CAPTION_AREA)== CPDFCaptionType.CPDF_CAPTION_AREA)
                    {
                        IsArea = true;
                    }
                    if ((CaptionType & CPDFCaptionType.CPDF_CAPTION_LENGTH) == CPDFCaptionType.CPDF_CAPTION_LENGTH)
                    {
                        IsLength = true;
                    }
                    SettingPanel.ChangedCheckBoxIsChecked(IsArea, IsLength);
                    InfoPanel.SetMeasureInfo(Annot);
                    SetMeasureInfoType(CPDFMeasureType.CPDF_AREA_MEASURE);
                }
            }
            catch (Exception e)
            {

            }
        }

        private double GetMeasureRatio(string baseUnit)
        {
            if (baseUnit == CPDFMeasure.CPDF_PT)
            {
                return 1 / 72;
            }
            if (baseUnit == CPDFMeasure.CPDF_IN)
            {
                return 1;
            }
            if (baseUnit == CPDFMeasure.CPDF_MM)
            {
                return 1 / 25.4;
            }
            if (baseUnit == CPDFMeasure.CPDF_CM)
            {
                return 1 / 2.54;
            }
            if (baseUnit == CPDFMeasure.CPDF_M)
            {
                return 1 / 0.0254;
            }
            if (baseUnit == CPDFMeasure.CPDFO_KM)
            {
                return 1 / 0.0254 / 1000;
            }

            if (baseUnit == CPDFMeasure.CPDF_FT)
            {
                return 12;
            }
            if (baseUnit == CPDFMeasure.CPDF_YD)
            {
                return 36;
            }
            if (baseUnit == CPDFMeasure.CPDF_MI)
            {
                return 63360;
            }
            return 0;
        }

        public void SetSettingsControl(CPDFDisplaySettingsControl cPDFDisplaySettingsControl)
        {
            displaySettingsControl = cPDFDisplaySettingsControl;
        }

        public void ClearAllToolState()
        {
            PDFMeasureTool.ClearAllToolState();
        }
        public void ClearViewerControl()
        {
            PDFGrid.Child = null;
            BotaContainer.Child = null;
            PropertyContainer.Child = null;
            displaySettingsControl = null;
        }

        private void PanelState_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(PanelState.IsLeftPanelExpand))
            {
                ExpandLeftPanel(panelState.IsLeftPanelExpand);
            }
            else if (e.PropertyName == nameof(PanelState.RightPanel))
            {
                if (panelState.RightPanel == PanelState.RightPanelState.PropertyPanel)
                {
                    ExpandRightPropertyPanel(measurePropertyControl, Visibility.Visible);
                }
                else if (panelState.RightPanel == PanelState.RightPanelState.ViewSettings)
                {
                    ExpandRightPropertyPanel(displaySettingsControl, Visibility.Visible);
                }
                else
                {
                    ExpandRightPropertyPanel(null, Visibility.Collapsed);
                }
            }
        }

        #endregion

        #region Expand and collapse Panel

        public void ExpandRightPropertyPanel(Visibility visible)
        {
            ExpandRightPropertyPanel(measurePropertyControl, visible);
        }

        public void ExpandNullRightPropertyPanel(Visibility visible)
        {
            ExpandRightPropertyPanel(null, visible);
        }

        public void ExpandViewSettings(Visibility visible)
        {
            SetViewSettings(displaySettingsControl, visible);
        }

        private void ExpandRightPropertyPanel(UIElement propertytPanel, Visibility visible)
        {
            PropertyContainer.Width = 260;
            PropertyContainer.Child = propertytPanel;
            PropertyContainer.Visibility = visible;
        }

        private void SetViewSettings(CPDFDisplaySettingsControl displaySettingsControl, Visibility visibility)
        {
            PropertyContainer.Child = displaySettingsControl;
            PropertyContainer.Visibility = visibility;
        }

        public void ExpandLeftPanel(bool isExpand)
        {
            BotaContainer.Visibility = isExpand ? Visibility.Visible : Visibility.Collapsed;
            Splitter.Visibility = isExpand ? Visibility.Visible : Visibility.Collapsed;
            if (isExpand)
            {
                BodyGrid.ColumnDefinitions[0].Width = new GridLength(320);
                BodyGrid.ColumnDefinitions[1].Width = new GridLength(15);
            }
            else
            {
                BodyGrid.ColumnDefinitions[0].Width = new GridLength(0);
                BodyGrid.ColumnDefinitions[1].Width = new GridLength(0);
            }
        }

        #endregion

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void MeasureInfoPanel_SettingClick(object sender, EventArgs e)
        {
            if (sender is MeasureInfoPanel)
            {
                switch ((sender as MeasureInfoPanel).MeasureType)
                {
                    case CPDFMeasureType.CPDF_DISTANCE_MEASURE:
                    case CPDFMeasureType.CPDF_PERIMETER_MEASURE:
                        SettingPanel.ShowAreaAndLength(Visibility.Collapsed);
                        break;
                    case CPDFMeasureType.CPDF_AREA_MEASURE:
                        SettingPanel.ShowAreaAndLength(Visibility.Visible);
                        break;
                    default:
                        break;
                }
            }
            SettingPanel.ReturnToInfoPanel = true;
            SetInfoPanelVisble(false, true);
            AnnotParam annotParam = ParamConverter.CPDFDataConverterToAnnotParam(
                PdfViewControl.GetCPDFViewer().GetDocument(), currentAnnot.Page.PageIndex, currentAnnot);
            SettingPanel.BindMeasureSetting(GetMeasureInfoFromParam(annotParam));
        }

        private CPDFMeasureInfo GetMeasureInfoFromParam(AnnotParam param)
        {
            if(param is LineMeasureParam lineParam)
            {
                return lineParam.measureInfo;
            }
            if (param is PolyLineMeasureParam polyLineParam)
            {
                return polyLineParam.measureInfo;
            }
            if (param is PolygonMeasureParam polygonParam)
            {
                return polygonParam.measureInfo;
            }
            return null;
        }

        private void SettingPanel_CancelEvent(object sender, EventArgs e)
        {
            SetInfoPanelVisble(SettingPanel.ReturnToInfoPanel, false);
        }

        private void SettingPanel_DoneEvent(object sender, EventArgs e)
        {
            SetInfoPanelVisble(SettingPanel.ReturnToInfoPanel, false);
            SettingPanel.SaveMeasureSetting(currentAnnot);
        }

        public void SetInfoPanelVisble(bool measureInfo, bool measureSetting)
        {
            InfoPanel.Visibility = measureInfo ? Visibility.Visible : Visibility.Collapsed;
            SettingPanel.Visibility = measureSetting ? Visibility.Visible : Visibility.Collapsed;
        }

        public void SetMeasureInfoType(CPDFMeasureType measureType)
        {
            InfoPanel?.SetMeasureType(measureType);
        }
        
        public void SetBOTAContainer(CPDFBOTABarControl botaControl)
        {
            this.BotaContainer.Child = botaControl;
        }

        public void SetMeasureScale(CPDFMeasureType measureType, string scale)
        {
            InfoPanel?.SetMeasureScale(measureType,scale);
        }
    }
}