using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Paroxe.PdfRenderer
{
#if !UNITY_WEBGL
///
/// Don't instantiate this class directly. Use the static method instead PDFProgressiveSearch.CreateSearch
///
public class PDFProgressiveSearch : UIBehaviour
{
private bool m_AbortRequested;
private int m_CurrentPage;
private PDFDocument m_Document;
private PDFSearchHandle.MatchOption m_Flags;
private bool m_NewSearchRequested;
private int m_PageCount;
private byte[] m_Search;
private IList[] m_SearchResults;
private bool m_SearchStarted;
private float m_TimeBudget = 0.50f;
private int m_Total;
public delegate void ProgressEventHandler(PDFProgressiveSearch sender, int total);
public delegate void SearchFinishedEventHandler(PDFProgressiveSearch sender, IList[] searchResults);
public event ProgressEventHandler OnProgressChanged;
public event SearchFinishedEventHandler OnSearchFinished;
///
/// Create a progressive search object within the scene.
///
///
/// Time budget per frame. The value must be metween 0.0f and 1.0f
///
public static PDFProgressiveSearch CreateSearch(PDFDocument document, float timeBudget)
{
GameObject searchObject = new GameObject();
searchObject.name = "PDFProgressiveSearch";
PDFProgressiveSearch progressiveSearch = searchObject.AddComponent();
progressiveSearch.m_Document = document;
progressiveSearch.m_TimeBudget = Mathf.Clamp01(timeBudget);
return progressiveSearch;
}
///
/// Stop the current search request.
///
public void Abort()
{
m_AbortRequested = true;
}
///
/// Start a new search and if a search is already started this method will stop it.
///
///
/// PDFSearchHandle.MATCH_CASE, (PDFSearchHandle.MATCH_WHOLE_WORD or PDFSearchHandle.MATCH_CASE | PDFSearchHandle.MATCH_WHOLE_WORD)
public void StartSearch(string search, PDFSearchHandle.MatchOption flags)
{
if (string.IsNullOrEmpty(search.Trim()))
m_Search = null;
else
m_Search = PDFLibrary.Encoding.GetBytes(search.Trim() + "\0");
m_Flags = flags;
m_PageCount = m_Document.GetPageCount();
m_NewSearchRequested = true;
}
private void LateUpdate()
{
if (!m_SearchStarted && m_NewSearchRequested)
{
m_CurrentPage = 0;
m_SearchResults = new IList[m_PageCount];
m_NewSearchRequested = false;
m_SearchStarted = true;
m_AbortRequested = false;
m_Total = 0;
}
if (m_SearchStarted)
{
if (m_AbortRequested)
{
m_SearchStarted = false;
m_NewSearchRequested = false;
m_AbortRequested = false;
m_Total = 0;
return;
}
if (m_NewSearchRequested)
{
m_CurrentPage = 0;
m_SearchResults = new IList[m_PageCount];
m_NewSearchRequested = false;
m_Total = 0;
}
if (m_Search == null || m_Search.Length == 0)
{
m_SearchStarted = false;
if (OnProgressChanged != null)
{
OnProgressChanged(this, 0);
}
var handler = OnSearchFinished;
if (handler != null)
{
handler(this, null);
}
}
else
{
Stopwatch timer = Stopwatch.StartNew();
for (int i = m_CurrentPage; i < m_PageCount; ++i)
{
using (PDFTextPage textPage = m_Document.GetPage(i).GetTextPage())
{
IList searchResults = textPage.Search(m_Search, m_Flags);
m_SearchResults[i] = searchResults;
m_Total += searchResults.Count;
++m_CurrentPage;
if (timer.ElapsedMilliseconds >=
m_TimeBudget * 1000.0f * (1.0f / Mathf.Max(Application.targetFrameRate, 1.0f / Time.deltaTime)))
{
if (OnProgressChanged != null)
{
OnProgressChanged(this, m_Total);
}
break;
}
}
}
if (m_CurrentPage + 1 > m_PageCount)
{
m_SearchStarted = false;
if (OnProgressChanged != null)
{
OnProgressChanged(this, m_Total);
}
var handler = OnSearchFinished;
if (handler != null)
{
handler(this, m_SearchResults);
}
if (OnProgressChanged != null)
{
OnProgressChanged(this, m_Total);
}
}
}
}
}
}
#endif
}