#include "Deriv.hpp"

Deriv::Deriv(void) : Base1(), Base2(), x(0), y(0)
{
    cerr << "Deriv : constructor implicit." << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

Deriv::Deriv(Deriv const & D) : Base1(D), Base2(D), x(D.x), y(D.y)
{
    cerr << "Deriv : constructor de copiere." << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

Deriv::Deriv(int Vx, int Vy) : Base1(), Base2(), x(Vx), y(Vy)
{
    cerr << "Deriv : constructor cu parametri." << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

Deriv::Deriv(Base1 const &B1) : Base1(B1)
{
    cerr << "Deriv : constructor cu parametru referinta la Base1" << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

Deriv::Deriv(Base2 const &B2) : Base2(B2)
{
    cerr << "Deriv : constructor cu parametru referinta la Base1" << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

virtual Deriv::~Deriv()
{
    cerr << "Deriv : destructor." << endl;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
}

Deriv & Deriv::operator =(Deriv const &D)
{
    *(Base1 *)this = D;
    *(Base2 *)this = D;
    x = D.x;
    y = D.y;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
    return *this;
}

Deriv Deriv::operator +(Deriv const &D) const
{
    Deriv       R; //Rezultatul
    R.x = x + D.x;
    R.y = y + D.y;
    //Conversia clasei derivate la un tip de baza
    //prin intermediul pointerului deoarece altfel
    //s-ar utiliza o referinta neconstanta la un
    //obiect anonim temporar. Nu este prea elegant, nu-i asa?
    //O astfel de constructie, desi corecta, trebuie evitata.
    //Oricum, chestiunea functioneaza numai datorita existeneti
    //constructorilor cu parametri adecvati pentru clasa Deriv.
    *(Base1 *)&R = Base1(*this)+ D;
    *(Base2 *)&R = Base2(*this) + D;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
    return R;
}

virtual int Deriv::operator ()(int ValInt)
{
    cerr << "Deriv : operatorul virtual ()" << endl;
    return x + y + ValInt;
}

int Deriv::operator ()(int Val1, int Val2)
{
    cerr << "Deriv : operatorul ()" << endl;
    return x * Val1 + y * Val2;
}

istream & operator >>(istream &In, Deriv &D)
{
    cerr << "Operatorul de extractie prieten al clasei de baza Deriv." << endl;
    cerr << "x : ";
    In >> D.x;
    cerr << "y : ";
    In >> D.y;
    In >> *(Base1 *)&D;
    In >> *(Base2 *)&D;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
    return In;
}

ostream & operator <<(ostream &Out, Deriv const &D)
{
    cerr << "Operatorul de insertie prieten al clasei de baza Deriv." << endl;
    Out << "x : " << D.x << endl << "y : " << D.y << endl;
    Out << *(Base1 *)&D;
    Out << *(Base2 *)&D;
#if defined(_DEBUG_)
    cerr << "Apasati enter";
    cin.get();
#endif
    return Out;
}
