//    args.java by Steven R. Brandt
//    <p>
//    An example file distributed with com.stevesoft.pat
//    and com.stevesoft.pat.apps
//    <p>
//    This software comes without express or implied warranty.
//    No claim is made about the suitability of this software for
//    any purpose and neither I nor SteveSoft shall be liable for
//    damages suffered by the user of this software.
import com.stevesoft.pat.*;

// Deeply Weird Stuff: Giving
// arguments to user defined patterns and
// replacement rules.  You probably don't
// want to try and understand this unless
// you are already defining and using your
// own patterns and replacement rules.

// This is a replace rule that copies the
// matched text m times when replacing.
// ${multi:3} is equivalent to $&$&$&
// ${multi:5} is equivalent to $&$&$&$&$&.
class MultiplicityRule extends ReplaceRule {
  int m = 1;
  MultiplicityRule() {}
  MultiplicityRule(int mi) { m = mi; }

  // This is the thing that does the actual replacing
  // see fancy.java for the basics.
  public void apply(StringBufferLike sb,RegRes rr) {
    for(int i=0;i<m;i++)
      sb.append(rr.stringMatched());
  }

  // This allows the arg to work.  The arg is
  // given in the String following the ReplaceRule's
  // name.  See below.
  public ReplaceRule arg(String s) {
    try {
      Integer i = new Integer(s);
      return new MultiplicityRule(i.intValue());
    } catch(Exception e) {}
    return null;
  }
}

// This matches on a 2 digit pattern, but
// only if the digits add up to st.
class SumTo extends Validator {
  int st = 5;
  SumTo() {}
  SumTo(int s) { st = s; }

  // This allows the arg to work.  The arg is
  // given in the String following the pattern's
  // name.  See below.
  public Validator arg(String s) {
    try {
      Integer i = new Integer(s);
      return new SumTo(i.intValue());
    } catch(Exception e) {}
    return null;
  }

  // This is some code that you provide to perform
  // an additional check on a piece of text.  In this
  // case we check to see if the first two characters
  // are digits that add up to the value stored in st.
  public int validate(String src,int start,int end) {
    char c1 = src.charAt(start);
    char c2 = src.charAt(start+1);
    return c1+c2-2*'0' == st ? end : -1;
  }
}

public class args {
  public static void main(String[] args) {
    // Tell package pat the name of the MultiplicityRule.
    ReplaceRule.define("mult",new MultiplicityRule());

    // Tell package pat the name of the SumTo pattern.
    Regex.define("SumTo","\\d\\d",new SumTo());

    // Compile the pattern/replace rule pair...
    // The arg method of SumTo is called with "7" and the
    // arg method of MultiplicityReplaceRule is called
    // with "5".
    Regex r = Regex.perlCode("s/(??SumTo:7)/<${mult:5}>/");

    System.out.println(r.replaceAll("3 34 125"));
    // This should yield "3 <3434343434> 1<2525252525>"
    // Why?  We only match on pairs of digits that add up
    // to 7.  That means "34" and "25".  They are replaced
    // with "<"+5 copies of the matched String+">" according
    // to our eccentric rules.
  }
}
