/*********************************************************************
 * Author: B. Alex Bridges                                           *
 * File: RatNum.java                                                 *
 * Class: CPSC-101 Lab Section 3                                     *
 * Project: Lab 6 - Rational Numbers                                 *
 * Purpose: This program performs various operations on sets of      *
 *			rational numbers.                                        *
 *********************************************************************/

/* IMPORTS */
import java.awt.*;
import java.io.*;
import java.util.StringTokenizer;


class RatNum
{
	/* GLOBAL VARIABLES */
	private int int_Numerator = 0;
	private int int_Denominator = 0;
	private static int int_Count = 0;

	/*************************************************************************
	 * Purpose: Creates a true rational number.                              *
	 * Input: num = the numerator                                            *
	 *        denom = the denominator                                        *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum(int num, int denom)
	{
		int_Numerator = num;
		int_Denominator = denom;
		int_Count++;
	} // method RatNum(int num, int denom)

	/*************************************************************************
	 * Purpose: Creates the rational number zero.                            *
	 * Input: N/A                                                            *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum()
	{
		int_Numerator = 0;
		int_Denominator = 1;
		int_Count++;
	} // method RatNum()

	/*************************************************************************
	 * Purpose: Creates an integer rational number.                          *
	 * Input: val = the integer value                                        *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum(int val)
	{
		int_Numerator = val;
		int_Denominator = 1;
		int_Count++;
	} // method RatNum(int val)

	/*************************************************************************
	 * Purpose: Creates a duplicate rational number.                         *
	 * Input: val = a rational number                                        *
	 * Output: N/A                                                           *
	 * Called Routines: val.getNum(), val.getDenom()                         *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum(RatNum val)
	{
		int_Numerator = val.getNum();
		int_Denominator = val.getDenom();
		int_Count++;
	} // method RatNum(RatNum val)

	/*************************************************************************
	 * Purpose: Returns the numerator of a rational number.                  *
	 * Input: N/A                                                            *
	 * Output: The integer value of the numerator                            *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public int getNum()
	{
		return int_Numerator;
	} // method getNum()

	/*************************************************************************
	 * Purpose: Returns the denominator of a rational number.                *
	 * Input: N/A                                                            *
	 * Output: The integer value of the denominator                          *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public int getDenom()
	{
		return int_Denominator;
	} // method getDenom()

	/*************************************************************************
	 * Purpose: Returns the number of existing rational numbers.             *
	 * Input: N/A                                                            *
	 * Output: The number of existing rational number                        *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public static int getCount()
	{
		return int_Count;
	} // method getCount()

	/*************************************************************************
	 * Purpose: Assigns the value to the numerator.                          *
	 * Input: x = the integer value for the numerator                        *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public void setNum(int x)
	{
		int_Numerator = x;
	} // method setNum(int x)

	/*************************************************************************
	 * Purpose: Assigns the value to the denominator.                        *
	 * Input: x = rhe integer value for the denominator                      *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public void setDenom(int y)
	{
		int_Denominator = y;
	} // method setNum(int y)

	/*************************************************************************
	 * Purpose: To determine the greatest common factor between the          *
	 *          numerator and the denominator.                               *
	 * Input: a = the numerator                                              *
	 *        b = the denominator                                            *
	 * Output: N/A                                                           *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public static int GCF(int a, int b)
	{
		if (b == 0)
			return a;
		else
			return GCF(b, a % b);
	} // method GCF(int i, int j)

	/*************************************************************************
	 * Purpose: To determine the reduced form of a rational number.          *
	 * Input: val = a rational number                                        *
	 * Output: N/A                                                           *
	 * Called Routines: getNum, getDenom, GCF                                *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum reduced(RatNum val)
	{
		int num = val.getNum();
		int denom = val.getDenom();
		int factor = RatNum.GCF(num,denom);

		val.setNum(num / factor);
		val.setDenom(denom / factor);
		
		return val;
	} // method reduced(RatNum val)

	/*************************************************************************
	 * Purpose: Adds 2 rational numbers                                      *
	 * Input: val = the 2nd rational number                                  *
	 * Output: the reduced result                                            *
	 * Called Routines: getNum, getDenom, reduced                            *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum add(RatNum b)
	{
		RatNum result = new RatNum();

		result.setNum( ( int_Numerator * b.getDenom() ) + ( b.getNum() * int_Denominator ) );
		result.setDenom( int_Denominator * b.getDenom() );

		return reduced(result);
	} // method add(RatNum b)

	/*************************************************************************
	 * Purpose: Subtracts 2 rational numbers                                 *
	 * Input: val = the 2nd rational number                                  *
	 * Output: the reduced result                                            *
	 * Called Routines: getNum, getDenom, reduced                            *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum subtract(RatNum b)
	{
		RatNum result = new RatNum();

		result.setNum( ( int_Numerator * b.getDenom() ) - ( b.getNum() * int_Denominator) );
		result.setDenom( int_Denominator * b.getDenom() );

		return reduced(result);
	} // method subtract(RatNum b)

	/*************************************************************************
	 * Purpose: Multiplies 2 rational numbers                                *
	 * Input: val = the 2nd rational number                                  *
	 * Output: the reduced result                                            *
	 * Called Routines: getNum, getDenom, reduced                            *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum multiply(RatNum b)
	{
		RatNum result = new RatNum();

		result.setNum( int_Numerator * b.getNum() );
		result.setDenom( int_Denominator * b.getDenom() );

		return reduced(result);
	} // method multiply(RatNum b)

	/*************************************************************************
	 * Purpose: Divides 2 rational numbers                                   *
	 * Input: val = the 2nd rational number                                  *
	 * Output: the reduced result                                            *
	 * Called Routines: getNum, getDenom, reduced                            *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum divide(RatNum b)
	{
		RatNum result = new RatNum();

		result.setNum( int_Numerator * b.getDenom() );
		result.setDenom( int_Denominator * b.getNum() );

		return reduced(result);
	} // method divide(RatNum b)

	/*************************************************************************
	 * Purpose: Compares if the rational number a is less than b             *
	 * Input: val = the 2nd rational number                                  *
	 * Output: TRUE or FALSE                                                 *
	 * Called Routines: getNum, getDenom                                     *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public boolean isLess(RatNum b)
	{
		return ( ( int_Numerator * b.getDenom() ) < ( b.getNum() * int_Denominator ) );
	} // method isLess(RatNum b)

	/*************************************************************************
	 * Purpose: Compares if the rational number a is equal to b              *
	 * Input: val = the 2nd rational number                                  *
	 * Output: TRUE or FALSE                                                 *
	 * Called Routines: getNum, getDenom                                     *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public boolean isEqual(RatNum b)
	{
		return ( ( int_Numerator * b.getDenom() ) == ( b.getNum() * int_Denominator ) );
	} // method isEqual(RatNum b)

	/*************************************************************************
	 * Purpose: Converts the rational number to a string                     *
	 * Input: N/A                                                            *
	 * Output: the string equivalent                                         *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public String toString()
	{
		return ( Integer.toString(int_Numerator)+"/"+Integer.toString(int_Denominator) );
	} // method toString()

	/*************************************************************************
	 * Purpose: Converts the rational number to a float                      *
	 * Input: N/A                                                            *
	 * Output: the float equivalent                                          *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public float toFloat()
	{
		return ( (float)int_Numerator / (float)int_Denominator );
	} // method toFloat()

	/*************************************************************************
	 * Purpose: Reads in rational numbers                                    *
	 * Input: STANDARD - a string in the form a/b                            *
	 * Output: the ratinal number equivalent                                 *
	 * Called Routines: N/A                                                  *
	 * Assumptions: N/A                                                      *
	 *************************************************************************/
	public RatNum ReadRatNum(String[] args) throws IOException
	{
		/* LOCAL VARIABLES */
		String str_Line = new String(); // THE LINE OF TEXT READ IN
		StringTokenizer strT_Parser	= new StringTokenizer(""); // STRING TOKENS
		int int_NumTokens = 0; // THE NUMBER OF TOKENS THAT THE LINE OF TEXT WAS BROKEN INTO
		String str_Number = new String(); // THE CURRENT NUMBER
		RatNum result = new RatNum();
		
		/* STANDARD TEXT INPUT STREAM SETUP */
		BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in) );

		while( stdin.ready() )		
		{	
			/* INPUT */
			str_Line = stdin.readLine();
			
			/* LINE => RATIONAL NUMBERS */
			strT_Parser = new StringTokenizer(str_Line, "/ \t\n\r", true);
			
			int_NumTokens = strT_Parser.countTokens();
			
			for (int_NumTokens = int_NumTokens; int_NumTokens != 0; int_NumTokens--)
			{
				str_Number = strT_Parser.nextToken();
				
				System.out.println("Number = "+str_Number);
			} // for
		} // while

		return(result);
	} // method ReadRatNum()
} // class RatNum


/*************************************************************************
 * Purpose: Demonstrates the functionality of RatNum                     *
 * Input: STANDARD = pairs of rational numbers, one pair per line        *
 * Output: them added, subtracted, multiplied, divided, compared, equated*
 * Called Routines: RatNum class                                         *
 * Assumptions: N/A                                                      *
 *************************************************************************/
class Driver
{
	public void main ()
	{
		/* HEADER */
		System.out.println("B. Alex Bridges");
		System.out.println("CPSC-101, Winter 1998");
		System.out.println("The Rational Numbers Program");
		System.out.println(); // BLANK LINE
	} // method main
} // class Driver
