/* gnu/regexp/REMatch.java
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.util.regex;

import gnu.java.lang.CPStringBuilder;

import java.io.Serializable;

/**
 * An instance of this class represents a match
 * completed by a gnu.regexp matching function. It can be used
 * to obtain relevant information about the location of a match
 * or submatch.
 *
 * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
 */
public final class REMatch implements Serializable, Cloneable
{
  private String matchedText;
  private CharIndexed matchedCharIndexed;

  // These variables are package scope for fast access within the engine
  int eflags;			// execution flags this match was made using

  // Offset in source text where match was tried.  This is zero-based;
  // the actual position in the source text is given by (offset + anchor).
  int offset;

  // Anchor position refers to the index into the source input
  // at which the matching operation began.
  // This is also useful for the ANCHORINDEX option.
  int anchor;

  // Package scope; used by RE.
  int index;			// used while matching to mark current match position in input
  // start1[i] is set when the i-th subexp starts. And start1[i] is copied
  // to start[i] when the i-th subexp ends.  So start[i] keeps the previously
  // assigned value while the i-th subexp is being processed. This makes
  // backreference to the i-th subexp within the i-th subexp possible.
  int[] start;			// start positions (relative to offset) for each (sub)exp.
  int[] start1;			// start positions (relative to offset) for each (sub)exp.
  int[] end;			// end positions for the same
  // start[i] == -1 or end[i] == -1 means that the start/end position is void.
  // start[i] == p or end[i] == p where p < 0 and p != -1 means that
  // the actual start/end position is (p+1). Start/end positions may
  // become negative when the subexpression is in a RETokenLookBehind.
  boolean empty;		// empty string matched. This flag is used only within
  // RETokenRepeated.

  BacktrackStack backtrackStack;

  public Object clone ()
  {
    try
    {
      REMatch copy = (REMatch) super.clone ();

        copy.start = (int[]) start.clone ();
        copy.start1 = (int[]) start1.clone ();
        copy.end = (int[]) end.clone ();

        return copy;
    }
    catch (CloneNotSupportedException e)
    {
      throw new Error ();	// doesn't happen
    }
  }

  void assignFrom (REMatch other)
  {
    start = other.start;
    start1 = other.start1;
    end = other.end;
    index = other.index;
    backtrackStack = other.backtrackStack;
  }

  REMatch (int subs, int anchor, int eflags)
  {
    start = new int[subs + 1];
    start1 = new int[subs + 1];
    end = new int[subs + 1];
    this.anchor = anchor;
    this.eflags = eflags;
    clear (anchor);
  }

  void finish (CharIndexed text)
  {
    start[0] = 0;
    CPStringBuilder sb = new CPStringBuilder ();
    int i;
    for (i = 0; i < end[0]; i++)
      sb.append (text.charAt (i));
    matchedText = sb.toString ();
    matchedCharIndexed = text;
    for (i = 0; i < start.length; i++)
      {
	// If any subexpressions didn't terminate, they don't count
	// TODO check if this code ever gets hit
	if ((start[i] == -1) ^ (end[i] == -1))
	  {
	    start[i] = -1;
	    end[i] = -1;
	  }
      }
    backtrackStack = null;
  }

    /** Clears the current match and moves the offset to the new index. */
  void clear (int index)
  {
    offset = index;
    this.index = 0;
    for (int i = 0; i < start.length; i++)
      {
	start[i] = start1[i] = end[i] = -1;
      }
    backtrackStack = null;
  }

    /**
     * Returns the string matching the pattern.  This makes it convenient
     * to write code like the following:
     * <P>
     * <code> 
     * REMatch myMatch = myExpression.getMatch(myString);<br>
     * if (myMatch != null) System.out.println("Regexp found: "+myMatch);
     * </code>
     */
  public String toString ()
  {
    return matchedText;
  }

    /**
     * Returns the index within the input text where the match in its entirety
     * began.
     */
  public int getStartIndex ()
  {
    return offset + start[0];
  }

    /**
     * Returns the index within the input string where the match in
     * its entirety ends.  The return value is the next position after
     * the end of the string; therefore, a match created by the
     * following call:
     *
     * <P>
     * <code>REMatch myMatch = myExpression.getMatch(myString);</code>
     * <P>
     * can be viewed (given that myMatch is not null) by creating
     * <P>
     * <code>String theMatch = myString.substring(myMatch.getStartIndex(),
     * myMatch.getEndIndex());</code>
     * <P>
     * But you can save yourself that work, since the <code>toString()</code>
     * method (above) does exactly that for you.  
     */
  public int getEndIndex ()
  {
    return offset + end[0];
  }

