#pragma once

#include "DiscretePoint.h"
#include "Vector.h"

#include <memory>

class Transform;

class Point
{
public:
    Point(double x = 0, double y = 0, double z = 0);

    Point(const DiscretePoint& point);

    Point(const Point& reference, double offSetX, double offSetY, double offSetZ = 0);

    ~Point();

    void apply(const Transform& transform);

    double getX() const;

    double getY() const;

    double getZ() const;

    double getDistance(const Point& point) const;

    double getDeltaX(const Point& point) const;

    double getDeltaY(const Point& point) const;

    double getDeltaZ(const Point& point) const;

    Vector getDelta(const Point& point) const;

    bool isAtOrigin() const;

    void move(const Vector& vector);

    void move(double x, double y = 0.0, double z = 0.0);

    void operator+=(const Vector& vector)
    {
        move(vector);
    }

    bool operator==(const Point& rhs) const
    {
       return (mX == rhs.mX)
       && (mY == rhs.mY)
       && (mZ == rhs.mZ);
    }

    bool operator!=(const Point& rhs) const
    {
      return !operator==(rhs);
    }

private:
    double mX{0};
    double mY{0};
    double mZ{0};
};

using PointPtr = std::unique_ptr<Point>;
