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 System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using foxit;
using foxit.pdf;
using foxit.addon.xfa;
using PDFReader_Demo_CSharp.Interface.Windows;
using PDFReader_Demo_CSharp.Common;


namespace PDFReader_Demo_CSharp.UI
{
    public struct CharRangeInfo
    {
        public int page_index;
        public int start_char_index;
        public int end_char_index;
    }

    public struct XFA_CARETINFO
    {
        public XFA_CARETINFO(int new_page_index)
        {
            is_visible = false;
            page_index = new_page_index;
            is_horizonal = false;
            anchor_rect = null;
        }

        public int page_index;
        public bool is_visible;
        public foxit.common.fxcrt.RectF anchor_rect;
        public bool is_horizonal;
    };

    public partial class MainForm : Form
    {       
        private const int recentfile_count_in_menu_ = 4;
        private List<string> recentfile_path_list_ = null;

        private bool is_first_load_ = true;
        private float dpi_x_ = 0.0f;
        private float dpi_y_ = 0.0f;

        private string file_name_ = String.Empty;
        private string password_ = String.Empty;

        public CPDFReaderDoc reader_doc_ = null;

        private int current_page_index_ = 0;
        private string select_text_string_ = null;
        internal SearchContext search_context_ = null;

        private foxit.common.Rotation page_rotation_ = 0;
        private float zoom_factor_ = 1.0f;

        public string search_text_string_ = "";
        private SearchDlg search_dlg_ = null;

        private System.Windows.Forms.ToolStripMenuItem documentToolstripMenuitem = null;
        private System.Windows.Forms.ToolStripMenuItem maintool_toolstrip_menuitem_ = null;
        private System.Windows.Forms.ToolStripMenuItem annot_toolstrip_menuitem_ = null;

        private foxit.pdf.interform.TimerCallback timer_ = null;

        XFA_CARETINFO xfa_caret_info_;

        XFAWidget focus_xfa_widget_;
        XFAWidget hover_xfa_widget_;
        string copy_or_cut_string_ = "";

        DocumentPropertyDlg document_property_dlg_ = null;

        IConpomentViewControl view_control_ = null;

        ContextMenuStrip xfa_context_menustrip_ = null;

        ContextMenuStrip formfiller_menu_strip_ = null;

        public enum OperatorType
        {
            UNKNOWN = 0,
            DRAWINGANNOT,
            HAND,
            TEXTPAGE,
            TEXTSEARCH,
            DRAWINGPSI,
            ANNOTSELECT,
            AUTOSCROLL,
        };

#region UTIL
        private void ReleasePageResource(bool is_page = true)
        {
        }

        public void DisplayCaret(int page_index, bool is_visible, ref foxit.common.fxcrt.RectF anchor_rect)
        {
            xfa_caret_info_.is_visible = is_visible;
            Control temp_control = view_control_ as Control;
            if (temp_control == null)
                return;

            if (is_visible)
            {
                xfa_caret_info_.anchor_rect = anchor_rect;
                xfa_caret_info_.page_index = page_index;

                Rectangle caret_rect = new Rectangle();
                this.view_control_.DocToWindow(page_index, anchor_rect, ref caret_rect);
                WindowsAPI.DestroyCaret();
                WindowsAPI.CreateCaret(temp_control.Handle, (IntPtr)0, 0, (int)caret_rect.Height);
                WindowsAPI.SetCaretPos(caret_rect.Left, caret_rect.Top);
                WindowsAPI.ShowCaret(temp_control.Handle);
            }
            else
            {
                WindowsAPI.DestroyCaret();
                WindowsAPI.HideCaret(temp_control.Handle);
            }
        }

        public void GoToPage(int page_index)
        {
            int page_count = reader_doc_.GetPageCount();
            if (page_index < 0)
            {
                page_index = 0;
            }
            if (page_index > page_count)
            {
                page_index = page_count - 1;
            }

            current_page_index_ = page_index;
            view_control_.GoToPage(page_index);

            if (current_page_index_ > 0)
            {
                nextPageToolStripButton.Enabled = true;
                prePageToolStripButton.Enabled = true;
                if (current_page_index_ == reader_doc_.GetPageCount() - 1)
                {
                    nextPageToolStripButton.Enabled = false;
                }
            }
            else if (current_page_index_ == 0)
            {
                prePageToolStripButton.Enabled = false;
                nextPageToolStripButton.Enabled = true;
                if (current_page_index_ == reader_doc_.GetPageCount() - 1)
                {
                    nextPageToolStripButton.Enabled = false;
                }
            }
        }