    /**
     * Returns the string matching the given subexpression.  The subexpressions
     * are indexed starting with one, not zero.  That is, the subexpression
     * identified by the first set of parentheses in a regular expression
     * could be retrieved from an REMatch by calling match.toString(1).
     *
     * @param sub Index of the subexpression.
     */
  public String toString (int sub)
  {
    if ((sub >= start.length) || sub < 0)
      throw new IndexOutOfBoundsException ("No group " + sub);
    if (start[sub] == -1)
      return null;
    if (start[sub] >= 0 && end[sub] <= matchedText.length ())
      return (matchedText.substring (start[sub], end[sub]));
    else
      {
	// This case occurs with RETokenLookAhead or RETokenLookBehind.
	CPStringBuilder sb = new CPStringBuilder ();
	int s = start[sub];
	int e = end[sub];
	if (s < 0)
	  s += 1;
	if (e < 0)
	  e += 1;
	for (int i = start[0] + s; i < start[0] + e; i++)
	  sb.append (matchedCharIndexed.charAt (i));
	return sb.toString ();
      }
  }

    /** 
     * Returns the index within the input string used to generate this match
     * where subexpression number <i>sub</i> begins, or <code>-1</code> if
     * the subexpression does not exist.  The initial position is zero.
     *
     * @param sub Subexpression index
     * @deprecated Use getStartIndex(int) instead.
     */
  public int getSubStartIndex (int sub)
  {
    if (sub >= start.length)
      return -1;
    int x = start[sub];
    return (x == -1) ? x : (x >= 0) ? offset + x : offset + x + 1;
  }

    /** 
     * Returns the index within the input string used to generate this match
     * where subexpression number <i>sub</i> begins, or <code>-1</code> if
     * the subexpression does not exist.  The initial position is zero.
     *
     * @param sub Subexpression index
     * @since gnu.regexp 1.1.0
     */
  public int getStartIndex (int sub)
  {
    if (sub >= start.length)
      return -1;
    int x = start[sub];
    return (x == -1) ? x : (x >= 0) ? offset + x : offset + x + 1;
  }

    /** 
     * Returns the index within the input string used to generate this match
     * where subexpression number <i>sub</i> ends, or <code>-1</code> if
     * the subexpression does not exist.  The initial position is zero.
     *
     * @param sub Subexpression index
     * @deprecated Use getEndIndex(int) instead
     */
  public int getSubEndIndex (int sub)
  {
    if (sub >= start.length)
      return -1;
    int x = end[sub];
    return (x == -1) ? x : (x >= 0) ? offset + x : offset + x + 1;
  }

    /** 
     * Returns the index within the input string used to generate this match
     * where subexpression number <i>sub</i> ends, or <code>-1</code> if
     * the subexpression does not exist.  The initial position is zero.
     *
     * @param sub Subexpression index
     */
  public int getEndIndex (int sub)
  {
    if (sub >= start.length)
      return -1;
    int x = end[sub];
    return (x == -1) ? x : (x >= 0) ? offset + x : offset + x + 1;
  }

    /**
     * Substitute the results of this match to create a new string.
     * This is patterned after PERL, so the tokens to watch out for are
     * <code>$0</code> through <code>$9</code>.  <code>$0</code> matches
     * the full substring matched; <code>$<i>n</i></code> matches
     * subexpression number <i>n</i>.
     * <code>$10, $11, ...</code> may match the 10th, 11th, ... subexpressions
     * if such subexpressions exist.
     *
     * @param input A string consisting of literals and <code>$<i>n</i></code> tokens.
     */
  public String substituteInto (String input)
  {
    // a la Perl, $0 is whole thing, $1 - $9 are subexpressions
    CPStringBuilder output = new CPStringBuilder ();
    int pos;
    for (pos = 0; pos < input.length () - 1; pos++)
      {
	if ((input.charAt (pos) == '$')
	    && (Character.isDigit (input.charAt (pos + 1))))
	  {
	    int val = Character.digit (input.charAt (++pos), 10);
	    int pos1 = pos + 1;
	    while (pos1 < input.length () &&
		   Character.isDigit (input.charAt (pos1)))
	      {
		int val1 =
		  val * 10 + Character.digit (input.charAt (pos1), 10);
		if (val1 >= start.length)
		  break;
		pos1++;
		val = val1;
	      }
	    pos = pos1 - 1;

	    if (val < start.length)
	      {
		output.append (toString (val));
	      }
	  }
	else
	  output.append (input.charAt (pos));
      }
    if (pos < input.length ())
      output.append (input.charAt (pos));
    return output.toString ();
  }

/*  The following are used for debugging purpose
    public static String d(REMatch m) {
	if (m == null) return "null";
        else return "[" + m.index + "]";
    }

    public String substringUptoIndex(CharIndexed input) {
	StringBuffer sb = new StringBuffer();
	for (int i = 0; i < index; i++) {
	    sb.append(input.charAt(i));
	}
	return sb.toString();
    }
*/

}
