/* ********************************************
		Program: lab07tp.cpp
		
		Tonya M. Payne
		COSC 1435 :: Section 3
		
		Version: 1.0
		Date:		Original 3 March 2010
		Purpose:	Add and multiply two fractions together, giving both the
					fraction and the decimal equivalent. I have also made it to
					where it will check for improper fractions and give it as
					a proper fraction, and then check to see if it can be 
					reduced, and gives the reduction as well.
		
		Input: Keyboard
		Output: To screen


*///////////////////////////////////////////////

#include <iostream> //Used for cout
#include <iomanip>	//For output formatting
#include <cmath>  	//For math functions

using namespace std; //compiler environment

//function for finding greatest common factor, used for reducing fractions
//to their least common denominator
int GCF( int i, int j )
{
    while( 1 )
    {
        i = i % j;
		if( i == 0 )
			return j;
		j = j % i;

        if( j == 0 )
			return i;
    }
}

//the main part of the program
int main()
{
	int iNum1,	//the first numerator
		iDen1,	//the first denominator
		iNum2, 	// the second numerator
		iDen2, 	// the second denominator
		iNumResultM,	//the result for the numerator with multiplication
		iDenResultM,	//the result for the denominator with multiplication
		iNumResultA,	//the result for the numerator with addition
		iDenResultA;	//the result for the denominator with addition
	double 	dResultM,	//the result for multiplying the fractions
			dResultA;	//the result for adding the fractions
		
	//gets the data
	cout << "Enter the first numerator: ";
	cin >> iNum1;
	cout << "Enter the first denominator: ";
	cin >> iDen1;
		//checks for a zero in the denominator
		while ( iDen1 == 0 )
			{
				cout << "The denominator cannot be zero, please enter a "
						 "non-zero number. \n";
				cin >> iDen1;
			}		
	cout << "Enter the second numerator: ";
	cin >> iNum2;
	cout << "Enter the second denominator: ";
	cin >> iDen2;
		//checks for a zero in the denominator
		while ( iDen2 == 0 )
			{
				cout << "The denominator cannot be zero, please enter a "
						"non-zero number. \n";
				cin >> iDen2;
			}
			
	//white space, looks better for formatting
	cout << "-------------------------------------------------\n";
	
	//fixes irrational fractions, swaps negative from denominator to numerator
	//in the case of a negative denominator, and if both numerator and
	//denominator are negative, makes it positive
	if ( iDen1 < 0 && iNum1 > 0 )
		{
			iNum1 = -iNum1;
			iDen1 = -iDen1;
			cout << "The denominator was negative in the first fraction, \n" 
					"so the negative was swapped with the numerator, \n"
					"normalizing the fraction.\n";
		}
		
	if ( iDen2 < 0 && iNum2 > 0 )
		{
			iNum2 = -iNum2;
			iDen2 = -iDen2;
			cout << "The denominator was negative in the second fraction, \n" 
					"so the negative was swapped with the numerator, \n"
					"normalizing the fraction.\n";
		}
	if ( iNum1 < 0 && iDen1 < 0 )
		{
			iNum1 = -iNum1;
			iDen1 = -iDen1;
			cout << "Both the numerator and denominator were negative in \n"
					"the first fraction, therefore the fraction is positive.\n";
		}
	if ( iNum2 < 0 && iDen2 < 0 )
		{
			iNum2 = -iNum2;
			iDen2 = -iDen2;
			cout << "Both the numerator and denominator were negative in \n"
					"the first fraction, therefore the fraction is positive.\n";
		}
	
	//multiplication of the fractions
	iNumResultM = iNum1 * iNum2;
	iDenResultM = iDen1 * iDen2;
	dResultM = iNumResultM / static_cast<double>( iDenResultM );
	
	//addition of the fractions
	iNumResultA = ( iNum1 * iDen2 ) + ( iNum2 * iDen1 );
	iDenResultA = ( iDen1 * iDen2 );
	dResultA = iNumResultA / static_cast<double>( iDenResultA );
	
	//white space, looks better for formatting
	cout << "-------------------------------------------------\n";
	
	//prints out the fractions you've entered
	cout << "First fraction: " << setw(16) << iNum1 << '/' << iDen1 << endl;
	cout << "Second fraction: " << setw(15) << iNum2 << '/' << iDen2 << endl;
	
	cout << endl;
	
	//prints out the maths, multiplication	
	cout << "Multiplication result: " << setw(9) << iNumResultM << '/' 
			<< iDenResultM << " or " << dResultM << endl;
		
	//checks to see if it's improper and gives proper fraction, so long as
	//the numerator is not zero
	if (( abs ( iNumResultM ) > iDenResultM ) && ((abs (iNumResultM) % 
		abs (iDenResultM)) != 0 ))
		{
			cout << "As a mixed fraction: " << setw(11);
			cout << static_cast<int>( iNumResultM/iDenResultM ) << " " ;
			cout << abs ( iNumResultM ) % abs ( iDenResultM ) << "/" ;
			cout << iDenResultM << endl;
		}
	
	//checks to see if the fraction can be reduced and reduces it, so long as
	//the numerator is not zero, otherwise it's a whole number and has
	//already been printed		
	if ( (GCF((abs(iNumResultM) % abs (iDenResultM)) , ( iDenResultM ))) != 1 &&
		 ((abs (iNumResultM) % abs (iDenResultM)) != 0 ))
		{
			cout << "Which can be reduced to: " << setw(7) ;
			cout << static_cast<int>( iNumResultM/iDenResultM  ) << " " ;
			cout << (abs (iNumResultM) % abs (iDenResultM))/
					(GCF((abs(iNumResultM) % abs (iDenResultM)) , 
					(iDenResultM))) << "/" ; 
			cout << iDenResultM/(GCF((abs(iNumResultM) % abs (iDenResultM)) , 
					( iDenResultM ))) << endl;
		}		

	cout << "-------------------------------------------------\n";
						
	//prints out maths, addition		
	cout << "Addition result: " << setw(15) << iNumResultA << '/' 
			<< iDenResultA << " or " << dResultA << endl;
					
	//checks to see if it's improper and gives proper fraction, so long as
	//the numerator is not zero
	if (( abs ( iNumResultA ) > iDenResultA ) && ((abs (iNumResultA) % 
		abs (iDenResultA)) != 0 ))
		{
			cout << "As a mixed fraction: " << setw(11);
			cout << static_cast<int>( iNumResultA/iDenResultA  ) << " " ;
			cout << abs ( iNumResultA ) % abs ( iDenResultA ) << "/" ;
			cout << iDenResultA << endl;
		}
	
	//checks to see if the fraction can be reduced and reduces it, so long as
	//the numerator is not zero, otherwise it's a whole number and has
	//already been printed		
	if ( (GCF((abs(iNumResultA) % abs (iDenResultA)) , ( iDenResultA ))) != 1 &&
		 ((abs (iNumResultA) % abs (iDenResultA)) != 0 ))
		{
			cout << "Which can be reduced to: " << setw(7) ;
			cout << static_cast<int>( iNumResultA/iDenResultA  ) << " " ;
			cout << (abs (iNumResultA) % abs (iDenResultA))/
					(GCF((abs(iNumResultA) % abs (iDenResultA)) , 
					(iDenResultA))) << "/" ; 
			cout << iDenResultA/(GCF((abs(iNumResultA) % abs (iDenResultA)) , 
					( iDenResultA ))) << endl;
		
		}
			

		
	return 0;	
}
