#include "MixedExpression.h"
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;

// Convert a mixed expression to its normal form.
void MixedExpression::reduce(void)
{
	long numerator = a*c + b; // Holds the numerator.
	long remainder = numerator % c; // Holds the remainder.
	long dividend = numerator / c; // Holds the dividend.
	long gcd = 1; // Holds the greatest common divisor.
	
	// Get the greatest common divisor.
 	for (int i = 2; i <= remainder; i++) 
	{
 		if((c % i ==0) && (remainder % i==0)) 
		{
 			gcd = i;
 		}
 	}
 	remainder /= gcd; // Divide the remainder by the GCD.
 	c /= gcd; // Divide the denominator by the GCD.
 	a = dividend; // Set a equal to the dividend.
 	b = remainder; // Set b equal to the remainder.
 	if(b == 0) // If b is zero, set to default.
	{
		c = 1;
	}
}

// Set three values in the default constructor to 0.
MixedExpression::MixedExpression()
{
	a = 0;
	b = 0;
	c = 1;
}

// Set three values in the normal constructor equal to the arguments.
MixedExpression::MixedExpression(long d, long e, long f)
{
	a = d;
	b = e;
	c = f;
}

// Add two mixed expressions and return the result.
MixedExpression MixedExpression::add(MixedExpression op)
{
	MixedExpression res;
	res.a = a + op.a;
	res.b = (b * op.c) + (op.b * c);
	res.c = c * op.c;
	return MixedExpression(res.a,res.b,res.c);
}

// Subtract two mixed expressions and return the result.
MixedExpression MixedExpression::subtract(MixedExpression op)
{
	MixedExpression res;
	res.a = a - op.a;
	res.b = (b * op.c) - (op.b * c);
	res.c = c * op.c;
	return MixedExpression(res.a,res.b,res.c);
}

// Multiply two mixed expressions and return the result.
MixedExpression MixedExpression::multiply(MixedExpression op)
{
	long numerator;
	long denominator;
	long remainder;
	MixedExpression res;
	
	numerator = (a*c + b) * (op.a * op.c + op.b);
	denominator = c * op.c;
	remainder = numerator % denominator;
	res.a = numerator/denominator;
	return MixedExpression(res.a,remainder,denominator);
}

// Divide two mixed expressions and return the result.
MixedExpression MixedExpression::divide(MixedExpression op)
{
	long numerator;
	long denominator;
	long remainder;
	MixedExpression res;
	
	numerator = (a*c + b) * (op.c);
	denominator = c * (op.a * op.c + op.b);
	remainder = numerator % denominator;
	res.a = numerator/denominator;
	return MixedExpression(res.a,remainder,denominator);
}

// Read each value and character.
void MixedExpression::ReadMixedExp(istream &in)
{
	char remove;
	in >> remove >> a >> remove >> b >> remove >> c >> remove;
}

// Print the results.
void MixedExpression::printData(ostream &out)
{
	reduce();
	out << "( " << a << " + " << b << " / " << c << " )";
}

