/*
 *******************************************************************************
 * Copyright (C) 1996-2000, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/SearchIterator.java,v $ 
 * $Date: 2002/12/05 22:27:43 $ 
 * $Revision: 1.15 $
 *
 *****************************************************************************************
 */

package com.ibm.icu.text;

import java.text.CharacterIterator;

/**
 * <p>SearchIterator is an abstract base class that defines a protocol
 * for text searching. Subclasses provide concrete implementations of
 * various search algorithms.  A concrete subclass, StringSearch, is
 * provided that implements language-sensitive pattern matching based
 * on the comparison rules defined in a RuleBasedCollator
 * object. Instances of SearchIterator maintain a current position and
 * scan over the target text, returning the indices where a match is
 * found and the length of each match. Generally, the sequence of forward 
 * matches will be equivalent to the sequence of backward matches.One
 * case where this statement may not hold is when non-overlapping mode 
 * is set on and there are continuous repetitive patterns in the text. 
 * Consider the case searching for pattern "aba" in the text 
 * "ababababa", setting overlapping mode off will produce forward matches
 * at offsets 0, 4. However when a backwards search is done, the
 * results will be at offsets 6 and 2.</p>
 * 
 * <p>If matches searched for have boundary restrictions. BreakIterators 
 * can be used to define the valid boundaries of such a match. Once a 
 * BreakIterator is set, potential matches will be tested against the
 * BreakIterator to determine if the boundaries are valid and that all
 * characters in the potential match are equivalent to the pattern 
 * searched for. For example, looking for the pattern "fox" in the text
 * "foxy fox" will produce match results at offset 0 and 5 with length 3
 * if no BreakIterators were set. However if a WordBreakIterator is set,
 * the only match that would be found will be at the offset 5. Since,
 * the SearchIterator guarantees that if a BreakIterator is set, all its
 * matches will match the given pattern exactly, a potential match that 
 * passes the BreakIterator might still not produce a valid match. For 
 * instance the pattern "e" will not be found in the string 
 * "&#92;u00e9" (latin small letter e with acute) if a 
 * CharacterBreakIterator is used. Even though "e" is
 * a part of the character "&#92;u00e9" and the potential match at
 * offset 0 length 1 passes the CharacterBreakIterator test, "&#92;u00e9"
 * is not equivalent to "e", hence the SearchIterator rejects the potential
 * match. By default, the SearchIterator
 * does not impose any boundary restriction on the matches, it will 
 * return all results that match the pattern. Illustrating with the 
 * above example, "e" will
 * be found in the string "&#92;u00e9" if no BreakIterator is
 * specified.</p>
 * 
 * <p>SearchIterator also provides a means to handle overlapping
 * matches via the API setOverlapping(boolean). For example, if
 * overlapping mode is set, searching for the pattern "abab" in the
 * text "ababab" will match at positions 0 and 2, whereas if
 * overlapping is not set, SearchIterator will only match at position
 * 0. By default, overlapping mode is not set.</p>
 * 
 * <p>The APIs in SearchIterator are similar to that of other text
 * iteration classes such as BreakIterator. Using this class, it is
 * easy to scan through text looking for all occurances of a
 * match.</p>
 * <p>
 * Example of use:<br>
 * <pre>
 * String target = "The quick brown fox jumped over the lazy fox";
 * String pattern = "fox";
 * SearchIterator iter = new StringSearch(pattern, target);
 * for (int pos = iter.first(); pos != SearchIterator.DONE; 
 *                                                       pos = iter.next()) {
 *     // println matches at offset 16 and 41 with length 3
 *     System.out.println("Found match at " + pos + ", length is " 
 *                        + iter.getMatchLength());
 * }
 * target = "ababababa";
 * pattern = "aba";
 * iter.setTarget(new StringCharacterIterator(pattern));
 * iter.setOverlapping(false);
 * System.out.println("Overlapping mode set to false");
 * System.out.println("Forward matches of pattern " + pattern + " in text "
 *                    + text + ": ");
 * for (int pos = iter.first(); pos != SearchIterator.DONE; 
 *                                                       pos = iter.next()) {
 *     // println matches at offset 0 and 4 with length 3
 *     System.out.println("offset " + pos + ", length " 
 *                        + iter.getMatchLength());
 * }
 * System.out.println("Backward matches of pattern " + pattern + " in text "
 *                    + text + ": ");
 * for (int pos = iter.last(); pos != SearchIterator.DONE; 
 *                                                    pos = iter.previous()) {
 *     // println matches at offset 6 and 2 with length 3
 *     System.out.println("offset " + pos + ", length " 
 *                        + iter.getMatchLength());
 * }
 * System.out.println("Overlapping mode set to true");
 * System.out.println("Index set to 2");
 * iter.setIndex(2);
 * iter.setOverlapping(true);
 * System.out.println("Forward matches of pattern " + pattern + " in text "
 *                    + text + ": ");
 * for (int pos = iter.first(); pos != SearchIterator.DONE; 
 *                                                       pos = iter.next()) {
 *     // println matches at offset 2, 4 and 6 with length 3
 *     System.out.println("offset " + pos + ", length " 
 *                        + iter.getMatchLength());
 * }
 * System.out.println("Index set to 2");
 * iter.setIndex(2);
 * System.out.println("Backward matches of pattern " + pattern + " in text "
 *                    + text + ": ");
 * for (int pos = iter.last(); pos != SearchIterator.DONE; 
 *                                                    pos = iter.previous()) {
 *     // println matches at offset 0 with length 3
 *     System.out.println("offset " + pos + ", length " 
 *                        + iter.getMatchLength());
 * }
 * </pre>
 * </p>
 * @author Laura Werner, synwee
 * @stable ICU 2.0
 * @see BreakIterator
 */
