/**
 * Rational numbers; numbers which can be expressed as the ration of
 * two integers.
 *
 * @author Samuel A. Rebelsky
 * @author CSC153 2004S
 * @version 0.3 of April 2004
 */
public class Rational
{
  // +------------------+--------------------------------------------------
  // | Design Decisions |
  // +------------------+

 /*
1. When do we simplify rational numbers?  Only when the user tells us to.

2. How do we represent addition?  Three main options:
  a. static method 
	Rational add(Rational, Rational)
  b. mutator
	void incrementBy(Rational)
  c. return a new rational
	Rational add(Rational)
  Sam hates option b, so we'll do a or c or both.
  */

  // +--------+------------------------------------------------------------
  // | Fields |
  // +--------+

  /** 
   * Look!  It's the numerator.  If you don't know what a numerator
   * is, you shouldn't be reading this code.
   */
  int numerator;
  /** 
   * Look!  It's the denominator.  It should not be 0 or negative.
   */
  int denominator;

  // +--------------+------------------------------------------------------
  // | Constructors |
  // +--------------+

  // FORM: protection Name (matches of class) open paren, parameters close
  // paren, body

  /**
   * Preconditions:
   *   denominator is positive.
   */
  public Rational(int numerator, int denominator)
  {
    this.numerator = numerator;
    this.denominator = denominator;
  } // Rational(int, int)

  public Rational(int whole)
  {
    this.numerator = whole;
    this.denominator = 1;
  } // Rational(int)

  public Rational(float inexact)
  {
    // Fun thing to think about during break
    // Figure out how many "places" it is.
    // Multiply by that many places.
    // Simplify
    // Here's the STUB
    this.numerator = 0;
    this.denominator = 1;
  } // Rational(float)

  public Rational(String parseMe)
  {
    // Scan the string for a slash, using some string operators
    int pos = parseMe.indexOf('/');
    if (pos == -1) {
      this.numerator = Integer.parseInt(parseMe);
      this.denominator = 1;
    }
    else {
      // Break the string into two symbolic strings
      this.numerator = Integer.parseInt(parseMe.substring(0,pos));
      this.denominator = Integer.parseInt(parseMe.substring(pos+1));
    }
  } // Rational(String)

  /**
   * Create the rational number 8 to simplify subclassing.
   */
  public Rational()
  {
    this(8,1);
  } // Rational()

  // +---------+-----------------------------------------------------------
  // | Methods |
  // +---------+

  /**
   * Add another rational to this rational, returning a newly
   * created rational.
   *
   * a/b + c/d = (ad + bc)/bd
   */
  public Rational add(Rational other)
  { 
     int num = this.numerator * other.denominator
             + this.denominator * other.numerator;
     int denom = this.denominator * other.denominator;

     Rational result = new Rational(num, denom);
     result.simplify();
     return result;
  } // add(Rational)

  /**
   * Reduce the rational to the simplest form.
   */
  public void simplify()
  {
    // Find the greatest common divisor of numerator and denominator
    int gcd = ReallyHelpfulMathFunctions.gcd(this.numerator, this.denominator);
    // Divide both by that gcd
    this.numerator = this.numerator / gcd;
    this.denominator = this.denominator / gcd;
  } // simplify()

  /**
   * Convert to a string, typically for printing.
   */
  public String toString()
  {
    if (this.denominator == 1)
      return Integer.toString(this.numerator);
    else
      return this.numerator + "/" + this.denominator;
  } // toString()

  /**
   * Convert the rational to a real.
   */
  public float toFloat()
  {
    return ((float) this.numerator) / ((float) this.denominator);
  } // toFloat()
} // class Rational

