//  Objectif : Implantation des fonctions de la classe Fraction

#include "Fraction.h"
#include <iostream>
#include <assert.h>

int Fraction :: numerateur() const
{
    return this->_numerateur;
}

int Fraction :: denominateur() const
{
    return this->_denominateur;
}

void Fraction :: afficher() const
{
    cout << this->_numerateur;
    if (this->_denominateur != 1) {
	cout << '/' << this->_denominateur;
    }
}

void Fraction :: set(int num, int den)
{
    assert(den != 0);

    this->_numerateur = num;
    this->_denominateur = den;
    this->normaliser();
}

void Fraction :: opposer()
{
    this->_numerateur = - this->_numerateur;
    // La fraction reste normalisée !
}

Fraction Fraction :: opposee()
{
    Fraction resultat;
    resultat.set(-this->_numerateur, this->_denominateur);
    return resultat;
}


namespace {

    int pgcd (int a, int b)
	    // plus grand diviseur commun des deux entiers strictement positifs
	    // a et b.
	    //
	    // @requires a > 0;
	    // @requires b > 0;
    {
	while (a != b) {
	    if (a > b) {
		a = a - b;
	    }
	    else {
		b = b - a;
	    }
	}
	return a;
    }

}

void Fraction :: normaliser ()
{
    if (this->_numerateur == 0) {
	this->_denominateur = 1;
    }
    else {
	// mettre le signe sur le numérateur
	if (this->_denominateur < 0) {
	    this->_denominateur = - this->_denominateur;
	    this->_numerateur = - this->_numerateur;
	}

	// simplifier
	int le_pgcd = pgcd(abs(this->_numerateur), this->_denominateur);
	this->_numerateur /= le_pgcd;
	this->_denominateur /= le_pgcd;
    }
}