public abstract class SearchIterator 
{
	
	// public data members -------------------------------------------------
	
    /**
     * DONE is returned by previous() and next() after all valid matches have 
     * been returned, and by first() and last() if there are no matches at all.
     * @see #previous
     * @see #next
     * @stable ICU 2.0
     */
    public static final int DONE = -1;
    
    // public methods -----------------------------------------------------
    
    // public setters -----------------------------------------------------
    
    /**
     * <p>
     * Sets the position in the target text at which the next search will start.
     * This method clears any previous match.
     * </p>
     * @param position position from which to start the next search
     * @exception IndexOutOfBoundsException thrown if argument position is out
     *            of the target text range.
     * @see #getIndex
     * @draft ICU 2.2
     */
    public void setIndex(int position) {
        if (position < targetText.getBeginIndex() 
            || position > targetText.getEndIndex()) {
            throw new IndexOutOfBoundsException(
                "setIndex(int) expected position to be between " +
                targetText.getBeginIndex() + " and " + targetText.getEndIndex());
        }
        m_setOffset_ = position;
        m_reset_ = false;
        matchLength = 0;
    }
	
	/**
	 * <p>
     * Determines whether overlapping matches are returned. See the class 
     * documentation for more information about overlapping matches.
     * </p>
	 * <p>
     * The default setting of this property is false
     * </p>
	 * @param allowOverlap flag indicator if overlapping matches are allowed
     * @see #isOverlapping
	 * @draft ICU 2.2
	 */
	public void setOverlapping(boolean allowOverlap)
	{
		m_isOverlap_ = allowOverlap;
	}
	
	/**
     * Set the BreakIterator that is used to restrict the points at which 
     * matches are detected.
     * Using <tt>null</tt> as the parameter is legal; it means that break 
     * detection should not be attempted.
     * See class documentation for more information.
     * @param breakiter A BreakIterator that will be used to restrict the 
     * 					points at which matches are detected.
     * @see #getBreakIterator
     * @see BreakIterator
     * @stable ICU 2.0
     */
    public void setBreakIterator(BreakIterator breakiter) 
    {
        breakIterator = breakiter;
        if (breakIterator != null) {
        	breakIterator.setText(targetText);
        }
    }
    