        public int GetCurPageIndex()
        {
            if (view_control_.IsVisiblePage(current_page_index_))
            {

            }
            return current_page_index_;
        }

        public void ReDraw()
        {
            Control temp_control = view_control_ as Control;
            if (temp_control != null)
                temp_control.Invalidate();
        }

        private void CloseProgram()
        {
            WriteFilePathToIni();
        }

        private void EnableButton(bool is_enable)
        {
            this.closeToolStripMenuItem.Enabled = is_enable;
            this.handToolStripButton.Enabled = is_enable;
            this.zoomInToolStripButton.Enabled = is_enable;
            this.zoomOutToolStripButton.Enabled = is_enable;
            this.rotateLeftToolStripButton.Enabled = is_enable;
            this.rotateRightToolStripButton.Enabled = is_enable;
            this.searchToolStripButton.Enabled = is_enable;
            this.selectToolStripButton.Enabled = is_enable;
        }

        public CPDFReaderDoc GetCurDocument()
        {
            return reader_doc_;
        }

        public IConpomentViewControl Viewer
        {
            get
            {
                return view_control_;
            }
        }

        public foxit.common.Rotation GetRotate()
        {
            return page_rotation_;
        }

        public float GetScale()
        {
            return zoom_factor_;
        }

        public void UpdateCurPage(int page_index)
        {
            current_page_index_ = page_index;
        }

        public void SetFocusXFAWidget(XFAWidget xfa_widget)
        {
            focus_xfa_widget_ = xfa_widget;
            if (view_control_ != null)
                view_control_.SetFocusXFAWidget(xfa_widget);
        }

        public XFAWidget GetFocusXFAWidget()
        {
            if (view_control_ != null)
                focus_xfa_widget_ = view_control_.GetFocusXFAWidget();

            return focus_xfa_widget_;
        }

        public void SetHoverXFAWidget(XFAWidget xfa_widget)
        {
            hover_xfa_widget_ = xfa_widget;
            if (view_control_ != null)
                view_control_.SetHoverXFAWidget(xfa_widget);
        }

        public XFAWidget GetHoverXFAWidget()
        {
            if (view_control_ != null)
                hover_xfa_widget_ = view_control_.GetHoverXFAWidget();

            return hover_xfa_widget_;
        }
        #endregion

        #region UI
        public MainForm()
        {
            InitializeComponent();

            Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
            dpi_x_ = graphics.DpiX;
            dpi_y_ = graphics.DpiY;

            current_operator_type_ = OperatorType.HAND;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            recentfile_path_list_ = new List<string>();

            ShowRecentFileInMenu();

            this.toolToolStripMenuItem.Click += new EventHandler(MainForm_Resize);
            this.statusBarToolStripMenuItem.Click += new EventHandler(MainForm_Resize);

            this.viewControlPanel.Scroll += new ScrollEventHandler(panel_Scroll);
            this.Activated += new EventHandler(MainForm_Activated);

            GetFocus(Controls);

            is_first_load_ = false;
        }

        void AddDocuemntMenu()
        {
            ToolStripItemCollection menuItems = menuStripMain.Items;

            if (documentToolstripMenuitem == null || !menuItems.Contains(documentToolstripMenuitem))
                documentToolstripMenuitem = AddMainMenuContextMenu("Document", menuItems, null);

            maintool_toolstrip_menuitem_ = new ToolStripMenuItem("Tool");
            annot_toolstrip_menuitem_ = new ToolStripMenuItem("Annot");

            //Add document menu 
            AddContextMenu("Property", documentToolstripMenuitem.DropDownItems, new EventHandler(DocumentPropertyMenuClicked));
        }

        void RemoveDocumentMenu()
        {
            ToolStripItemCollection menuItems = menuStripMain.Items;
            if (menuItems.Contains(documentToolstripMenuitem))
            {
                menuItems.Remove(documentToolstripMenuitem);
            }
        }

        ToolStripMenuItem AddMainMenuContextMenu(string text, ToolStripItemCollection cms, EventHandler callback)
        {
            if (text == "-")
            {
                ToolStripSeparator tsp = new ToolStripSeparator();
                cms.Add(tsp);
                return null;
            }
            else if (!string.IsNullOrEmpty(text))
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(text);
                tsmi.Tag = text + "TAG";
                tsmi.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                if (callback != null)
                    tsmi.Click += callback;
                cms.Insert(cms.Count - 1, tsmi);

                return tsmi;
            }

            return null;
        }

