#include <iostream>

using namespace std;

#include "Cercle.h"
#include "Ellipse.h"
#include "Rectangle.h"
#include "Triangle.h"

int main()
{
    /*
        Forme classe abstraite
            Composé de de Segment(s)
                Composé de Point(s)
                    Polygone hérite de Forme
                        Triangle hérite de Polygone
                        Rectangle hérite de Polygone
                    Cercle hérite de Forme
                    Ellipse hérite de Forme
    */

    Point a(3, 4);
    Point b(1, 2);
    Point c(3, 6);
    Triangle monTriangle(a, b, c);

    Point d(5, 8);
    Rectangle monRectangle(a, b, c, d);

    Cercle monCercle(a, 5);

    Ellipse monEllipse(a, 5, 3);

    // Les différentes méthodes doivent être virtual pour appliquer les fonctions de la classe fille

    cout << "Un triangle a " << monTriangle.getNombrePoints() << " points" << endl;
    cout << "Un rectangle a " << monRectangle.getNombrePoints() << " points" << endl;
    cout << "Un cercle a " << monCercle.getNombrePoints() << " (soit une infinite) de points" << endl;
    cout << "Une ellipse a " << monEllipse.getNombrePoints() << " (soit une infinite) de points" << endl << endl;

    cout << "Affichage du triangle" << endl;
    monTriangle.afficher();

    monTriangle.zoomer();
    cout << "Affichage du triangle apres zoom" << endl;
    monTriangle.afficher();

    monTriangle.rotation();
    cout << "Affichage du triangle apres rotation" << endl;
    monTriangle.afficher();

    monTriangle.translation();
    cout << "Affichage du triangle apres translation" << endl;
    monTriangle.afficher();

    cout << endl;

    cout << "Affichage du rectangle" << endl;
    monRectangle.afficher();

    monRectangle.zoomer();
    cout << "Affichage du rectangle apres zoom" << endl;
    monRectangle.afficher();

    monRectangle.rotation();
    cout << "Affichage du rectangle apres rotation" << endl;
    monRectangle.afficher();

    monRectangle.translation();
    cout << "Affichage du rectangle apres translation" << endl;
    monRectangle.afficher();

    cout << endl;

    cout << "Affichage du cercle" << endl;
    monCercle.afficher();

    monCercle.zoomer();
    cout << "Affichage du cercle apres zoom" << endl;
    monCercle.afficher();

    monCercle.rotation();
    cout << "Affichage du cercle apres rotation: RaS" << endl;
    monCercle.afficher();

    monCercle.translation();
    cout << "Affichage du cercle apres translation:" << endl;
    monCercle.afficher();

    cout << endl;

    cout << "Affichage de l'ellipse" << endl;
    monEllipse.afficher();

    monEllipse.zoomer();
    cout << "Affichage de l'ellipse apres zoom" << endl;
    monEllipse.afficher();

    monEllipse.rotation();
    cout << "Affichage de l'ellipse apres rotation: RaS" << endl;
    monEllipse.afficher();

    monEllipse.translation();
    cout << "Affichage de l'ellipse apres translation:" << endl;
    monEllipse.afficher();

    /*
        Passage en dynamique
    */

    Forme *tableau[4]; // Tableau de formes
    // Le polymorphisme permet de créer un tableau de formes, quelles qu'elles soient: triangle, rectangle, ellipse...

    tableau[0] = new Triangle(a, b, c);
    tableau[1] = new Rectangle(a, b, c, d);
    tableau[2] = new Cercle(a, 5);
    tableau[3] = new Ellipse(a, 5, 3);

    cout << endl << "Affichage du triangle dynamique" << endl;
    tableau[0]->afficher();

    cout << "Zoom du triangle" << endl;
    tableau[0]->zoomer();
    tableau[0]->afficher();

    cout << "Rotation du triangle" << endl;
    tableau[0]->rotation();
    tableau[0]->afficher();

    cout << endl << "Affichage du rectangle dynamique" << endl;
    tableau[1]->afficher();

    cout << endl << "Affichage du cercle dynamique" << endl;
    tableau[2]->afficher();

    cout << endl << "Affichage du ellipse dynamique" << endl;
    tableau[3]->afficher();

    // Appel aux méthodes statiques pour récupérer les compteurs
    cout << endl << "Il y a actuellement " << Cercle::nombreInstances() << " cercle(s) cree(s)" << endl;
    cout << "Il y a actuellement " << Ellipse::nombreInstances() << " ellipses(s) creee(s)" << endl;
    cout << "Il y a actuellement " << Rectangle::nombreInstances() << " rectangles(s) cree(s)" << endl;
    cout << "Il y a actuellement " << Triangle::nombreInstances() << " triangles(s) cree(s)" << endl << endl;

    cout << "Il y a actuellement " << Forme::nombreInstances() << " formes(s) creee(s)" << endl;
    cout << "Il y a actuellement " << Polygone::nombreInstances() << " polygones(s) creee(s)" << endl;
    cout << "Il y a actuellement " << Point::nombreInstances() << " points(s) cree(s)" << endl;

    delete [] tableau; // Suppression du tableau alloué dynamiquement

    return 0;
}
