//  Objectif :
//	Implantation de la classe Point

#include "Point.h"

#include <math.h>

namespace {

    inline double carre(double x)
	// le carré de x
    {
	return x * x;
    }

}

Point :: Point(double x, double y)
{
    _x = x;
    _y = y;
}

Point :: Point(const Point& autre)
{
    std::cerr << "**** CONSTRUCTEUR " << "Point :: Point(" << autre << ")"
	    << " @ " << this << std::endl;
    _x = autre.x();
    _y = autre.y();

}

Point & Point :: operator = (const Point& autre)
{
    std::cerr << "**** AFFECTATION " << "Point :: operator = (" << autre << ")"
	    << " @ " << this << std::endl;
    _x = autre.x();
    _y = autre.y();

    return *this;
}

Point :: ~Point()
{
    std::cerr << "**** DESTRUCTEUR " << "Point :: ~Point() // " << *this
	    << " @ " << this << std::endl;
}


double Point :: x() const
{
    return _x;
}

double Point :: y() const
{
    return _y;
}

void Point :: set_x(double nx)
{
    _x = nx;
}

void Point :: set_y(double ny)
{
    _y = ny;
}

void Point :: set_cartesien(double vx, double vy)
{
    set_x(vx);
    set_y(vy);
}

void Point :: translater(double dx, double dy)
{
    // translater chaque coordonnée
    _x = _x + dx;
    _y = _y + dy;
}

double Point :: distance(const Point &p) const
{
    return sqrt(carre(x() - p.x()) + carre(y() - p.y()));
}

void Point :: afficher(std::ostream &out) const
{
    out << "(" << x() << "," << y() << ")";
}

std::ostream & operator << (std::ostream & out, const Point &p)
{
    p.afficher(out);
    return out;
}

bool Point :: operator == (const Point & autre) const
{
    return (x() == autre.x()) && (y() == autre.y());
}

bool Point :: operator != (const Point & autre) const
{
    return ! (*this == autre);
}

Point& Point :: operator += (const Point &p2)
{
    _x += p2._x;
    _y += p2._y;

    return *this;
}

Point Point :: operator + (const Point &p2) const
{
    Point result = *this;
    result += p2;

    std::cout << "*this = " << *this << std::endl;
    std::cout << "p2 = " << p2 << std::endl;
    std::cout << "result = " << result << std::endl;

    return result;
}

Point Point :: operator * (double r) const
{
	Point result(x() * r, y() * r);
	return result;
}

double Point :: operator * (const Point &p2) const
{
    double result = x() * p2.x() + y() * p2.y();
    return result;
}

Point operator * (double facteur, const Point & p)
{
    return Point(facteur*p.x(), facteur*p.y());
}
