#include <iostream>
#include <cmath>

class Point
{
private:
    int x;
    int y;

public:
    Point() = default;
    Point(int x, int y)
    {
        this->x = x;
        this->y = y;

        std::cout << "Constuctor in Point Class Called" << std::endl;
    }

    int getX()
    {
        return x;
    }
    int getY()
    {
        return y;
    }

    void setPoint(int nX, int nY)
    {
        x = nX;
        y = nY;
    }

    void add(Point p)
    {
        x += p.x;
        y += p.y;
    }

    int calculateDistance();

    ~Point()
    {
        std::cout << "Destructor in Point Class" << std ::endl;
    }
};

class Point3D : private Point
{
private:
    int z;

public:
    Point3D() = default;

    Point3D(int x, int y, int z) : Point(x, y)
    {
        this->z = z;
        std::cout << "Constuctor in Point3D Class Called" << std::endl;
    }

    int getZ()
    {
        return z;
    }

    void setZ(int nZ)
    {
        z = nZ;
    }

    void setDelegate(int x, int y)
    {
        setPoint(x, y);
    }

    int deletegateX()
    {
        return getX();
    }

    int deletegateY()
    {
        return getY();
    }

    void add(Point3D p)
    {
        Point::add({p.getX(), p.getY()});
        z += p.z;
    }

    int calculateDistance()
    {
        return sqrt((deletegateX() * deletegateX()) + (deletegateY() * deletegateY()) + (z*z));
    }

    void display()
    {
        std::cout << getX() << getY() << z << std::endl;
    }

    ~Point3D()
    {
        std::cout << "Destructor in Point3D Class" << std::endl;
    }
};

int main()
{

    Point3D d;
    d.setDelegate(2, 3);
    d.setZ(6);
    d.display();

    std::cout << "Delegated X: " << d.deletegateX() << std::endl;
    std::cout << "Delegated Y: " << d.deletegateY() << std::endl;
    std::cout << "Z: " << d.getZ() << std::endl;


    std::cout << "Distance: " << d.calculateDistance() << std::endl;
    return 0;
}