#ifndef LINALG_POINT_HPP
#define LINALG_POINT_HPP

#include "share.hpp"
#include <cstddef>
#include "vector.hpp"

namespace visual_engine {
namespace detail {
namespace linalg {

class vector;

class point final {
    coord_t x_, y_, z_;

public:
    point(coord_t x, coord_t y, coord_t z) : x_(x), y_(y), z_(z) {}
    point(const vector& v);

    struct point_hasher {
        size_t operator()(const point& p) const;
    };

    void console_dump(void) const;
    bool is_valid()         const;

    bool operator==(const point& p) const {
        return equal(p.x_, x_) &&
               equal(p.y_, y_) &&
               equal(p.z_, z_);
    }

    coord_t get_x(void) const { return x_; }
    coord_t get_y(void) const { return y_; }
    coord_t get_z(void) const { return z_; }

    void move(const vector &v);
    void rotate(const point &p, const vector &v);

    // void set_x(coord_t x) { x_ = x; }
    // void set_y(coord_t y) { y_ = y; }
    // void set_z(coord_t z) { z_ = z; }
};

} // namespace linalg
} // namespace detail

using typename detail::linalg::point;

} // namespace visual_engine

#endif // LINALG_POINT_HPP
