/*---------------------------------------------------------------------------
File:         			OrOperator.java
Package:                        JFLAP Version 3.1
Author:			        Ted Hung
                                
Description of Contents:	Contains class OrOperator.
				
--------------------------------------------------------------------------*/

/* 
 * Susan H. Rodger, Magda Procopiuc, Octavian Procopiuc, Eric Gramond, Ted Hung
 * Computer Science Department
 * Duke University
 * August 1999
 * Supported by National Science Foundation DUE-9596002, DUE-9555084,
 *  and DUE-9752583
 *
 * Copyright (c) 1999
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the author.  The name of the author may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package flap.operators;

import java.util.*;
import java.awt.*;
import flap.*;
//
//
// OrOperator
//
//
public class OrOperator extends Operator
{
   public OrOperator(Environment env)
   {
      setEnvironment(env);
   }

   /**
    * returns the identifier that is specific to the
    * operator
    */
   public String getIdentifier()
   {
      return "+";
   }

   /**
    * clones the operator so it can be used in a factory
    */
   public Operator Clone()
   {
      return new OrOperator(environ);
   }
   
   /**
    * returns the number of arguments that this operator
    * pops off of the stack
    */
   public int numArguments()
   {
      return 2;
   }

   /**
    * returns the priority of the given operator
    * so operator precedence can be handled
    */
   public int getPriority()
   {
      return 1;
   }

   /**
    * returns whether the result of this operator can be concatenated with
    * for example "a*b", a* can be concatenated with
    * but not "a+bc", "a+b" cannot be concatenated with
    */
   public boolean canConcatenate()
   {
      return false;
   }

   /**
    * executes the given operator on the given operands
    */
   public String execute(Stack operands)
   {
      Expression operand1 = (Expression) operands.pop();
      Expression operand2 = (Expression) operands.pop();

      //add the state for the first operand
      State startState;
      State endState;
      if(operand2.state == null)
      {
	 //place the user's states and transitions
	 startState = environ.d.addState(0,0);
	 endState = environ.d.addState(0,0);
	 endState.isFinal = true;
	 Transition trans = environ.d.addTransition(startState, endState);
	 trans.label = new String(operand2.exp);

	 placeStates(environ.d, startState, endState);

	 //place the correct answer states and transitions
	 startState = environ.dfa.d.addState(0,0);
	 endState = environ.dfa.d.addState(0,0);
	 endState.isFinal = true;
	 trans = environ.dfa.d.addTransition(startState, endState);
	 trans.label = new String(operand2.exp);

	 placeStates(environ.dfa.d, startState, endState);
      }
      else
      {
	 startState = operand2.state;
      }

      //add the second one only if it hasn't already
      //been added
      State aState;
      if(operand1.state == null)
      {
	 //place the user's states and transitions
	 aState = environ.d.addState(0,0);
	 endState = environ.d.addState(0,0);
	 endState.isFinal = true;
	 Transition trans = environ.d.addTransition(aState, endState);
	 trans.label = new String(operand1.exp);

	 placeStates(environ.d, aState, endState);

	 //place the correct answer states and transitions
         aState = environ.dfa.d.addState(0,0);
	 endState = environ.dfa.d.addState(0,0);
	 endState.isFinal = true;
	 trans = environ.dfa.d.addTransition(aState, endState);
	 trans.label = new String(operand1.exp);

	 placeStates(environ.dfa.d, aState, endState);
	 endState = aState;
      }
      else
      {
	 endState = operand1.state;
      }

      //create a base state for the OR operator
      aState = environ.dfa.d.addState(0,0);

      //add a lambda transition between the two subexpressions
      //and the base state
      if(startState != null && endState != null)
      {
	 environ.dfa.d.addTransition(aState,
	    environ.dfa.d.getStateWithId(startState.id));
	 environ.dfa.d.addTransition(aState,
	    environ.dfa.d.getStateWithId(endState.id));
      }

      environ.dfa.d.theStates.removeElement(aState);
      environ.dfa.d.placeState(aState, environ.dfa.d.theStates);
      environ.dfa.d.theStates.addElement(aState);

      environ.dfa.d.initialState = aState;
      environ.d.repaint();

      String temp1 = operand2.exp.equals(" ") ? "!" : operand2.exp;
      String temp2 = operand1.exp.equals(" ") ? "!" : operand1.exp;
      operands.push(new Expression(temp1 + "+" + temp2, aState));
      return temp1 + "+" + temp2;
   }
}