    /**
     * Set the target text to be searched. Text iteration will then begin at 
 	 * the start of the text string. This method is useful if you want to 
     * reuse an iterator to search within a different body of text.
	 * @param text new text iterator to look for match, 
	 * @exception IllegalArgumentException thrown when text is null or has
	 * 			  0 length
	 * @see #getTarget
	 * @stable ICU 2.4
	 */
	public void setTarget(CharacterIterator text)
	{
		if (text == null || text.getEndIndex() == text.getIndex()) {
            throw new IllegalArgumentException("Illegal null or empty text");
        }
        
        targetText = text;
        targetText.setIndex(targetText.getBeginIndex());
        matchLength = 0;
        m_reset_ = true;
        m_isForwardSearching_ = true;
        if (breakIterator != null) {
        	breakIterator.setText(targetText);
        }
	}

	// public getters ----------------------------------------------------
	
	/**
     * <p>
     * Returns the index of the most recent match in the target text.
	 * This call returns a valid result only after a successful call to 
	 * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
	 * Just after construction, or after a searching method returns 
	 * <tt>DONE</tt>, this method will return <tt>DONE</tt>.
     * </p>
	 * <p>
     * Use <tt>getMatchLength</tt> to get the length of the matched text.
     * <tt>getMatchedText</tt> will return the subtext in the searched 
     * target text from index getMatchStart() with length getMatchLength(). 
     * </p>
	 * @return index to a substring within the text string that is being 
	 *         searched.
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #first
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
	 * @draft ICU 2.2
	 */
	public int getMatchStart()
	{
        return m_lastMatchStart_;
	}

	/**
     * Return the index in the target text at which the iterator is currently
     * positioned. 
     * If the iteration has gone past the end of the target text, or past 
     * the beginning for a backwards search, {@link #DONE} is returned.
     * @return index in the target text at which the iterator is currently 
     *         positioned.
     * @draft ICU 2.2
     * @see #first
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     */
    public abstract int getIndex();
    
    /**
     * <p>
     * Returns the length of the most recent match in the target text. 
     * This call returns a valid result only after a successful
     * call to {@link #first}, {@link #next}, {@link #previous}, or 
     * {@link #last}.
     * Just after construction, or after a searching method returns
     * <tt>DONE</tt>, this method will return 0. See getMatchStart() for 
     * more details.
     * </p>
     * @return The length of the most recent match in the target text, or 0 if 
     *         there is no match.
     * @see #getMatchStart
     * @see #getMatchedText
     * @see #first
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public int getMatchLength() 
    {
        return matchLength;
    }
    
    /**
     * Returns the BreakIterator that is used to restrict the indexes at which 
     * matches are detected. This will be the same object that was passed to 
     * the constructor or to <code>setBreakIterator</code>.
     * If the BreakIterator has not been set, <tt>null</tt> will be returned.
     * See setBreakIterator for more information.
     * @return the BreakIterator set to restrict logic matches
     * @see #setBreakIterator
     * @see BreakIterator
     * @stable ICU 2.0
     */
    public BreakIterator getBreakIterator() 
    {
        return breakIterator;
    }
    
    /**
     * Return the target text that is being searched.
     * @return target text being searched.
     * @see #setTarget
     * @stable ICU 2.0
     */
    public CharacterIterator getTarget() 
    {
        return targetText;
    }
    
    /**
     * Returns the text that was matched by the most recent call to 
     * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}. 
     * If the iterator is not pointing at a valid match, for instance just 
     * after construction or after <tt>DONE</tt> has been returned, an empty 
     * String will be returned. See getMatchStart for more information
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #first
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     * @return the substring in the target text of the most recent match 
     * @stable ICU 2.0
     */
    public String getMatchedText() 
    {
        if (matchLength > 0) {
            int limit = m_lastMatchStart_ + matchLength;
    		StringBuffer result = new StringBuffer(matchLength);
    		result.append(targetText.current());
    		targetText.next();
    		while (targetText.getIndex() < limit) {
    			result.append(targetText.current());
    			targetText.next();
    		}
            targetText.setIndex(m_lastMatchStart_);
    		return result.toString();
    	}
        return null;
    }