        ToolStripMenuItem AddContextMenu(string text, ToolStripItemCollection cms, EventHandler callback)
        {
            if (text == "-")
            {
                ToolStripSeparator tsp = new ToolStripSeparator();
                cms.Add(tsp);
                return null;
            }
            else if (!string.IsNullOrEmpty(text))
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(text);
                tsmi.Tag = text + "TAG";
                if (callback != null)
                    tsmi.Click += callback;
                cms.Add(tsmi);

                return tsmi;
            }

            return null;
        }

        public void ShowTextPopup(Control control)
        {
            if (control == null)
                return;

            control.ContextMenuStrip = contextMenuStrip1;
        }

        void DocumentPropertyMenuClicked(object sender, EventArgs e)
        {
            if (reader_doc_ == null)
                return;

            if (document_property_dlg_ == null)
                document_property_dlg_ = new DocumentPropertyDlg(this);

            document_property_dlg_.ShowDialog(this);

            document_property_dlg_ = null;
        }

        void panel_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
            {
                
            }

            if (e.ScrollOrientation == ScrollOrientation.VerticalScroll)
            {
                
            }
        }

        void MainForm_Activated(object sender, EventArgs e)
        {
        }

        void GetFocus(Control.ControlCollection cs)
        {
            foreach (Control c in cs)
            {
                c.MouseHover +=new EventHandler(c_MouseHover); 
                GetFocus(c.Controls);
            }
        }

        void  c_MouseHover(object sender, EventArgs e)
        {
            this.Activate();
        }

        private const int WM_NCMOUSEMOVE = 0x00A0;
        private const int WM_MOUSEMOVE = 0x0200;

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
        }

        private OperatorType current_operator_type_;

        public void SetOperatorType(OperatorType operatorType)
        {
            current_operator_type_ = operatorType;
        }

        public OperatorType GetOperatorType()
        {
            return current_operator_type_;
        }

        public bool IsHandTool()
        {
            return current_operator_type_ == OperatorType.HAND;
        }

        public bool IsTextTool()
        {
            return current_operator_type_ == OperatorType.TEXTPAGE;
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.openPDFFileDialog.FileName = "";
            this.openPDFFileDialog.Filter = "*.pdf|*.pdf";
            this.openPDFFileDialog.ShowDialog(this);
            OpenPDFFile(this.openPDFFileDialog.FileName);
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            this.openPDFFileDialog.FileName = "";
            this.openPDFFileDialog.Filter = "*.pdf|*.pdf";
            this.openPDFFileDialog.ShowDialog(this);
            OpenPDFFile(this.openPDFFileDialog.FileName);
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseDocumentAndFile();
            this.closeToolStripMenuItem.Enabled = false;
        }

        private void prePageToolStripButton_Click(object sender, EventArgs e)
        {
            current_page_index_--;
            ReleasePageResource();

            GoToPage(current_page_index_);
        }

        private void nextPageToolStripButton_Click(object sender, EventArgs e)
        {
            current_page_index_++;
            ReleasePageResource();

            GoToPage(current_page_index_);
        }

        private void zoomInToolStripButton_Click(object sender, EventArgs e)
        {
            zoomIn();
        }

        private void zoomOutToolStripButton_Click(object sender, EventArgs e)
        {
            zoomOut();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult.OK == MessageBox.Show("The application will be closed, whether to continue?", "", MessageBoxButtons.OKCancel))
            {
                CloseDocumentAndFile();
                CloseProgram();
            }
            else
                e.Cancel = true;
        }

        private void toolToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem tool_check_menuitem = sender as ToolStripMenuItem;
            if (tool_check_menuitem.Checked == false)
            {
                this.toolStripMain.Visible = false;
            }
            else
                this.toolStripMain.Visible = true;
        }

        private void statusBarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem statusbar_check_menuitem = sender as ToolStripMenuItem;
            if (statusbar_check_menuitem.Checked == false)
            {
                this.statusStripMain.Visible = false;
            }
            else
                this.statusStripMain.Visible = true;
        }

        private void aboutPDFReaderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutCSharpPDFReader aboutCSharpPDFReader = new AboutCSharpPDFReader();
            aboutCSharpPDFReader.TopMost = true;
            aboutCSharpPDFReader.Show();
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            int menu_height = menuStripMain.Height;
            if (menuStripMain.Visible == false && is_first_load_ == false)
                menu_height = 0;

            int tool_height = toolStripMain.Height;
            if (toolStripMain.Visible == false && is_first_load_ == false)
                tool_height = 0;

            int statusbar_height = statusStripMain.Height;
            if (statusStripMain.Visible == false && is_first_load_ == false)
                statusbar_height = 0;

            this.viewControlPanel.Left = 0;
            this.viewControlPanel.Top = menu_height + tool_height;
            this.viewControlPanel.Width = this.ClientSize.Width;
            this.viewControlPanel.Height = this.ClientSize.Height - (tool_height + menu_height + statusbar_height);

            UpdatePageSize();
        }

        public void UpdatePageSize()
        {
            if (view_control_ == null)
                return;

            view_control_.UpdateControlSize();
        }

        private void panel_Paint(object sender, PaintEventArgs e)
        {
            int menu_height = menuStripMain.Height;
            if (menuStripMain.Visible == false && is_first_load_ == false)
                menu_height = 0;

            int tool_height = toolStripMain.Height;
            if (toolStripMain.Visible == false && is_first_load_ == false)
                tool_height = 0;

            int statusbar_height = statusStripMain.Height;
            if (statusStripMain.Visible == false && is_first_load_ == false)
                statusbar_height = 0;

            this.viewControlPanel.Left = 0;
            this.viewControlPanel.Top = menu_height + tool_height;
            this.viewControlPanel.Width = this.ClientSize.Width;
            this.viewControlPanel.Height = this.ClientSize.Height - (tool_height + menu_height + statusbar_height);
        }

        private void zoomOut()
        {
            float previous_zoom_factor = zoom_factor_;
            zoom_factor_ -= 0.1f;
            if (zoom_factor_ < 0.3f)
            {
                zoom_factor_ = 0.3f;
                if (zoom_factor_ == previous_zoom_factor)
                    return;
            }

            if (view_control_ != null)
                view_control_.SetScale(zoom_factor_);
        }

        private void zoomIn()
        {
            float previous_zoom_factor = zoom_factor_;
            zoom_factor_ += 0.1f;
            if (zoom_factor_ >= 7.0f)
            {
                zoom_factor_ = 7.0f;
                if (zoom_factor_ == previous_zoom_factor)
                    return;
            }

            if (view_control_ != null)
                view_control_.SetScale(zoom_factor_);
        }

        private void rotateRightToolStripButton_Click(object sender, EventArgs e)
        {
            page_rotation_ = (page_rotation_ == foxit.common.Rotation.e_Rotation270 ? 0 : (page_rotation_ + 1));
            reader_doc_.UpdatePDFPages((int)dpi_x_, (int)dpi_y_, page_rotation_, true);

            if (view_control_ != null)
                view_control_.SetRotate(page_rotation_);
        }

        private void rotateLeftToolStripButton_Click(object sender, EventArgs e)
        {
            page_rotation_ = (page_rotation_ == foxit.common.Rotation.e_Rotation0 ? foxit.common.Rotation.e_Rotation270 : (page_rotation_ - 1));
            reader_doc_.UpdatePDFPages((int)dpi_x_, (int)dpi_y_, page_rotation_, true);

            if (view_control_ != null)
                view_control_.SetRotate(page_rotation_);
        }

        void viewControl_MouseMove(object sender, MouseEventArgs e)
        {
            Control temp_control = view_control_ as Control;
            if (temp_control != null)
                temp_control.Cursor = IsTextTool() ? Cursors.IBeam : Cursors.Hand;
        }

        private void searchToolStripButton_Click(object sender, EventArgs e)
        {
            EnableButon(false);
            SetOperatorType(OperatorType.TEXTSEARCH);

            search_dlg_ = new SearchDlg(this);
            search_dlg_.Show();
        }

        public void EnableButon(bool enable)
        {
            this.searchToolStripButton.Enabled = enable;

            this.fileToolStripMenuItem.Enabled = enable;
            this.documentToolstripMenuitem.Enabled = enable;
            this.helpToolStripMenuItem.Enabled = enable;

            this.openToolStripButton.Enabled = enable;
            this.handToolStripButton.Enabled = enable;
            this.selectToolStripButton.Enabled = enable;
            this.annot_toolstrip_menuitem_.Enabled = enable;
            this.zoomOutToolStripButton.Enabled = enable;
            this.zoomInToolStripButton.Enabled = enable;
            this.rotateLeftToolStripButton.Enabled = enable;
            this.rotateRightToolStripButton.Enabled = enable;
            this.viewToolStripMenuItem.Enabled = enable;
            this.toolToolStripMenuItem.Enabled = enable;
        }

        private void selectToolStripButton_Click(object sender, EventArgs e)
        {
            viewControlPanel.Cursor = Cursors.IBeam;

            SetOperatorType(OperatorType.TEXTPAGE);
        }

        private void handToolStripButton_Click(object sender, EventArgs e)
        {
            viewControlPanel.Cursor = Cursors.Hand;

            SetOperatorType(OperatorType.HAND);
            EnableButon(true);
            
            WindowsAPI.HideCaret(viewControlPanel.Handle);
        }

        private void recentFileMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem recent_file_menuitem = sender as ToolStripMenuItem;
            if (!File.Exists(recent_file_menuitem.Text))
            {
                MessageBox.Show("File " + recent_file_menuitem.Text + " is not exist!");
                RemoveFilePathToRecentMenu(recent_file_menuitem.Text);
                return;
            }
            if (!OpenPDFFile(recent_file_menuitem.Text))
            {
                RemoveFilePathToRecentMenu(recent_file_menuitem.Text);
            }
        }

        public void OnPrint(int start_page_index, int end_page_index, int options)
        {

        }
