// Union.java

/** A regular expression consisting of the union of two
 *  other regular expressions.
 *  @author <a href="mailto:bergmann@rowan.edu"> Seth Bergmann </a>
 *  @author <a href="mailto:gspyo@jersey.net"> Greg Safko </a>
 */
public class Union extends Expr
{  

   /** Constructor for a union.
    *  @param l The left operand of the union.
    *  @param r The right operand of the union.
    */
    public Union (Expr l, Expr r)
    {	
   		super (l.reduce(),r.reduce()); 
    }

  /** Return the union reduce based on the rules of 
   * regular expressions
   */
	public Expr reduce()
	{			
	if(this.getLeft() instanceof Empty)
		return this.getRight().reduce();
	if(this.getRight() instanceof Empty)
		return this.getLeft().reduce();
	if(this.getLeft().equals(this.getRight()))
		return this.getLeft().reduce();
	if(this.getLeft() instanceof Star)
		if(this.getRight() instanceof Star)
			if(this.getLeft().getStar().equals(this.getLeft().getStar()))
				return this.getLeft().getStar().reduce();
	
	// if an epsilon is reduced with a star, return the star
	if(this.getLeft() instanceof Epsilon)
		if(this.getRight() instanceof Star)
			return this.getRight().reduce();
	if(this.getRight() instanceof Epsilon)
		if(this.getLeft() instanceof Star)
			return this.getLeft().reduce();
	
	// if an alpha primitaive is unioned with an identical 
	// alpha primitive, return the primitive		
	if(this.getLeft() instanceof Alpha)
		if(this.getRight() instanceof Alpha)	
			if(this.getRight().getValue() == this.getLeft().getValue())
				return this.getLeft().reduce();
	
	// otherwise, it couldn't be reduced
	return this;	
	}


   /** Return the union in the form of a string which
    *  people can understand.
    */
    public String toString ()
    {  	
   // Insert the parentheses, and the union operator "+"
   // and return as a string.  Also convert the left and right
   // operands to strings.  Every kind of Expr will have its own 
   // toString() method.
	return "(" + this.getLeft().reduce().toString() + "+" + this.getRight().reduce().toString() + ")";
    }
	
	


}