	// miscellaneous public methods -----------------------------------------
		
	/**
     * Search <b>forwards</b> in the target text for the next valid match,
     * starting the search from the current iterator position. The iterator is 
	 * adjusted so that its current index, as returned by {@link #getIndex},
	 * is the starting position of the match if one was found. If a match is 
     * found, the index of the match is returned, otherwise <tt>DONE</tt> is
     * returned.  If overlapping mode is set, the beginning of the found match
     * can be before the end of the current match, if any.
	 * @return The starting index of the next forward match after the current 
     *         iterator position, or 
	 *         <tt>DONE</tt> if there are no more matches.
	 * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #following
     * @see #preceding
     * @see #previous
     * @see #first
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public int next()
    {
    	int start = targetText.getIndex();
    	if (m_setOffset_ != DONE) {
	    	start = m_setOffset_;	
	    	m_setOffset_ = DONE;	
	    }
	    if (m_isForwardSearching_) {
	    	if (!m_reset_ && 
	        	start + matchLength >= targetText.getEndIndex()) {
	            // not enough characters to match
                matchLength = 0;
                targetText.setIndex(targetText.getEndIndex());
                m_lastMatchStart_ = DONE;
	            return DONE; 
	        }
	        m_reset_ = false;
	    }
	    else {
	        // switching direction. 
	        // if matchedIndex == USEARCH_DONE, it means that either a 
	        // setIndex has been called or that previous ran off the text
	        // string. the iterator would have been set to offset 0 if a 
	        // match is not found.
	        m_isForwardSearching_ = true;
	        if (start != DONE) {
	            // there's no need to set the collation element iterator
	            // the next call to next will set the offset.
	            return start;
	        }
	    }
	    
        if (start == DONE) {
            start = targetText.getBeginIndex();
        }
        if (matchLength > 0) {
            // if match length is 0 we are at the start of the iteration
            if (m_isOverlap_) {
                start ++;
            }
            else {
                start += matchLength;
            }
        }
	    m_lastMatchStart_ = handleNext(start);
        return m_lastMatchStart_;
    }

    /**
     * Search <b>backwards</b> in the target text for the next valid match,
     * starting the search from the current iterator position. The iterator is 
     * adjusted so that its current index, as returned by {@link #getIndex},
     * is the starting position of the match if one was found. If a match is 
     * found, the index is returned, otherwise <tt>DONE</tt> is returned.  If
     * overlapping mode is set, the end of the found match can be after the
     * beginning of the previous match, if any.
     * @return The starting index of the next backwards match after the current 
     *         iterator position, or 
     *         <tt>DONE</tt> if there are no more matches.
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #following
     * @see #preceding
     * @see #next
     * @see #first
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public int previous()
    {
    	int start = targetText.getIndex();
    	if (m_setOffset_ != DONE) {
	    	start = m_setOffset_;	
	    	m_setOffset_ = DONE;	
	    }
    	if (m_reset_) {
            m_isForwardSearching_ = false;
            m_reset_ = false;
            start = targetText.getEndIndex();
        }
        
        if (m_isForwardSearching_ == true) {
            // switching direction. 
            // if matchedIndex == USEARCH_DONE, it means that either a 
            // setIndex has been called or that next ran off the text
            // string. the iterator would have been set to offset textLength if 
            // a match is not found.
            m_isForwardSearching_ = false;
            if (start != targetText.getEndIndex()) {
                return start;
            }
        }
        else {
        	if (start == targetText.getBeginIndex()) {
                // not enough characters to match
                matchLength = 0;
                targetText.setIndex(targetText.getBeginIndex());
                m_lastMatchStart_ = DONE;
                return DONE; 
            }
        }

        m_lastMatchStart_ = handlePrevious(start);
        return m_lastMatchStart_;
    }

    /**
     * Return true if the overlapping property has been set.
     * See setOverlapping(boolean) for more information.
     * @see #setOverlapping
     * @return true if the overlapping property has been set, false otherwise
     * @draft ICU 2.2
     */
    public boolean isOverlapping() 
    {
        return m_isOverlap_;
    }
    
