/**
 * 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)
{
    list<Figure *>::const_iterator it(image._figures.begin());
    list<Figure *>::const_iterator end(image._figures.end());
    while(it != end)
    {
        _figures.push_back((*it)->copy());
        ++it;
    }
}

/**
 * Fonction virtuelle de copie
 */
Figure * Image::copy()
{
    return new Image(*this);
}

Figure * Image::getFigure(int index) const
{
    if ((0 <= index) && (index < IMAGE_MAX))
    {
        list<Figure *>::const_iterator it(_figures.begin());
        list<Figure *>::const_iterator end(_figures.end());
        for( int i = 0; it != end; i++, ++it)
        {
            if (i == index)
                return const_cast<Figure *> (*it);
        }
        return 0;
    }
    return 0;
}


/**
 * 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
    {
        //_tableau[_nombre++] = (const_cast<Figure *> (&f))->copy();
        _figures.push_back((const_cast<Figure *> (&f))->copy());
        _nombre++;
    }
}

/**
 * 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;
    list<Figure *>::const_iterator it(_figures.begin());
    list<Figure *>::const_iterator end(_figures.end());
    for( ; it != end; ++it)
    {
        (const_cast<Figure *>(*it))->deplacer(p);
    }
}

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

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

    list<Figure *>::const_iterator it(_figures.begin());
    list<Figure *>::const_iterator end(_figures.end());
    for( ; it != end; ++it)
    {
        res +=  (*it)->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;
}
