//[0
import java.util.*;


/**
 * A partial encapsulation of a mutable Fraction
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Fraction 
//]0
    implements Operand
//[0
{
    private int    denominator, numerator;


    /**
     * Default Constructor
     */
    public Fraction()
    {
       this(0,1);       
    }

    /**
     * Explicit Value Constructor
     *
     * @param numerator   The numerator
     * @param denominator The denominator
     */
    public Fraction(int numerator, int denominator)
    {
       this.numerator   = Math.abs(numerator);
       this.denominator = Math.abs(denominator);
    }
    
    /**
     * Find a common denominator
     *
     * @param other   The other Fraction
     */
    private int commonDenominator(Fraction other)
    {
       int       result;

       if (this.denominator == other.denominator)
          result = this.denominator;
       else
          result = this.denominator * other.denominator;
       
       return result;       
    }
    

//]0

//[Increaseable

    /**
     * Increase this Fraction by a given amount (required by Increaseable)
     *
     * @param otherFraction   The amount to change this Fraction by
     */
    public void increaseBy(Increaseable otherFraction)
    {
       Fraction   other;
       int        cd;

        // This typecast is dangerous. We will talk about how
        // to eliminate the need for it later.
       other = (Fraction)otherFraction;       

       cd = commonDenominator(other);
       if (denominator == cd)
       {
          numerator += numerator;          
       }
       else
       {
          numerator = numerator *(cd/denominator) +
                      other.numerator*(cd/other.denominator);

          denominator = cd;          
       }
    }
    
//]Increaseable


//[Initializeable
    /**
     * Initialize tha attributes of this object from a String representation
     * (required by Initializeable).
     *
     * @param s   The String representation (delimited by a slash)
     */
    public void fromString(String s)
    {
       String                 token;       
       StringTokenizer        st;

       
       st = new StringTokenizer(s, "/");       

       try
       {
          token       = st.nextToken();
          numerator   = Integer.parseInt(token);
          
          token       = st.nextToken();
          denominator = Integer.parseInt(token);
       }
       catch (NoSuchElementException nsee)
       {
          // Leave the remaining default values as they are
       }
       catch (NumberFormatException nfe)
       {
          // Leave the remaining default values as they are
       }
    }

//]Initializeable
//[0    

    /**
     * Get a String representation of this Fraction
     *
     * @return  The String
     */ 
    public String toString()
    {
       return numerator+"/"+denominator;       
    }
    
}
//]0
