#include "Rational.h"

Rational::Rational(int nume, int denom)
{
	if (denom == 0)
		throw "Now you've done it.. you attempted to divide by zero!";

	denominator = denom;
	numerator = nume;
	myValue = (float)numerator / (float)denominator;
	reduce();
}

Rational Rational::operator*(const Rational &right)
{
	Rational temp((numerator * right.numerator), (denominator * right.denominator));

	temp.reduce();

    return temp;
}

Rational Rational::operator+(const Rational &right)
{
	int leftTmp, rightTmp;
	Rational temp;

	temp.denominator = denominator * right.denominator;

	leftTmp = ((temp.denominator) * numerator) / denominator;
	rightTmp = ((temp.denominator) * right.numerator) / right.denominator;

	temp.numerator = leftTmp + rightTmp;

	temp.reduce();

    return temp;
}

Rational Rational::operator-(const Rational &right)
{
	int leftTmp, rightTmp;
	Rational temp;

	temp.denominator = denominator * right.denominator;

	leftTmp = ((temp.denominator) * numerator) / denominator;
	rightTmp = ((temp.denominator) * right.numerator) / right.denominator;

	temp.numerator = leftTmp - rightTmp;

	temp.reduce();

    return temp;
}

Rational Rational::operator/(Rational &right)
{
	// Use a new object with my nume and denom to make * easier
	Rational left(numerator, denominator);
	Rational temp;

	// Multiply myself times the reciprocal of right
	right.reciprocal();
	temp = left * right;
	// Put right back the way it was
	right.reciprocal();

	temp.reduce();

	return temp;
}

bool Rational::operator<(const Rational &right)
{
	// myValue holds the current nume/denom value
	if (myValue < right.myValue)
		return true;
	
	return false;
}

bool Rational::operator<=(const Rational &right)
{
	// myValue holds the current nume/denom value
	if (myValue <= right.myValue)
		return true;
	
	return false;
}

bool Rational::operator==(const Rational &right)
{
    // myValue holds the current nume/denom value
	if (myValue == right.myValue)
		return true;
	
	return false;
}

bool Rational::operator>(const Rational &right)
{
    // myValue holds the current nume/denom value
	if (myValue > right.myValue)
		return true;
	
	return false;
}

bool Rational::operator>=(const Rational &right)
{
    // myValue holds the current nume/denom value
	if (myValue >= right.myValue)
		return true;
	
	return false;
}

void Rational::display()
// Print out fraction
{
	cout << "(" << numerator << " / " << denominator << ")";
}

void Rational::reciprocal()
// Flip the denominator and numerator
{
	int temp;
	temp = numerator;
	numerator = denominator;
	denominator = temp;
}

int Rational::reduce()
/*	Do some simple reduction on the fraction
	returns the greatest common devisor
*/
{
	int remain, tmpDenom, tmpNume, lastRemain = 0;
	bool flipped = false;

	// We always must divide the larger by the smaller
	if (numerator < denominator)
	{
		// The nume is bigger then the denom so lets flip it
		reciprocal();
		flipped = true;
	}

	// Put the denom and nume in temp variables
	tmpDenom = denominator;
	tmpNume = numerator;

	// Flip the fraction back to the way it was
	if (flipped)
		reciprocal();

	// Get our very first remainder.. its a boy!
	remain = tmpNume % tmpDenom;

	while(remain > 0)
	{
		lastRemain = remain;
		remain = tmpDenom % remain;
		tmpDenom = lastRemain;
	}

	if (lastRemain != 0)
	{
		// divide the fraction by the GCD
		denominator = denominator / lastRemain;
		numerator = numerator / lastRemain;
	}

	// If lastRemain is still zero the fraction could not be reduced
    return lastRemain;
}
