using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using C1.Win.C1Document;
using C1.Win.C1Document.Export;

namespace SearchText
{
    public partial class Form1 : Form
    {
        private string _loadedFile = null;
        private C1TextSearchManager _textSearchManager;

        public Form1()
        {
            InitializeComponent();

            //
            tbFile.Text = @"..\..\DefaultDocument.pdf";
            _textSearchManager = new C1TextSearchManager(c1PdfDocumentSource1);
            _textSearchManager.FindActionCompleted += _textSearchManager_FindActionCompleted;
            _textSearchManager.FoundPositionsChanged += _textSearchManager_FoundPositionsChanged;
            _textSearchManager.LongOperation += _textSearchManager_LongOperation;

            //
            UpdateControls();
        }

        private void _textSearchManager_LongOperation(object sender, C1.Win.LongOperationEventArgs e)
        {
            Invoke((MethodInvoker)(() =>
            {
                pbFind.Value = (int)Math.Round(e.Complete * pbFind.Maximum);
            }));
        }

        private void _textSearchManager_FoundPositionsChanged(object sender, EventArgs e)
        {
            Invoke((MethodInvoker)(() =>
            {
                int n = _textSearchManager.FoundPositions.Count;
                for (int i = lvFoundPositions.Items.Count; i < n; i++)
                {
                    C1FoundPosition fp = _textSearchManager.FoundPositions[i];
                    var bounds = fp.GetBounds();
                    ListViewItem lvi = new ListViewItem(new string[]
                        {
                        (i + 1).ToString(),
                        fp.GetPage().PageNo.ToString(),
                        string.Format("{0}, {1}, {2}, {3}", (int)Math.Round(bounds.Left), (int)Math.Round(bounds.Top), (int)Math.Round(bounds.Width), (int)Math.Round(bounds.Height)),
                        fp.PositionInNearText.ToString(),
                        fp.NearText,
                        });
                    lvFoundPositions.Items.Add(lvi);
                }
            }));
        }

        private void _textSearchManager_FindActionCompleted(object sender, FindActionCompletedEventArgs e)
        {
            Invoke((MethodInvoker)(() =>
            {
                UpdateControls();
                pbFind.Visible = false;
            }));
        }

        private void UpdateControls()
        {
            bool enabled = !string.IsNullOrEmpty(tbFindText.Text) && !_textSearchManager.IsSearching();

            btnFind.Enabled = enabled;
        }

        private void btnFile_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
            {
                tbFile.Text = openFileDialog1.FileName;
            }
        }

        private void btnFind_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbFile.Text))
            {
                MessageBox.Show(this, "Please select a PDF file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!File.Exists(tbFile.Text))
            {
                MessageBox.Show(this, string.Format("File \"{0}\" does not exist.", tbFile.Text), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (string.Compare(_loadedFile, tbFile.Text, true) != 0)
            {
                // load document
                while (true)
                {
                    try
                    {
                        c1PdfDocumentSource1.LoadFromFile(tbFile.Text);
                        _loadedFile = tbFile.Text;
                        break;
                    }
                    catch (PdfPasswordException)
                    {
                        string password = PasswordForm.DoEnterPassword(tbFile.Text);
                        if (password == null)
                            return;
                        c1PdfDocumentSource1.Credential.Password = password;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }

            //
            lvFoundPositions.Items.Clear();
            C1FindTextParams ftp = new C1FindTextParams(tbFindText.Text, cbxWholeWord.Checked, cbxCaseSensitive.Checked);
            _textSearchManager.FindStartAsync(0, true, ftp, false);

            // 
            UpdateControls();
            pbFind.Value = 0;
            pbFind.Visible = true;
        }

        private void tbFindText_TextChanged(object sender, EventArgs e)
        {
            UpdateControls();
        }
    }
}
