#include "matrice.h"

Matrice :: Matrice (int lignes, int colonnes)
    : _lignes(lignes),  _colonnes(colonnes), t(NULL)
{
    t = new Vecteur * [_lignes];
    assert(t);

    for (int i = 0; i < _lignes; i++)
        t[i] = new Vecteur(0,_colonnes);
}

Matrice :: Matrice (const Matrice & x)
  : _lignes(x._lignes),  _colonnes(x._colonnes), t(NULL)
{
    t = new Vecteur * [_lignes];
    assert(t);

    for (int i = 0; i < _lignes; i++)
    {
        // appel au constructeur de copie de la classe Vecteur
        t[i] = new Vecteur (x[i]);
        //*t[i] = x[i];
    }
}

Matrice :: ~ Matrice ()
{
    for (int i = 0; i < _lignes; i++)
    {
        //cout << "destruction du " << i << "ième vecteur" << endl;
        if (t[i] != NULL)
            delete t[i];
    }
    //	cout << "destruction du tableau de pointeurs" << endl;
    if (t != NULL)
        delete [] t;
}



Matrice & Matrice :: operator= (const Matrice & x)
{
    if ( this == &x )
    {
        cout << "Matrices identiques" << endl;
        return *this;
    }

    assert((_lignes == x._lignes) && (_colonnes == x._colonnes));

    int i;
    for (i = 0; i < _lignes; i++)
    {
        cout << "destruction du " << i << "ième vecteur" << endl;
        delete t[i];
    }
    cout << "destruction du tableau de pointeurs" << endl;
    delete [] t;

    t = new Vecteur * [_lignes];
    assert(t);

    for (i = 0; i < _lignes; i++)
    {
        t[i] = new Vecteur(0,_colonnes);
        *t[i] = x[i];
    }

    return *this;
}

 const Vecteur & Matrice::operator[] (int i) const
{
    //	return **(t+i); OK
     cout << "const Vecteur & Matrice::operator[] (int i) const " << endl;
    return *(t[i]);
}

Vecteur & Matrice :: operator[] (int i)
{
    //	return **(t+i); OK
    return *(t[i]);
}

int Matrice::operator()(int i, int j) const
{
    return (*t[i])[j];
}

int & Matrice::operator()(int i, int j)
{
//    return (*t[i])[j];
    return (*this)[i][j];

}


Matrice Matrice:: operator+ (const Matrice & x) const
{
    assert(getLignes() == x.getLignes() && getColonnes() == x.getColonnes());

    Matrice sum(getLignes(), getColonnes());

    for (int i = 0; i < getLignes(); i++)
        for (int j = 0; j < getColonnes(); j++)
            sum[i][j] = (*this)[i][j] + x[i][j];

    return sum;
}


Matrice Matrice:: operator- ( ) const
{
    Matrice sum(getLignes(), getColonnes());

    for (int i = 0; i < getLignes(); i++)
        for (int j = 0; j < getColonnes(); j++)
            sum[i][j] = - (*this)[i][j];

    return sum;
}

Matrice Matrice:: operator* (const Matrice& x) const
{
    assert(getColonnes() == x.getLignes());

    Matrice produit(getLignes(), x.getColonnes());


    for (int i = 0; i < getLignes(); i++)
        for (int k = 0; k < x.getColonnes(); k++)
            for (int j = 0; j < getColonnes(); j++)
                produit[i][k] += (*this)[i][j] * x[j][k];

    return produit;
}

ostream & operator<< (ostream & os, const Matrice & x)
{
    os << "( ";
    for (int i = 0; i < x._lignes; i++)
        os << x[i];
    os << " )";
    return os;
}



istream & operator>> (istream & is, Matrice & x)
{
    cout << "rentrez les " << x._lignes << " _lignes" << endl;
    for (int i = 0; i < x._lignes; i++)
        is >> x[i];
    return is;
}

/**

ostream & operator<< (ostream & os, const Matrice & x)
{
	os << "( ";
	for (int i = 0; i < x._lignes; i++)
		os << *(x.t[i]);
        os << " )";
        return os;
}



istream & operator>> (istream & is, Matrice & x)
{
	cout << "rentrez les " << x._lignes << " _lignes" << endl;
      	for (int i = 0; i < x._lignes; i++)
		is >> *(x.t[i]);
        return is;
}

*/
