#include <iostream>
#include <cstring>
using namespace std;

class Hartie {
protected:
    char* m_numeFabrica;
    int m_pret;

public:
    Hartie(const char* nume = "", int pret = 0)
        : m_pret(pret) {
        m_numeFabrica = new char[strlen(nume) + 1];
        strcpy(m_numeFabrica, nume);
    }

    virtual ~Hartie() {
        delete[] m_numeFabrica;
    }

    virtual void afisare() const {
        cout << "Hartie: " << m_numeFabrica << ", Pret: " << m_pret << endl;
    }

    virtual int getPret() const {
        return m_pret;
    }
};

class Carte : virtual public Hartie {
protected:
    float m_greutate;
    int m_pret; // Pret propriu

public:
    Carte(const char* nume = "", int pretHartie = 0, int pretCarte = 0, float greutate = 0)
        : Hartie(nume, pretHartie), m_pret(pretCarte), m_greutate(greutate) {}

    void afisare() const override {
        cout << "Carte: " << m_numeFabrica << ", Pret hartie: " << Hartie::getPret()
             << ", Pret carte: " << m_pret << ", Greutate: " << m_greutate << endl;
    }

    int getPret() const override {
        return m_pret;
    }
};

class Coperta : virtual public Hartie {
protected:
    float m_greutate;
    int m_pret; // Pret propriu

public:
    Coperta(const char* nume = "", int pretHartie = 0, int pretCoperta = 0, float greutate = 0)
        : Hartie(nume, pretHartie), m_pret(pretCoperta), m_greutate(greutate) {}

    void afisare() const override {
        cout << "Coperta: " << m_numeFabrica << ", Pret hartie: " << Hartie::getPret()
             << ", Pret coperta: " << m_pret << ", Greutate: " << m_greutate << endl;
    }

    int getPret() const override {
        return m_pret;
    }
};

class CarteSiCoperta : public Carte, public Coperta {
    char* m_titluCarte;

public:
    CarteSiCoperta(const char* nume = "", int pretHartie = 0, int pretCarte = 0, int pretCoperta = 0,
                   float greutateCarte = 0, float greutateCoperta = 0, const char* titlu = "")
        : Hartie(nume, pretHartie),
          Carte(nume, pretHartie, pretCarte, greutateCarte),
          Coperta(nume, pretHartie, pretCoperta, greutateCoperta) {
        m_titluCarte = new char[strlen(titlu) + 1];
        strcpy(m_titluCarte, titlu);
    }

    ~CarteSiCoperta() {
        delete[] m_titluCarte;
    }

    void afisare() const override {
        cout << "Carte si Coperta: " << m_titluCarte << ", Pret total: " << getPret() << endl;
    }

    int getPret() const override {
        return Hartie::getPret() + Carte::getPret() + Coperta::getPret();
    }
};



int main() {
    const int N = 5;
    Hartie* elemente[N];

    // Crearea obiectelor
    elemente[0] = new Hartie("FabricaA", 10);
    elemente[1] = new Carte("FabricaB", 15, 20, 0.5);
    elemente[2] = new Coperta("FabricaC", 10, 25, 0.3);
    elemente[3] = new CarteSiCoperta("FabricaD", 10, 30, 20, 1.0, 0.5, "Titlu1");
    elemente[4] = new CarteSiCoperta("FabricaE", 5, 15, 10, 0.8, 0.4, "Titlu2");

    // Afișarea elementelor
    cout << "Elementele initiale:\n";
    for (int i = 0; i < N; ++i) {
        elemente[i]->afisare();
    }

    // Sortarea elementelor după preț
    for (int i = 0; i < N - 1; ++i) {
        for (int j = i + 1; j < N; ++j) {
            if (elemente[i]->getPret() > elemente[j]->getPret()) {
                swap(elemente[i], elemente[j]);
            }
        }
    }

    // Afișarea elementelor sortate
    cout << "\nElementele sortate dupa pret:\n";
    for (int i = 0; i < N; ++i) {
        elemente[i]->afisare();
    }

    // Eliberarea memoriei
    for (int i = 0; i < N; ++i) {
        delete elemente[i];
    }

    return 0;
}
