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

//overloaded output operator
ostream& operator<<(ostream &out, fraction x)
{
if (x.denom==1)
    out<<x.num;
else
    out<<x.num<<"/"<<x.denom;
return out;                                        //return a reference to the output stream
}

//overloaded input operator
istream& operator>>(istream &in, fraction &x)
{
while(isspace(in.peek()))
    in.get();                                    //skip whitespace
x.num=0;
if (in.peek()>'9' or in.peek()<'0')                //no fraction to read
    in.clear(ios::failbit);
else
    {
    in>>x.num;                //read the numerator
    if(in.peek()=='/')                                //get the slash if it's there
        {
        in.get();
        if (in.peek()>'9' or in.peek()<'0')                //no denominator to read
            in.clear(ios::failbit);
        else
            in>>x.denom;
        }
    else
        x.denom=1;
    }
x.reduce();
return in;                                        //return a reference to the input stream
}

// default constructor -- needed because I included other constructors
fraction::fraction()
{}

// integer constructor
fraction::fraction(int x)
{
num=x;
denom=1;
}

// constructor; x becomes the numerator, y becomes the denominator
fraction::fraction(int x,int y)
{
num=x;
denom=y;
}

//preincrement
fraction fraction::operator++()
{
fraction c;
*this=*this+1;
c.num=num;
c.denom=denom;
return c;
}

//postincrement (x is not used in the function; its value is 0.)
fraction fraction::operator++(int x)
{
fraction c;
c=*this;
*this=*this+1;
return c;
}

//predecrement
fraction fraction::operator--()
{
fraction c;
*this=*this - 1;
return *this;
}

//postdecrement (x is not used in the function; its value is 0.)
fraction fraction::operator--(int x)
{
fraction c;
c=*this;
num-=denom;
return c;
}

//overloaded *=
fraction fraction::operator*=(fraction a)
{
fraction c;
c.num=num*a.num;
c.denom=a.denom*denom;
c.reduce();
num=c.num;
denom=c.denom;
return c;
}

//overloaded /=
fraction fraction::operator/=(fraction a)
{
fraction c;
c.num=num*a.denom;
c.denom=a.num*denom;
c.reduce();
num=c.num;
denom=c.denom;
return c;
}

//overloaded +=
fraction fraction::operator+=(fraction a)
{
fraction c;
c.num=num*a.denom+denom*a.num;
c.denom=a.denom*denom;
c.reduce();
num=c.num;
denom=c.denom;
return c;
}

//overloaded -=
fraction fraction::operator-=(fraction a)
{
fraction c;
c.num=num*a.denom-denom*a.num;
c.denom=a.denom*denom;
c.reduce();
num=c.num;
denom=c.denom;
return c;
}

//overloaded *
fraction fraction::operator*(fraction a)
{
fraction c;
c.num=num*a.num;
c.denom=a.denom*denom;
c.reduce();
return c;
}

//overloaded /
fraction fraction::operator/(fraction a)
{fraction c;
c.num=num*a.denom;
c.denom=a.num*denom;
c.reduce();
return c;
}

//overloaded +
fraction fraction::operator+(fraction a)
{fraction c;
c.num=num*a.denom+denom*a.num;
c.denom=a.denom*denom;
c.reduce();
return c;
}

fraction operator+(int a, fraction b)    
{
     fraction c;
     c.num=a*b.denom+b.num;
     c.denom=b.denom;
     c.reduce();
     return c;
}    

//overloaded -
fraction fraction::operator-(fraction a)
{fraction c;
c.num=num*a.denom-denom*a.num;
c.denom=a.denom*denom;
c.reduce();
return c;
}

//overloaded ==
bool fraction::operator==(fraction a)
{fraction c;
c=*this;
c.reduce();
a.reduce();
return (c.num==a.num && c.denom==a.denom);
}

//overloaded <
bool fraction::operator<(fraction a)
{fraction c;
c=*this;
c.reduce();
a.reduce();
return (c.num*a.denom < c.denom*a.num);
}

//overloaded >
bool fraction::operator>(fraction a)
{fraction c;
c=*this;
c.reduce();
a.reduce();
return (c.num*a.denom > c.denom*a.num);
}


//greatest common divisor
//uses Euclidean Algorithm (recursive)
int fraction::gcd(int a,int b)
{int answer;
if(b==0)
    answer=a;
else
    answer=gcd(b,a%b);
return answer;
}

//put fraction into lowest terms
void fraction::reduce()
{
int common;
common=gcd(abs(num),abs(denom));
num/=common;
denom/=common;
if(denom<0) //make sure denominator is positive
    {
    denom*=(-1);
    num*=(-1);
    }    
}