using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using foxit;
using foxit.pdf;
using foxit.addon.xfa;
using foxit.common.fxcrt;
using PDFReader_Demo_CSharp.Common;
using PDFReader_Demo_CSharp.Interface.Windows;

namespace PDFReader_Demo_CSharp.UI
{
    public class XFADocProvider : foxit.addon.xfa.DocProviderCallback
    {
        private WeakReference reader_doc_weakref_ = null;
        private const UInt32 default_hightlight_color_ = 0x50FF0000;


        public XFADocProvider(CPDFReaderDoc pReaderDoc)
        {
            reader_doc_weakref_ = new WeakReference(pReaderDoc);
        }

        CPDFReaderDoc GetDocument()
        {
            return reader_doc_weakref_.IsAlive ? reader_doc_weakref_.Target as CPDFReaderDoc : null;
        }

        public override void DisplayCaret(int page_index, bool is_visible, RectF rect)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            main_form.DisplayCaret(page_index, is_visible, ref rect);
        }

        public override void Dispose()
        {
            base.Dispose();
        }

        public override void ExportData(XFADoc doc, string file_path)
        {

        }

        public override int GetCurrentPage(XFADoc doc)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return -1;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return -1;

            return main_form.GetCurPageIndex();
        }

        public override uint GetHighlightColor(XFADoc doc)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return 0;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return 0;

            return default_hightlight_color_;
        }

        public override bool GetPopupPos(int page_index, float min_popup, float max_popup, RectF rect_widget, RectF inout_rect_popup)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return false;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null || main_form.Viewer == null)
                return false;

            Control view_control = main_form.Viewer as Control;
            if (view_control == null)
                return false;

            Rectangle client_rect = main_form.Viewer.GetPageRect();

            foxit.common.fxcrt.RectF new_rect = new RectF();
            main_form.Viewer.WindowToDoc(page_index, client_rect, ref new_rect);

            int top_length = 0;
            int bottom_length = 0;
            int actaul_length = 0;
            float fPoupHeight = 0;
            bool show_upside = true;
            top_length = (int)(new_rect.top - rect_widget.top);
            bottom_length = (int)(rect_widget.bottom - new_rect.bottom);
            if (rect_widget.right > new_rect.right)
            {
                inout_rect_popup.left -= rect_widget.right - new_rect.right;
                inout_rect_popup.right -= rect_widget.right - new_rect.right;
            }
            if (top_length <= 0 && bottom_length <= 0)
            {
                return false;
            }
            if (top_length <= 0)
            {
                actaul_length = bottom_length;
            }
            else if (bottom_length <= 0)
            {
                actaul_length = top_length;
                show_upside = false;
            }
            else if (top_length > bottom_length)
            {
                actaul_length = top_length;
                show_upside = false;
            }
            else
            {
                actaul_length = bottom_length;
            }

            if (actaul_length < min_popup)
            {
                fPoupHeight = min_popup;
            }
            else if (actaul_length > max_popup)
            {
                fPoupHeight = max_popup;
            }
            else
            {
                fPoupHeight = actaul_length;
            }
            if (!show_upside)
            {
                inout_rect_popup.top = Math.Abs(rect_widget.bottom - rect_widget.top);
                inout_rect_popup.bottom = inout_rect_popup.top + fPoupHeight;
            }
            else
            {
                inout_rect_popup.top = -fPoupHeight;
                inout_rect_popup.bottom = inout_rect_popup.top + fPoupHeight;
            }
            return true;

        }

        public override string GetTitle(XFADoc doc)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return "";
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return "";

            return "XFA Title";
        }

        public override void GotoURL(XFADoc doc, string url)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            WindowsAPI.ShellExecute(main_form.Handle, "Open", url, null, null, WindowsAPI.ShowCommands.SW_SHOW);
        }

        public override void ImportData(XFADoc doc, string file_path)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

        }

        public override void InvalidateRect(int page_index, RectF rect, DocProviderCallback.InvalidateFlag flag)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            main_form.ReDraw();
        }

        public override void PageViewEvent(int page_index, DocProviderCallback.PageViewEventType page_view_event_type)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
            reader_doc.UpdatePDFPages((int)graphics.DpiX, (int)graphics.DpiY, main_form.GetRotate(), true);
            main_form.UpdatePageSize();
        }

        public override bool PopupMenu(int page_index, foxit.common.fxcrt.PointF rect_popup)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return false;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null || main_form.Viewer == null)
                return false;

            System.Drawing.Point point = new System.Drawing.Point();
            main_form.Viewer.DocToWindow(page_index, rect_popup, ref point);

            main_form.ShowXfaPopup(point);

            return false;
        }

        public override void Print(XFADoc doc, int start_page_index, int end_page_index, int options)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            main_form.OnPrint(start_page_index, end_page_index, options);
        }

        public override void Release()
        {

        }

        public override void SetCurrentPage(XFADoc doc, int current_page_index)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            main_form.GoToPage(current_page_index);
            main_form.UpdateCurPage(current_page_index);
        }

        public override void SetFocus(XFAWidget xfa_widget, bool is_relayout)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;

            main_form.SetFocusXFAWidget(xfa_widget);
        }

        public override bool SubmitData(XFADoc doc, string target, DocProviderCallback.SubmitFormat format, DocProviderCallback.TextEncoding text_encoding, string content)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return false;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return false;

            MessageBox.Show("The target is : \n" + target);

            return true;
        }

        public override void SetChangeMark(XFADoc doc) {
        }

        public override void WidgetEvent(XFAWidget xfa_widget, WidgetEventType widget_event_type)
        {
            CPDFReaderDoc reader_doc = GetDocument();
            if (reader_doc == null)
                return;
            MainForm main_form = reader_doc.GetView();
            if (main_form == null)
                return;
            if (widget_event_type == foxit.addon.xfa.DocProviderCallback.WidgetEventType.e_WidgetEventTypeBeforeRemoved)
            {
                XFAWidget focuswidget = main_form.GetFocusXFAWidget();
                if (focuswidget == null || xfa_widget.GetIndex() == focuswidget.GetIndex())
                {
                    main_form.SetFocusXFAWidget(null);
                }

                XFAWidget hoverwidget = main_form.GetHoverXFAWidget();
                if (hoverwidget == null || xfa_widget.GetIndex() == hoverwidget.GetIndex())
                {
                    main_form.SetHoverXFAWidget(null);
                }
            }
            return;
        }

        public override void NotifyWidgetChangeInfo(XFADoc doc, XFAWidgetModifyInfo change_info)
        {
        }
    }
}