#endregion

#region Xfa
        ToolStripMenuItem CreateXfaTextStyleMenu()
        {
            ToolStripMenuItem strip_menuitem = new ToolStripMenuItem();

            var menu_text_style_items = new System.Windows.Forms.ToolStripItem[6];
            ToolStripMenuItem text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Bold";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaBold);
            menu_text_style_items[0] = text_strip_menuitem;

            text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Italic";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaItalic);
            menu_text_style_items[1] = text_strip_menuitem;

            text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Underline";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaUnderLine);
            menu_text_style_items[2] = text_strip_menuitem;

            text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Superscript";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaSuperScript);
            menu_text_style_items[3] = text_strip_menuitem;

            text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Subscript";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaSubScript);
            menu_text_style_items[4] = text_strip_menuitem;

            text_strip_menuitem = new ToolStripMenuItem();
            text_strip_menuitem.Name = "cutToolStripMenuItem";
            text_strip_menuitem.Size = new System.Drawing.Size(106, 22);
            text_strip_menuitem.Text = "Clear Style";
            text_strip_menuitem.Click += new System.EventHandler(this.OnXfaClearStyle);
            menu_text_style_items[5] = text_strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Text Style";
            strip_menuitem.DropDownItems.AddRange(menu_text_style_items);

            return strip_menuitem;
        }

        public ContextMenuStrip CreateXfaMenu()
        {
            var menu_items = new System.Windows.Forms.ToolStripItem[9];

            ToolStripMenuItem strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Cut";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaCut);
            menu_items[0] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Copy";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaCopy);
            menu_items[1] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Paste";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaPaste);
            menu_items[2] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Delete";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaDelete);
            menu_items[3] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "SelectAll";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaSelectAll);
            menu_items[4] = strip_menuitem;

            menu_items[5] = CreateXfaTextStyleMenu();

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "DeSelect";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaDeSelect);
            menu_items[6] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Undo";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaUndo);
            menu_items[7] = strip_menuitem;

            strip_menuitem = new ToolStripMenuItem();
            strip_menuitem.Name = "cutToolStripMenuItem";
            strip_menuitem.Size = new System.Drawing.Size(106, 22);
            strip_menuitem.Text = "Redo";
            strip_menuitem.Click += new System.EventHandler(this.OnXfaRedo);
            menu_items[8] = strip_menuitem;

            ContextMenuStrip xfa_menu_strip = new ContextMenuStrip();
            xfa_menu_strip.Items.AddRange(menu_items);

            return xfa_menu_strip;
        }

        public ContextMenuStrip CreateFormFillerMenu() {
            formfiller_menu_strip_ = new ContextMenuStrip();
            return formfiller_menu_strip_;
        }

        public void ShowFormFillerPopup(IntPtr menu_handle, System.Drawing.Point pt)
        {
            formfiller_menu_strip_ = (ContextMenuStrip)ContextMenuStrip.FromHandle(menu_handle);
            formfiller_menu_strip_.Show(this, pt);
        }

        public void ShowXfaPopup(System.Drawing.Point pt)
        {
            if (xfa_context_menustrip_ == null)
                xfa_context_menustrip_ = CreateXfaMenu();

            xfa_context_menustrip_.Show(this, pt);
        }

        void OnXfaCut(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            if (!xfa_menu.IsEmpty() && xfa_menu.CanCut())
                copy_or_cut_string_ = xfa_menu.Cut();
        }

        void OnXfaCopy(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            if (!xfa_menu.IsEmpty() && xfa_menu.CanCopy())
                copy_or_cut_string_ = xfa_menu.Copy();
        }

        void OnXfaDelete(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.Delete();
        }

        void OnXfaSelectAll(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.SelectAll();
        }

        void OnXfaDeSelect(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            if (xfa_menu.CanDeSelect())
                xfa_menu.DeSelect();
        }

        void OnXfaRedo(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            if (xfa_menu.CanRedo())
                xfa_menu.Redo();
        }

        void OnXfaUndo(object sender, EventArgs e)
        {
            WidgetMenu xfaMenu = new WidgetMenu(focus_xfa_widget_);
            if (xfaMenu.CanUndo())
                xfaMenu.Undo();
        }

        void OnXfaPaste(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            if (copy_or_cut_string_.Length > 0)
                xfa_menu.Paste(copy_or_cut_string_);
        }

        void OnXfaBold(object sender, EventArgs e)
        {
            WidgetMenu xfaMenu = new WidgetMenu(focus_xfa_widget_);
            xfaMenu.Bold();
        }

        void OnXfaItalic(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.Italic();
        }

        void OnXfaUnderLine(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.Underline();
        }

        void OnXfaSuperScript(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.Superscript();
        }

        void OnXfaSubScript(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.Subscript();
        }

        void OnXfaClearStyle(object sender, EventArgs e)
        {
            WidgetMenu xfa_menu = new WidgetMenu(focus_xfa_widget_);
            xfa_menu.ClearStyle();
        }
