//
// This software is now distributed according to
// the Lesser Gnu Public License.  Please see
// http://www.gnu.org/copyleft/lesser.txt for
// the details.
//    -- Happy Computing!
//
package com.stevesoft.pat;

import java.util.Hashtable;
import java.util.Vector;

/**
 * This class implements the (?: ... ) extended Pattern. It provides a base
 * class from which we derive the [ ... ], ( ... ), (?! ... ), and (?= ... )
 * patterns.
 */
class Or extends Pattern
{
  Vector v;

  Pattern[] pv = null;

  Or()
  {
    v = new Vector();
  }

  String leftForm()
  {
    return "(?:";
  }

  String rightForm()
  {
    return ")";
  }

  String sepForm()
  {
    return "|";
  }

  public Or addOr(Pattern p)
  {
    pv = null;
    v.addElement(p);
    p.setParent(this);
    return this;
  }

  public String toString()
  {
    int i;
    StringBuffer sb = new StringBuffer();
    sb.append(leftForm());
    if (v.size() > 0)
    {
      sb.append(((Pattern) v.elementAt(0)).toString());
    }
    for (i = 1; i < v.size(); i++)
    {
      sb.append(sepForm());
      sb.append(((Pattern) v.elementAt(i)).toString());
    }
    sb.append(rightForm());
    sb.append(nextString());
    return sb.toString();
  }

  public int matchInternal(int pos, Pthings pt)
  {
    if (pv == null)
    {
      pv = new Pattern[v.size()];
      v.copyInto(pv);
    }
    for (int i = 0; i < v.size(); i++)
    {
      Pattern p = pv[i]; // (Pattern)v.elementAt(i);
      int r = p.matchInternal(pos, pt);
      if (r >= 0)
      {
        return r;
      }
    }
    return -1;
  }

  public patInt minChars()
  {
    if (v.size() == 0)
    {
      return new patInt(0);
    }
    patInt m = ((Pattern) v.elementAt(0)).countMinChars();
    for (int i = 1; i < v.size(); i++)
    {
      Pattern p = (Pattern) v.elementAt(i);
      m.mineq(p.countMinChars());
    }
    return m;
  }

  public patInt maxChars()
  {
    if (v.size() == 0)
    {
      return new patInt(0);
    }
    patInt m = ((Pattern) v.elementAt(0)).countMaxChars();
    for (int i = 1; i < v.size(); i++)
    {
      Pattern p = (Pattern) v.elementAt(i);
      m.maxeq(p.countMaxChars());
    }
    return m;
  }

  Pattern clone1(Hashtable h)
  {
    Or o = new Or();
    h.put(this, o);
    h.put(o, o);
    for (int i = 0; i < v.size(); i++)
    {
      o.v.addElement(((Pattern) v.elementAt(i)).clone(h));
    }
    return o;
  }
};
