package com.srbenoit.geom;

/**
 * An interface for objects that can be represented as 3-dimensional vectors.
 */
public interface Vector3Int {

    /**
     * Gets the X component of the vector.
     *
     * @return  the X component
     */
    double getVecX();

    /**
     * Sets the X component of the vector.
     *
     * @param  xComp  the X component
     */
    void setVecX(double xComp);

    /**
     * Gets the Y component of the vector.
     *
     * @return  the Y component
     */
    double getVecY();

    /**
     * Sets the Y component of the vector.
     *
     * @param  yComp  the Y component
     */
    void setVecY(double yComp);

    /**
     * Gets the Z component of the vector.
     *
     * @return  the Z component
     */
    double getVecZ();

    /**
     * Sets the Z component of the vector.
     *
     * @param  zComp  the Z component
     */
    void setVecZ(double zComp);

    /**
     * Sets the coordinates of the vector.
     *
     * @param  xComp  the x component
     * @param  yComp  the y component
     * @param  zComp  the z component
     */
    void setVec(double xComp, double yComp, double zComp);

    /**
     * Sets the coordinates of the vector from another vector.
     *
     * @param  source  the vector whose components are to be copied
     */
    void setVec(Vector3Int source);

    /**
     * Adds to the components of the vector.
     *
     * @param  xDelta  the change to the x component
     * @param  yDelta  the change to the y component
     * @param  zDelta  the change to the z component
     */
    void addVec(double xDelta, double yDelta, double zDelta);

    /**
     * Adds a vector to this vector.
     *
     * @param  vector  the vector to add to this vector
     */
    void addVec(Vector3Int vector);

    /**
     * Subtracts a vector from this vector.
     *
     * @param  vector  the vector to subtract from this vector
     */
    void subVec(Vector3Int vector);

    /**
     * Subtracts <code>vector2</code> from <code>vector1</code> and stores the result in this
     * vector.
     *
     * @param  vector1 the vector from which to subtract
     * @param  vector2 the vector to subtract
     */
    void subVec(Vector3Int vector1, Vector3Int vector2);

    /**
     * Adds a scaled version of a vector to this vector (this = this + scale tuple).
     *
     * @param  scale   the scalar value
     * @param  vector  the vector to be scaled then added
     */
    void addVecScaled(double scale, Vector3Int vector);

    /**
     * Sets this vector to the vector from <code>point1</code> to <code>point2</code> (this =
     * point2 - point1).
     *
     * @param  point1  the first point
     * @param  point2  the second point
     */
    void vectorBetween(Point3Int point1, Point3Int point2);

    /**
     * Negates this vector in place.
     */
    void negateVec();

    /**
     * Scales this vector by a scalar factor.
     *
     * @param  scale  the scalar factor
     */
    void scaleVec(double scale);

    /**
     * Sets this vector to a scaled version of another vector.
     *
     * @param  scale  the scalar factor
     * @param  vec the vector to scale
     */
    void scaleVec(double scale, Vector3Int vec);

    /**
     * Gets the lazily computed length of the vector.
     *
     * @return  the length of the vector, or -1 if the length has not yet been computed
     */
    double lazyLength();

    /**
     * Gets the squared length of the vector.
     *
     * @return  the squared length of the vector
     */
    double lengthSquared();

    /**
     * Gets the length of the vector.
     *
     * @return  the length of the vector
     */
    double length();

    /**
     * Computes the dot product of this vector with another vector.
     *
     * @param   vector  the other vector
     * @return  the dot product
     */
    double dot(Vector3Int vector);

    /**
     * Computes the cross product of <code>first</code> and <code>second</code> and stores the
     * result in this vector.
     *
     * @param  first   the first tuple in the cross product
     * @param  second  the second tuple in the cross product
     */
    void cross(Vector3Int first, Vector3Int second);

    /**
     * Normalizes this vector in place. The null vector is normalized to (1,0).
     */
    void normalize();
}