#endregion

#region File Opeartion
        //for first load
        private void ShowRecentFileInMenu()
        {
            int index = this.fileToolStripMenuItem.DropDownItems.Count - 1;

            FileStream file_stream = new FileStream("../../../PDFFileName.ini", FileMode.OpenOrCreate);
            File.SetAttributes("../../../PDFFileName.ini", FileAttributes.Hidden);
            StreamReader stream_reader = new StreamReader(file_stream);

            if (stream_reader.Peek() >= 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    ToolStripSeparator separator_menuitem = new ToolStripSeparator();
                    this.fileToolStripMenuItem.DropDownItems.Insert(index, separator_menuitem);
                }
            }

            while (stream_reader.Peek() >= 0)
            {
                recentfile_path_list_.Add(stream_reader.ReadLine());
            }
            stream_reader.Close();

            index = this.fileToolStripMenuItem.DropDownItems.Count - 2;
            int count = recentfile_path_list_.Count;
            if (count > recentfile_count_in_menu_)
                count = recentfile_count_in_menu_;

            for (int i = 0; i < count; i++)
            {
                ToolStripMenuItem recent_file_menuitem = new ToolStripMenuItem(recentfile_path_list_[i]);
                this.fileToolStripMenuItem.DropDownItems.Insert(index, recent_file_menuitem);
                index++;
                recent_file_menuitem.Click += new EventHandler(recentFileMenuItem_Click);
            }
        }

        private void SetFilePathToRecentMenu(string file_path)
        {
            if (file_path == String.Empty) return;

            int index = 0;
            if (3 == this.fileToolStripMenuItem.DropDownItems.Count)
            {
                index = this.fileToolStripMenuItem.DropDownItems.Count - 1;
                for (int i = 0; i < 2; i++)
                {
                    ToolStripSeparator separator_menuitem = new ToolStripSeparator();
                    this.fileToolStripMenuItem.DropDownItems.Insert(index, separator_menuitem);
                }
            }

            index = this.fileToolStripMenuItem.DropDownItems.Count - 3;

            for (int i = index; i > 0; i--)
            {
                if (this.fileToolStripMenuItem.DropDownItems[i].GetType().Name.Equals("ToolStripSeparator"))
                    break;
                this.fileToolStripMenuItem.DropDownItems.RemoveAt(i);
            }

            for (int i = recentfile_path_list_.Count - 1; i >= 0; i--)
            {
                if (file_path.Equals(recentfile_path_list_[i]))
                    recentfile_path_list_.RemoveAt(i);
            }

            if (File.Exists(file_path))
            {
                if (recentfile_path_list_.Count == recentfile_count_in_menu_)
                {
                    recentfile_path_list_.RemoveAt(recentfile_path_list_.Count - 1);
                }
                recentfile_path_list_.Insert(0, file_path);
            }
            else
                MessageBox.Show("File is not exist!");

            int count = recentfile_path_list_.Count;
            if (recentfile_path_list_.Count >= recentfile_count_in_menu_)
                count = recentfile_count_in_menu_;

            index = this.fileToolStripMenuItem.DropDownItems.Count - 2;
            for (int i = 0; i < count; i++)
            {
                ToolStripMenuItem recent_file_menuitem = new ToolStripMenuItem(recentfile_path_list_[i]);
                this.fileToolStripMenuItem.DropDownItems.Insert(index + i, recent_file_menuitem);
                recent_file_menuitem.Click += new EventHandler(recentFileMenuItem_Click);
            }
        }

        private void RemoveFilePathToRecentMenu(string file_path)
        {
            if (file_path == String.Empty) return;

            int index = this.fileToolStripMenuItem.DropDownItems.Count - 3;

            for (int i = index; i > 0; i--)
            {
                if (this.fileToolStripMenuItem.DropDownItems[i].GetType().Name.Equals("ToolStripSeparator"))
                    break;
                this.fileToolStripMenuItem.DropDownItems.RemoveAt(i);
            }

            for (int i = recentfile_path_list_.Count - 1; i >= 0; i--)
            {
                if (file_path.Equals(recentfile_path_list_[i]))
                {
                    recentfile_path_list_.RemoveAt(i);
                    break;
                }
            }

            int count = recentfile_path_list_.Count;
            if (recentfile_path_list_.Count >= recentfile_count_in_menu_)
                count = recentfile_count_in_menu_;

            index = this.fileToolStripMenuItem.DropDownItems.Count - 2;
            for (int i = 0; i < count; i++)
            {
                ToolStripMenuItem recent_file_menuitem = new ToolStripMenuItem(recentfile_path_list_[i]);
                this.fileToolStripMenuItem.DropDownItems.Insert(index + i, recent_file_menuitem);
                recent_file_menuitem.Click += new EventHandler(recentFileMenuItem_Click);
            }
        }

        private bool OpenPDFFile(string pdf_file_name)
        {
            if (pdf_file_name == String.Empty || (pdf_file_name.Equals(file_name_) && reader_doc_ != null))
                return true;

            viewControlPanel.AutoScrollPosition = new System.Drawing.Point(0, 0);

            if (reader_doc_ != null)
                CloseDocumentAndFile();

            reader_doc_ = new CPDFReaderDoc();
            bool is_ok = reader_doc_.LoadPDFDocument(pdf_file_name);
            if (!is_ok)
            {
                ClosePDFFile();
                return false;
            }

            reader_doc_.SetPageView(this);
            reader_doc_.UpdatePDFPages((int)dpi_x_, (int)dpi_y_, page_rotation_, false);

            file_name_ = pdf_file_name;
            SetFilePathToRecentMenu(pdf_file_name);

            int page_count = reader_doc_.GetPageCount();
            if (current_page_index_ < page_count - 1)
            {
                this.nextPageToolStripButton.Enabled = true;
            }

            int reader_doc_real_width = (int)reader_doc_.GetRealWidth(zoom_factor_);
            int reader_doc_real_height = (int)reader_doc_.GetRealHeight(zoom_factor_);

            ContinuePageViewControl view_control = new ContinuePageViewControl();
            view_control.SetView(reader_doc_);
            view_control.MouseMove += new MouseEventHandler(viewControl_MouseMove);
            view_control_ = view_control;
            this.viewControlPanel.Controls.Add(view_control);
            view_control.UpdateControlSize();
            view_control.Focus();
            
            search_context_ = new SearchContext(reader_doc_);
            search_context_.SearchResult += new EventHandler<SearchEventArgs>(searchContext_SearchResult);

            EnableButton(true);

            AddDocuemntMenu();

            return true;
        }

        private bool CloseDocumentAndFile()
        {
            //WindowsAPI.HideCaret(pb.Handle);
            zoom_factor_ = 1.0f;

            search_context_ = null;
            if (search_dlg_ != null)
            {
                search_dlg_.Close();
                search_dlg_ = null;
            }

            EnableButton(false);
            this.closeToolStripMenuItem.Enabled = false;
            this.prePageToolStripButton.Enabled = false;
            this.nextPageToolStripButton.Enabled = false;

            ReleasePageResource();
            RemoveDocumentMenu();

            ClosePDFFile();

            current_page_index_ = 0;
            return true;
        }

        private void ClosePDFFile()
        {
            if (view_control_ != null)
            {
                view_control_.Release();
                Control temp_control = view_control_ as Control;
                if (temp_control != null)
                    this.viewControlPanel.Controls.Remove(temp_control);
                view_control_ = null;
            }

            if (reader_doc_ != null)
            {
                reader_doc_.Dispose();
                reader_doc_ = null;
            }
        }

        private void WriteFilePathToIni()
        {
            int count = recentfile_path_list_.Count;
            if (recentfile_path_list_.Count > recentfile_count_in_menu_)
                count = recentfile_count_in_menu_;

            string file_path = "";
            for (int j = 0; j < count; j++)
                file_path += recentfile_path_list_[j] + "\n";

            FileStream file_stream = new FileStream("../../../PDFFileName.ini", FileMode.OpenOrCreate);
            File.SetAttributes("../../../PDFFileName.ini", FileAttributes.Hidden);

            StreamWriter stream_writer = new StreamWriter(file_stream);

            stream_writer.Write(file_path);
            stream_writer.Flush();
            stream_writer.Close();
        }