    /** 
	 * <p>
     * Resets the search iteration. All properties will be reset to their
     * default values.
     * </p>
	 * <p>
     * If a forward iteration is initiated, the next search will begin at the
     * start of the target text. Otherwise, if a backwards iteration is initiated,
     * the next search will begin at the end of the target text.
     * </p>
	 * @draft ICU 2.2
	 */
	public void reset()
	{
		// reset is setting the attributes that are already in string search
        matchLength = 0;
        setIndex(targetText.getBeginIndex());
        m_isOverlap_ = false;
        m_isForwardSearching_ = true;
        m_reset_ = true;
        m_setOffset_ = DONE;
	}
	
	/**
     * Return the index of the first <b>forward</b> match in the target text. 
     * This method sets the iteration to begin at the start of the 
     * target text and searches forward from there.
     * @return The index of the first forward match, or <code>DONE</code> 
     * 		   if there are no matches.
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #following
     * @see #preceding
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public final int first() 
    {
        m_isForwardSearching_ = true;
        setIndex(targetText.getBeginIndex());
        return next();
    }

    /**
     * Return the index of the first <b>forward</b> match in target text that 
     * is at or after argument <tt>position</tt>. 
     * This method sets the iteration to begin at the specified
     * position in the the target text and searches forward from there.
     * @return The index of the first forward match, or <code>DONE</code> 
     *         if there are no matches.
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #first
     * @see #preceding
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public final int following(int position) 
    {
    	m_isForwardSearching_ = true;
    	// position checked in usearch_setOffset
        setIndex(position);
        return next();
    }
    
    /**
     * Return the index of the first <b>backward</b> match in target text. 
     * This method sets the iteration to begin at the end of the 
     * target text and searches backwards from there.
     * @return The starting index of the first backward match, or 
     *         <code>DONE</code> if there are no matches.
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #first
     * @see #preceding
     * @see #next
     * @see #previous
     * @see #following
     * @see #DONE
     * @stable ICU 2.0
     */
    public final int last() 
    {
        m_isForwardSearching_ = false;
        setIndex(targetText.getEndIndex());
        return previous();
    }
     
    /**
     * Return the index of the first <b>backwards</b> match in target 
     * text that ends at or before argument <tt>position</tt>. 
     * This method sets the iteration to begin at the argument
     * position index of the target text and searches backwards from there.
     * @return The starting index of the first backwards match, or 
     *         <code>DONE</code> 
     *         if there are no matches.
     * @see #getMatchStart
     * @see #getMatchLength
     * @see #getMatchedText
     * @see #first
     * @see #following
     * @see #next
     * @see #previous
     * @see #last
     * @see #DONE
     * @stable ICU 2.0
     */
    public final int preceding(int position) 
    {
        m_isForwardSearching_ = false;
        // position checked in usearch_setOffset
        setIndex(position);
        return previous();   
    }
    
    // protected data member ----------------------------------------------
    
    /**
     * The BreakIterator to define the boundaries of a logical match.
     * This value can be a null.
     * See class documentation for more information.
     * @see #setBreakIterator(BreakIterator)
     * @see #getBreakIterator
     * @see BreakIterator
     * @stable ICU 2.0
     */
    protected BreakIterator breakIterator; 

    /**
     * Target text for searching.
     * @see #setTarget(CharacterIterator)
     * @see #getTarget
     * @stable ICU 2.0
     */
    protected CharacterIterator targetText;
    /**
     * Length of the most current match in target text. 
     * Value 0 is the default value.
     * @see #setMatchLength
     * @see #getMatchLength
     * @stable ICU 2.0
     */
    protected int matchLength;
    
    // protected constructor ----------------------------------------------
    
