/*
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TextFinder_h
#define TextFinder_h

#include "core/editing/FindOptions.h"
#include "platform/geometry/FloatRect.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebFloatPoint.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebRect.h"
#include "public/web/WebFindOptions.h"
#include "web/WebExport.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"

namespace blink {

class Range;
class WebLocalFrameImpl;

template <typename T>
class WebVector;

class WEB_EXPORT TextFinder final
    : public GarbageCollectedFinalized<TextFinder> {
  WTF_MAKE_NONCOPYABLE(TextFinder);

 public:
  static TextFinder* create(WebLocalFrameImpl& ownerFrame);

  bool find(int identifier,
            const WebString& searchText,
            const WebFindOptions&,
            bool wrapWithinFrame,
            bool* activeNow = nullptr);
  void clearActiveFindMatch();
  void stopFindingAndClearSelection();
  void increaseMatchCount(int identifier, int count);
  int findMatchMarkersVersion() const { return m_findMatchMarkersVersion; }
  WebFloatRect activeFindMatchRect();
  void findMatchRects(WebVector<WebFloatRect>&);
  int selectNearestFindMatch(const WebFloatPoint&, WebRect* selectionRect);

  // Counts how many times a particular string occurs within the frame.  It
  // also retrieves the location of the string and updates a vector in the
  // frame so that tick-marks and highlighting can be drawn.  This function
  // does its work asynchronously, by running for a certain time-slice and
  // then scheduling itself (co-operative multitasking) to be invoked later
  // (repeating the process until all matches have been found).  This allows
  // multiple frames to be searched at the same time and provides a way to
  // cancel at any time (see cancelPendingScopingEffort).  The parameter
  // searchText specifies what to look for and |reset| signals whether this is
  // a brand new request or a continuation of the last scoping effort.
  void scopeStringMatches(int identifier,
                          const WebString& searchText,
                          const WebFindOptions&,
                          bool reset);

  // Cancels any outstanding requests for scoping string matches on the frame.
  void cancelPendingScopingEffort();

  // This function is called to reset the total number of matches found during
  // the scoping effort.
  void resetMatchCount();

  // Return the index in the find-in-page cache of the match closest to the
  // provided point in find-in-page coordinates, or -1 in case of error.
  // The squared distance to the closest match is returned in the
  // |distanceSquared| parameter.
  int nearestFindMatch(const FloatPoint&, float* distanceSquared);

  // Returns whether this frame has the active match.
  bool activeMatchFrame() const { return m_currentActiveMatchFrame; }

  // Returns the active match in the current frame. Could be a null range if
  // the local frame has no active match.
  Range* activeMatch() const { return m_activeMatch.get(); }

  void flushCurrentScoping();

  void resetActiveMatch() { m_activeMatch = nullptr; }

  int totalMatchCount() const { return m_totalMatchCount; }
  bool scopingInProgress() const { return m_scopingInProgress; }
  void increaseMarkerVersion() { ++m_findMatchMarkersVersion; }

  ~TextFinder();

  class FindMatch {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

   public:
    FindMatch(Range*, int ordinal);

    DECLARE_TRACE();

    Member<Range> m_range;

    // 1-based index within this frame.
    int m_ordinal;

    // In find-in-page coordinates.
    // Lazily calculated by updateFindMatchRects.
    FloatRect m_rect;
  };

  DECLARE_TRACE();

 private:
  class DeferredScopeStringMatches;
  friend class DeferredScopeStringMatches;

  explicit TextFinder(WebLocalFrameImpl& ownerFrame);

  // Notifies the delegate about a new selection rect.
  void reportFindInPageSelection(const WebRect& selectionRect,
                                 int activeMatchOrdinal,
                                 int identifier);

  void reportFindInPageResultToAccessibility(int identifier);

  // Clear the find-in-page matches cache forcing rects to be fully
  // calculated again next time updateFindMatchRects is called.
  void clearFindMatchesCache();

  // Select a find-in-page match marker in the current frame using a cache
  // match index returned by nearestFindMatch. Returns the ordinal of the new
  // selected match or -1 in case of error. Also provides the bounding box of
  // the marker in window coordinates if selectionRect is not null.
  int selectFindMatch(unsigned index, WebRect* selectionRect);

  // Compute and cache the rects for FindMatches if required.
  // Rects are automatically invalidated in case of content size changes,
  // propagating the invalidation to child frames.
  void updateFindMatchRects();

  // Sets the markers within a range as active or inactive. Returns true if at
  // least one such marker found.
  bool setMarkerActive(Range*, bool active);

  // Removes all markers.
  void unmarkAllTextMatches();

  // Determines whether the scoping effort is required for a particular frame.
  // It is not necessary if the frame is invisible, for example, or if this
  // is a repeat search that already returned nothing last time the same prefix
  // was searched.
  bool shouldScopeMatches(const WTF::String& searchText, const WebFindOptions&);

  // Removes the current frame from the global scoping effort and triggers any
  // updates if appropriate. This method does not mark the scoping operation
  // as finished.
  void flushCurrentScopingEffort(int identifier);

  // Finishes the current scoping effort and triggers any updates if
  // appropriate.
  void finishCurrentScopingEffort(int identifier);

  // Queue up a deferred call to scopeStringMatches.
  void scopeStringMatchesSoon(int identifier,
                              const WebString& searchText,
                              const WebFindOptions&,
                              bool reset);

  // Called by a DeferredScopeStringMatches instance.
  void callScopeStringMatches(DeferredScopeStringMatches*,
                              int identifier,
                              const WebString& searchText,
                              const WebFindOptions&,
                              bool reset);

  // Determines whether to invalidate the content area and scrollbar.
  void invalidateIfNecessary();

  WebLocalFrameImpl& ownerFrame() const {
    DCHECK(m_ownerFrame);
    return *m_ownerFrame;
  }

  Member<WebLocalFrameImpl> m_ownerFrame;

  // Indicates whether this frame currently has the active match.
  bool m_currentActiveMatchFrame;

  // The range of the active match for the current frame.
  Member<Range> m_activeMatch;

  // The index of the active match for the current frame.
  int m_activeMatchIndex;

  // The scoping effort can time out and we need to keep track of where we
  // ended our last search so we can continue from where we left of.
  //
  // This range is collapsed to the end position of the last successful
  // search; the new search should start from this position.
  Member<Range> m_resumeScopingFromRange;

  // Keeps track of the last string this frame searched for. This is used for
  // short-circuiting searches in the following scenarios: When a frame has
  // been searched and returned 0 results, we don't need to search that frame
  // again if the user is just adding to the search (making it more specific).
  WTF::String m_lastSearchString;

  // Keeps track of how many matches this frame has found so far, so that we
  // don't lose count between scoping efforts, and is also used (in conjunction
  // with m_lastSearchString) to figure out if we need to search the frame
  // again.
  int m_lastMatchCount;

  // This variable keeps a cumulative total of matches found so far in this
  // frame, and is only incremented by calling IncreaseMatchCount.
  int m_totalMatchCount;

  // Keeps track of whether the frame is currently scoping (being searched for
  // matches).
  bool m_frameScoping;

  // Identifier of the latest find-in-page request. Required to be stored in
  // the frame in order to reply if required in case the frame is detached.
  int m_findRequestIdentifier;

  // Keeps track of when the scoping effort should next invalidate the scrollbar
  // and the frame area.
  int m_nextInvalidateAfter;

  // A list of all of the pending calls to scopeStringMatches.
  HeapVector<Member<DeferredScopeStringMatches>> m_deferredScopingWork;

  // Version number incremented whenever this frame's find-in-page match
  // markers change.
  int m_findMatchMarkersVersion;

  // Local cache of the find match markers currently displayed for this frame.
  HeapVector<FindMatch> m_findMatchesCache;

  // Contents size when find-in-page match rects were last computed for this
  // frame's cache.
  IntSize m_contentsSizeForCurrentFindMatchRects;

  // This flag is used by the scoping effort to determine if we need to figure
  // out which rectangle is the active match. Once we find the active
  // rectangle we clear this flag.
  bool m_locatingActiveRect;

  // Keeps track of whether there is an scoping effort ongoing in the frame.
  bool m_scopingInProgress;

  // Keeps track of whether the last find request completed its scoping effort
  // without finding any matches in this frame.
  bool m_lastFindRequestCompletedWithNoMatches;

  // Determines if the rects in the find-in-page matches cache of this frame
  // are invalid and should be recomputed.
  bool m_findMatchRectsAreValid;
};

}  // namespace blink

WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch);

#endif  // TextFinder_h