#endregion

#region Text Search
        public void SearchText(string string_to_find, bool is_match_case_sensitive, bool is_match_whole_word, int direction)
        {
            if (null == reader_doc_ || null == search_context_)
                return;

            search_context_.StartSearch(GetCurPageIndex(), string_to_find, is_match_case_sensitive, is_match_whole_word, direction);
        }

        public void StopSearch()
        {
            if (null == reader_doc_ || null == search_context_)
                return;

            if (search_context_.IsSearching)
            {
                search_context_.StopSearch();
            }
        }

        public bool IsInSearching()
        {
            return search_context_ != null ? search_context_.IsSearching : false;
        }

        foxit.common.fxcrt.RectF[] GetSearchTextRect(TextSearch text_search)
        {
            foxit.common.fxcrt.RectFArray match_rect_array = text_search.GetMatchRects();
            int rect_count = match_rect_array.GetSize();

            foxit.common.fxcrt.RectF[] temp_rect_array = new foxit.common.fxcrt.RectF[rect_count];

            for (int i = 0; i < rect_count; i++)
            {
                foxit.common.fxcrt.RectF temp_rect = match_rect_array.GetAt(i);
                temp_rect_array[i] = temp_rect;
            }

            return temp_rect_array;
        }

        void searchContext_SearchResult(object sender, SearchEventArgs e)
        {
            if (e == null)
                return;

            SearchContextState state = e.State;
            switch (state)
            {
            case SearchContextState.SearchStart:
                break;
            case SearchContextState.SearchFind:
                {
                    TextSearch text_search = e.SearchHandle;
                    if (text_search != null)
                    {
                        if (current_page_index_ != e.PageIndex)
                        {
                            view_control_.ClearSearchText();
                            GoToPage(e.PageIndex);
                        }

                        var search_page_rect_list = new List<foxit.common.fxcrt.RectF>(GetSearchTextRect(text_search));
                        if (search_page_rect_list.Count > 0)
                        {
                            foxit.common.fxcrt.RectF first_rect= search_page_rect_list[0];
                            foxit.common.fxcrt.PointF make_center_point = new foxit.common.fxcrt.PointF(first_rect.left, first_rect.bottom);
                            System.Drawing.Point make_center_window_point = new System.Drawing.Point();
                            view_control_.DocToWindow(e.PageIndex, make_center_point, ref make_center_window_point);
                            Control temp_control = view_control_ as Control;
                            Rectangle client_rect = temp_control.ClientRectangle;

                            if (!client_rect.Contains(make_center_window_point))
                            {
                                view_control_.MovePage(make_center_window_point, new System.Drawing.Point(client_rect.X + client_rect.Width / 2, client_rect.Y + client_rect.Height / 2));
                            }
                        }
                        view_control_.DrawSearchText(e.PageIndex, search_page_rect_list);
                    }
                }
                break;
            case SearchContextState.SearchNoFind:
                {
                    MessageBox.Show("The text was not found!", "Information", MessageBoxButtons.OK);
                }
                break;
            case SearchContextState.SearchFindEnd:
                {
                    MessageBox.Show("Find Completed!", "Information", MessageBoxButtons.OK);
                    view_control_.ClearSearchText();
                }
                break;
            case SearchContextState.SearchStop:
                {
                    view_control_.ClearSearchText();
                }
                break;
            }
        }
#endregion

#region Text Select
        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            select_text_string_ = view_control_.GetSelectText();

            if (select_text_string_ == null || select_text_string_.Length == 0)
                return;

            Clipboard.SetDataObject(select_text_string_);
        }
#endregion

        public void SetTimeCallback(foxit.pdf.interform.TimerCallback timer)
        {
            timer_ = timer;
        }
        public foxit.pdf.interform.TimerCallback GetTimeCallback()
        {
            return timer_;
        }

        public void OnFormFillerCut(object sender, EventArgs e)
        {
            this.GetCurDocument().GetFormFiller().OnCut();
        }

        public void OnFormFillerCopy(object sender, EventArgs e)
        {
            this.GetCurDocument().GetFormFiller().OnCopy();
        }

        public void OnFormFillerPaste(object sender, EventArgs e)
        {
            this.GetCurDocument().GetFormFiller().OnPaste();
        }

        public void OnFormFillerDelete(object sender, EventArgs e)
        {
            this.GetCurDocument().GetFormFiller().OnDelete();
        }

        public void OnFormFillerSelectAll(object sender, EventArgs e)
        {
            this.GetCurDocument().GetFormFiller().OnSelectAll();
        }

    }
}
