//  Objectif :
//	Définition d'un point mathématique dans un espace plan (à deux
//	dimmensions) muni d'un repère cartésien
//

#ifndef Point__H
#define Point__H

#include <iostream>

class Point {
public:		// Constructeur

    Point(double vx, double vy);
	// Constructeur à partir des coordonnées cartésiennes vx et vy.
	//
	//@ ensures x() == vx;
	//@ ensures y() == vy;

public: 	// Vue cartésienne

    double x() const;
	// Abscisse du point.

    double y() const;
	// Ordonnée du point.

    void set_x(double nx);
	// Changer l'abscisse du point.
	//
	//@ ensures x() == nx;

    void set_y(double ny);
	// Changer l'ordonnée du point.
	//
	//@ ensures y() == ny;

    void set_cartesien(double vx, double vy);
	// Changer les coordonnées cartésiennes du point.
	//
	//@ ensures x() == vx;	// x initialisé
	//@ ensures y() == vy;	// y initialisé

public:		// Autres requêtes

    double distance(const Point &p) const;
	// Distance du point à un autre.

public:		// égalité et inégalité

    bool operator == (const Point & autre) const;
	// égalité de deux points
	//
	//@ ensures Result implies (x() == autre.x()) && (y() == autre.y());

    bool operator != (const Point & autre) const;
	// non égalité de deux points
	//
	//@ ensures Result == !(*this == autre);

public:		// surcharge des opérateurs arithmétiques

    Point operator + (const Point &p2) const;
	// opération interne
	//
	//@ ensures \Result.x() == x() + p2.x();
	//@ ensures \Result.y() == y() + p2.y();

    Point& operator += (const Point &p2);
	// opération interne
	//
	//@ ensures x() == \Old(x()) + p2.x();
	//@ ensures y() == \Old(y()) + p2.y();

    Point operator * (double r) const;
	// produit externe
	//
	//@ ensures \result.x() == x() * r;
	//@ ensures \result.y() == y() * r;

    double operator * (const Point &p2) const;
	// produit scalaire
	//
	//@ ensures \result == x() * p2.x() + y() * p2.y();

public:		// Autres commandes

    void translater(double dx, double dy);
	// Translater le point de dx suivant l'axe des X et dy suivant l'axe
	// des Y
	//
	//@ ensures x() == \Old(x()) + dx;
	//@ ensures y() == \Old(y()) + dy;

    void afficher(std::ostream &out = std::cout) const;
	// Afficher le point


public:		// Pour tracer la création/destruction des des points

    ~Point();
	// Destructeur

    Point(const Point &autre);
	// Constructeur de copie
	//
	//@ ensures *this == autre;	// copié

    Point & operator = (const Point & autre);
	// Opérateur d'affectation
	//
	//@ ensures *this == autre;	// copié


private:
    double _x;	// Abscisse du point
    double _y;	// Ordonnée du point

};

// Surcharges d'opérateurs

Point operator * (double facteur, const Point & p);

std::ostream & operator << (std::ostream & out, const Point &p);

#endif
