#include <iostream>
#include "Rational.h"

//Constructor sets the values of the numerator and denominator to two values set when called and then calls the reduce function to reduce the two numbers to be relatively prime to each other
Rational::Rational(int numer, int denom)
{
  numerator = numer;
  denominator = denom;
  reduce();
}

void Rational::reduce()
{
  //Creates copies of the denominator and numerator so as to not change the values and uses abs() for Euclidean Algorithm
  //Creates a placeholder variable that keeps track of numbers to be switched during the algorithm 
  int denomCpy,
    numerCpy,
    placeHolder;

  denomCpy = abs(denominator);
  numerCpy = abs(numerator);

  //Employs the Euclidean algorithm to find the greatest common divisor of the two numbers by continuously finding the remainder through % (when denomcpy is 0, numerCpy will be the gcd)
  while (denomCpy != 0)
    {
      placeHolder = denomCpy;
      denomCpy = numerCpy % denomCpy;
      numerCpy = placeHolder;
    }

  //Divides the denominator and the numerator by the gcd to reduce both, if the denominator was negative, then it multiplies both by -1 to place the negative since in the numerator position
  if (denominator < 0)
  {
    denominator /= -numerCpy;
    numerator /= -numerCpy;
  }
  else
  {
    denominator /= numerCpy;
    numerator /= numerCpy;
  }
}

//Returns the numerator
int Rational::getNumerator()
{
  return numerator;
}

//Returns the denominator
int Rational::getDenominator()
{
  return denominator;
}

//Overloads << by passing by reference 2 values -- the ostream object and the Rational object passed by reference in as fraction)
std::ostream &operator<<(std::ostream &out, Rational &fraction)
{
  //Calls the getNumerator function to get the numerator and appends '/' and calls the getDenominator function append the denominator to create a fraction and return it
  out << fraction.getNumerator() << '/' << fraction.getDenominator();
  return out;
}
