/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.util;

/**
 * A class which performs the equivalent of <CODE>String.indexOf(char)</CODE>, but using
 * multiple characters.  It locates the first instance within a string of <EM>any</EM> of
 * the specified characters.
 *
 * @author Eric J. Bowersox &lt;erbo@silcom.com&gt;
 * @version X
 */
public final class AnyCharMatcher
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private char[] charset;     // the set of characters to look for
  private int[] locs;         // a temporary array used for locations

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  /**
   * Creates a new character matcher that matches the specified characters.
   *
   * @param charset The set of characters to be matched by this object, expressed as a character array.
   */
  public AnyCharMatcher(char[] charset)
  {
    this.charset = charset;
    this.locs = new int[charset.length];

  } // end constructor

  /**
   * Creates a new character matcher that matches the specified characters.
   *
   * @param charset The set of characters to be matched by this object, expressed as a string.
   */
  public AnyCharMatcher(String charset)
  {
    this.charset = charset.toCharArray();
    this.locs = new int[charset.length()];

  } // end constructor

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns the offset within the string of the first instance of any character in this
   * character set.
   *
   * @param str The string to look through.  If this parameter is <B><CODE>null</CODE></B>,
   *            the method returns -1.
   * @return The 0-based index of the first instance of any character from this character
   *         matcher within <CODE>str</CODE>.  If <CODE>str</CODE> contains no instances of
   *         any character from this character matcher, -1 is returned.
   */
  public final int get(String str)
  {
    if (str==null)
      return -1;
    int numindexes = 0;
    int i;
    for (i=0; i<charset.length; i++)
    { // locate the index of the first HTML character
      int tmp = str.indexOf(charset[i]);
      if (tmp>=0)
	locs[numindexes++] = tmp;

    } // end for

    if (numindexes==0)
      return -1;  // no characters found
    else if (numindexes==1)
      return locs[0];  // only one found

    int rc = locs[0];
    for (i=1; i<numindexes; i++)
    { // this loop determines the lowest possible return value
      if (rc==0)
	return 0;  // can't get any lower!
      if (locs[i]<rc)
	rc = locs[i];  // this is now the lowest

    } // end for

    return rc;

  } // end get

  /**
   * Returns the offset within the string of the last instance of any character in this
   * character set.
   *
   * @param str The string to look through.  If this parameter is <B><CODE>null</CODE></B>,
   *            the method returns -1.
   * @return The 0-based index of the last instance of any character from this character
   *         matcher within <CODE>str</CODE>.  If <CODE>str</CODE> contains no instances of
   *         any character from this character matcher, -1 is returned.
   */
  public final int getLast(String str)
  {
    if (str==null)
      return -1;

    int numindexes = 0;
    int i;
    for (i=0; i<charset.length; i++)
    { // locate the index of the first HTML character
      int tmp = str.lastIndexOf(charset[i]);
      if (tmp>=0)
	locs[numindexes++] = tmp;

    } // end for

    if (numindexes==0)
      return -1;  // no characters found
    else if (numindexes==1)
      return locs[0];  // only one found

    int rc = locs[0];
    int limit = str.length() - 1;
    for (i=1; i<numindexes; i++)
    { // this loop determines the highest possible return value
      if (rc==limit)
	return limit;  // can't get any higher!
      if (locs[i]>rc)
	rc = locs[i];  // this is now the highest

    } // end for

    return rc;

  } // end getLast

} // end class AnyCharMatcher
