/**
 * auteurs          : Michel Landschoot
 * mail             : direction@landsnet.com
 * date de création : 2013-12-21
 * description      : impléméntation d'une classe décrivant une Image dans une hiérachie de figures
 */

#include "image.hpp"

static void afficherAux(ostream & os, const Image & image, int niveau);

/**
 * L'image témoin est une variable de classe
 */
Image Image::temoin = Image();


Image::Image(const Image & image) : _origine(image._origine), _nombre(image._nombre)
{
    for (int i = 0; i < _nombre; i++)
    {
      _tableau[i]= image._tableau[i]->copy();
    }
}

/**
 * Fonction virtuelle de copie
 */
Figure * Image::copy() const
{
    Image * res = new Image(this->_origine);
    res->_nombre = this->_nombre;
    for (int i = 0; i < this->_nombre; i++)
    {
        res->_tableau[i] = this->_tableau[i]->copy();
    }
    return res;
}


/**
 * ajout d' une figure à une image
 */
void Image::ajouter(const Figure & f)
{
    if (f == *this)
        return;

    if (_nombre == IMAGE_MAX)
        cerr << "l' image est deja remplie ! " << endl;
    else
    {
        /** Code pour du partage d'instances allouées dynamiquement
         * nécessite des compteurs de référence pour leur libération mémoire

            _tableau[_nombre++] = const_cast<Figure *> (&f);
        */
         _tableau[_nombre++] = (&f)->copy();
    }
}

/**
 * Déplacement-translation de valeur le point p
 * toutes les figures de l'image sont également déplacées
 */
void Image::deplacer(const Point & p)
{
    _origine += p;
    for (int i = 0; i < _nombre; i++)
    {
        if (_tableau[i] != 0)
            _tableau[i]->deplacer(p);
    }
}

/**
 * Le dessin se limite à un affichage
 */
void Image::dessiner(ostream & os) const
{
    os << *this << endl;
}

double  Image::surface() const
{
    double res = 0;

    for (int i = 0; i < _nombre; i++)
    {
        if (_tableau[i] != 0)
            res +=  _tableau[i]->surface();
    }
    return res;
}

void Image::afficher(ostream & os) const
{
    afficherAux(os, *this, 0);
}

static void afficherAux(ostream & os, const Image & image, int niveau)
{
    int j;
    for (j = 0; j < niveau; j++)
    {
                os << "\t";
    }
    os << "BEGIN IMAGE : " << image.getOrigine() << " " << image.getNombre() << " figures " << endl;
    for (int i = 0; i < image.getNombre(); i++)
    {
        const Image * imageIn = dynamic_cast<const Image *> (image.getFigure(i));
        if (imageIn != 0)
        {
            afficherAux(os, *imageIn, niveau + 1);
        }
        else
        {
            for (j = 0; j < niveau; j++)
            {
                os << "\t";
            }
            image.getFigure(i)->afficher(os);
        }
    }
    for (j = 0; j < niveau; j++)
    {
                os << "\t";
    }
    os << "END IMAGE" << endl;
}
