///////////////////////////////////////////////////////////////////////////////
/// @file deFraction.cpp
///
/// @brief fraction class based on integer numerator & denominator
///
/// @author Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Feb 2002
/// @author Assassin
/// @remarks Creation
///
/// @date Jul 2002
/// @author Hootie
/// @remarks Convert to static lib
///
///////////////////////////////////////////////////////////////////////////////

#include "deMath.hpp"

static bool Divisible(int num, int den)
{
	if ((num/den)*den == num)
		return true;
	return false;
}

deFraction deFraction::operator+(int rhs) const
{
	deFraction ret;
	ret.m_Num = m_Num + (rhs * m_Den);
	ret.m_Den = m_Den;
	return ret;
}

deFraction deFraction::operator-(int rhs) const
{
	deFraction ret;
	ret.m_Num = m_Num - (rhs * m_Den);
	ret.m_Den = m_Den;
	return ret;
}

deFraction deFraction::operator*(int rhs) const
{
	deFraction ret;
	ret.m_Num = m_Num * rhs;
	ret.m_Den = m_Den;
	return ret;
}

deFraction deFraction::operator/(int rhs) const
{
	deFraction ret;
	if (Divisible(m_Num, rhs))
	{
		ret.m_Num = m_Num / rhs;
		ret.m_Den = m_Den;
	}
	else
	{
		ret.m_Num = m_Num;
		ret.m_Den = m_Den * rhs;
	}
	return ret;
}

deFraction& deFraction::operator+=(const deFraction & rhs)
{
	if (this->m_Den == rhs.m_Den)
	{
		this->m_Num = this->m_Num + rhs.m_Num;
	}
	else if (Divisible(this->m_Den, rhs.m_Den))
	{
		this->m_Num = this->m_Num + (rhs.m_Num * (this->m_Den/rhs.m_Den));
	}
	else if (Divisible(rhs.m_Den, this->m_Den))
	{
		this->m_Num = rhs.m_Num + (this->m_Num * (rhs.m_Den/this->m_Den));
		this->m_Den = rhs.m_Den;
	}
	else
	{
		this->m_Num = (this->m_Num * rhs.m_Den) + (rhs.m_Num * this->m_Den);
		this->m_Den = this->m_Den * rhs.m_Den;
	}
	return *this;
}

deFraction& deFraction::operator-=(const deFraction & rhs)
{
	if (this->m_Den == rhs.m_Den)
	{
		this->m_Num = this->m_Num - rhs.m_Num;
	}
	else if (Divisible(this->m_Den, rhs.m_Den))
	{
		this->m_Num = this->m_Num - (rhs.m_Num * (this->m_Den/rhs.m_Den));
	}
	else if (Divisible(rhs.m_Den, this->m_Den))
	{
		this->m_Num = rhs.m_Num - (this->m_Num * (rhs.m_Den/this->m_Den));
		this->m_Den = rhs.m_Den;
	}
	else
	{
		this->m_Num = (this->m_Num * rhs.m_Den) - (rhs.m_Num * this->m_Den);
		this->m_Den = this->m_Den * rhs.m_Den;
	}
	return *this;
}

bool deFraction::operator==(const deFraction & rhs)
{
	if (this->m_Num == rhs.m_Num && this->m_Den == rhs.m_Den)
		return true;
	else if (m_Num * rhs.m_Den == rhs.m_Num*m_Den)
		return true;
	return false;
}

bool deFraction::operator==(int rhs)
{
	if (m_Den == 1 && m_Num == rhs)
	{
		return true;
	}
	else
	{
		if (Divisible(m_Num, m_Den))
		{
			if (m_Num/m_Den == rhs)
				return true;
		}
	}
	return false;
}