	/**
     * Protected constructor for use by subclasses.
     * Initializes the iterator with the argument target text for searching 
     * and sets the BreakIterator.
     * See class documentation for more details on the use of the target text
     * and BreakIterator.
     * @param target The target text to be searched.
     * @param breaker A {@link BreakIterator} that is used to determine the 
     *                boundaries of a logical match. This argument can be null.
     * @exception IllegalArgumentException thrown when argument target is null,
     *            or of length 0
     * @see BreakIterator  
     * @stable ICU 2.0
     */
    protected SearchIterator(CharacterIterator target, BreakIterator breaker)
    {
        if (target == null 
            || (target.getEndIndex() - target.getBeginIndex()) == 0) {
                throw new IllegalArgumentException(
                                   "Illegal argument target. " +
                                   " Argument can not be null or of length 0");
        }
    	targetText = target;
    	breakIterator = breaker;
    	if (breakIterator != null) {
    		breakIterator.setText(target);
    	}
    	matchLength = 0;
        m_lastMatchStart_ = DONE;
        m_isOverlap_ = false;
        m_isForwardSearching_ = true;
        m_reset_ = true;
        m_setOffset_ = DONE;
    }    
    
    // protected methods --------------------------------------------------

   
    /**
	 * Sets the length of the most recent match in the target text. 
	 * Subclasses' handleNext() and handlePrevious() methods should call this 
     * after they find a match in the target text.    
	 * @param length new length to set
     * @see #handleNext
     * @see #handlePrevious
     * @stable ICU 2.0
	 */
    protected void setMatchLength(int length)
    {
    	matchLength = length;
    }

	/**
	 * <p>
     * Abstract method that subclasses override to provide the mechanism 
	 * for finding the next <b>forwards</b> match in the target text. This 
     * allows different subclasses to provide different search algorithms.
     * </p> 
	 * <p>
     * If a match is found, this function must call setMatchLength(int) to
     * set the length of the result match.
     * The iterator is adjusted so that its current index, as returned by 
     * {@link #getIndex}, is the starting position of the match if one was 
     * found. If a match is not found, <tt>DONE</tt> will be returned.
     * </p> 
	 * @param start index in the target text at which the forwards search 
     *        should begin.
	 * @return the starting index of the next forwards match if found, DONE 
     *         otherwise
	 * @see #setMatchLength(int)
     * @see #handlePrevious(int)
     * @see #DONE
     * @stable ICU 2.0
	 */
    protected abstract int handleNext(int start);
    
    /**
	 * <p>
     * Abstract method which subclasses override to provide the mechanism 
	 * for finding the next <b>backwards</b> match in the target text. 
     * This allows different 
	 * subclasses to provide different search algorithms. 
     * </p> 
	 * <p>
     * If a match is found, this function must call setMatchLength(int) to
     * set the length of the result match.
     * The iterator is adjusted so that its current index, as returned by 
     * {@link #getIndex}, is the starting position of the match if one was 
     * found. If a match is not found, <tt>DONE</tt> will be returned.
     * </p> 
	 * @param start index in the target text at which the backwards search 
     *        should begin.
	 * @return the starting index of the next backwards match if found, 
     *         DONE otherwise
	 * @see #setMatchLength(int)
     * @see #handleNext(int)
     * @see #DONE
     * @stable ICU 2.0
	 */
    protected abstract int handlePrevious(int startAt);
    
    // private data members ------------------------------------------------
    
    /**
     * Flag indicates if we are doing a forwards search
     */
    private boolean m_isForwardSearching_;
    /**
     * Flag to indicate if overlapping search is to be done.
     * E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1.
     */
    private boolean m_isOverlap_;
    /**
     * Flag indicates if we are at the start of a string search.
     * This indicates that we are in forward search and at the start of m_text.
     */ 
    private boolean m_reset_;
    /**
     * Data member to store user defined position in setIndex().
     * If setIndex() is not called, this value will be DONE.
     */ 
    private int m_setOffset_;
    /**
     * Offset of the beginning of the last match
     */
    private int m_lastMatchStart_;
}
