//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// vector_utils.h: Utility classes implementing various vector operations

#ifndef COMMON_VECTOR_UTILS_H_
#define COMMON_VECTOR_UTILS_H_

#include <cmath>
#include <cstddef>
#include <ostream>
#include <type_traits>
#include "common/debug.h"

namespace angle
{

template <size_t Dimension, typename Type>
class Vector;

using Vector2 = Vector<2, float>;
using Vector3 = Vector<3, float>;
using Vector4 = Vector<4, float>;

using Vector2I = Vector<2, int>;
using Vector3I = Vector<3, int>;
using Vector4I = Vector<4, int>;

using Vector2U = Vector<2, unsigned int>;
using Vector3U = Vector<3, unsigned int>;
using Vector4U = Vector<4, unsigned int>;

template <size_t Dimension, typename Type>
class VectorBase
{
  public:
    using VectorN = Vector<Dimension, Type>;

    // Constructors
    VectorBase() = default;
    explicit VectorBase(Type element);

    template <typename Type2>
    VectorBase(const VectorBase<Dimension, Type2> &other);

    template <typename Arg1, typename Arg2, typename... Args>
    VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args);

    // Access the vector backing storage directly
    const Type *data() const { return mData; }
    Type *data() { return mData; }
    constexpr size_t size() const { return Dimension; }

    // Load or store the pointer from / to raw data
    static VectorN Load(const Type *source);
    static void Store(const VectorN &source, Type *destination);

    // Index the vector
    Type &operator[](size_t i) { return mData[i]; }
    const Type &operator[](size_t i) const { return mData[i]; }

    // Basic arithmetic operations
    VectorN operator+() const;
    VectorN operator-() const;
    VectorN operator+(const VectorN &other) const;
    VectorN operator-(const VectorN &other) const;
    VectorN operator*(const VectorN &other) const;
    VectorN operator/(const VectorN &other) const;
    VectorN operator*(Type other) const;
    VectorN operator/(Type other) const;
    friend VectorN operator*(Type a, const VectorN &b) { return b * a; }

    // Compound arithmetic operations
    VectorN &operator+=(const VectorN &other);
    VectorN &operator-=(const VectorN &other);
    VectorN &operator*=(const VectorN &other);
    VectorN &operator/=(const VectorN &other);
    VectorN &operator*=(Type other);
    VectorN &operator/=(Type other);

    // Comparison operators
    bool operator==(const VectorBase<Dimension, Type> &other) const;
    bool operator!=(const VectorBase<Dimension, Type> &other) const;

    // Other arithmetic operations
    Type length() const;
    Type lengthSquared() const;
    Type dot(const VectorBase<Dimension, Type> &other) const;
    VectorN normalized() const;

  protected:
    template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
    void initWithList(const Vector<OtherDimension, OtherType> &arg1, const Args &...args);

    // Some old compilers consider this function an alternative for initWithList(Vector)
    // when the variant above is more precise. Use SFINAE on the return value to hide
    // this variant for non-arithmetic types. The return value is still void.
    template <size_t CurrentIndex, typename OtherType, typename... Args>
    typename std::enable_if<std::is_arithmetic<OtherType>::value>::type initWithList(
        OtherType arg1,
        const Args &...args);

    template <size_t CurrentIndex>
    void initWithList() const;

    template <size_t Dimension2, typename Type2>
    friend class VectorBase;

    Type mData[Dimension];
};

template <size_t Dimension, typename Type>
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);

template <typename Type>
class Vector<2, Type> : public VectorBase<2, Type>
{
  public:
    // Import the constructors defined in VectorBase
    using VectorBase<2, Type>::VectorBase;

    // Element shorthands
    Type &x() { return this->mData[0]; }
    Type &y() { return this->mData[1]; }

    const Type &x() const { return this->mData[0]; }
    const Type &y() const { return this->mData[1]; }
};

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);

template <typename Type>
class Vector<3, Type> : public VectorBase<3, Type>
{
  public:
    // Import the constructors defined in VectorBase
    using VectorBase<3, Type>::VectorBase;

    // Additional operations
    Vector<3, Type> cross(const Vector<3, Type> &other) const;

    // Element shorthands
    Type &x() { return this->mData[0]; }
    Type &y() { return this->mData[1]; }
    Type &z() { return this->mData[2]; }

    const Type &x() const { return this->mData[0]; }
    const Type &y() const { return this->mData[1]; }
    const Type &z() const { return this->mData[2]; }
};

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);

template <typename Type>
class Vector<4, Type> : public VectorBase<4, Type>
{
  public:
    // Import the constructors defined in VectorBase
    using VectorBase<4, Type>::VectorBase;

    // Element shorthands
    Type &x() { return this->mData[0]; }
    Type &y() { return this->mData[1]; }
    Type &z() { return this->mData[2]; }
    Type &w() { return this->mData[3]; }

    const Type &x() const { return this->mData[0]; }
    const Type &y() const { return this->mData[1]; }
    const Type &z() const { return this->mData[2]; }
    const Type &w() const { return this->mData[3]; }
};

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);

// Implementation of constructors and misc operations

template <size_t Dimension, typename Type>
VectorBase<Dimension, Type>::VectorBase(Type element)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] = element;
    }
}

template <size_t Dimension, typename Type>
template <typename Type2>
VectorBase<Dimension, Type>::VectorBase(const VectorBase<Dimension, Type2> &other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] = static_cast<Type>(other.mData[i]);
    }
}

// Ideally we would like to have only two constructors:
//  - a scalar constructor that takes Type as a parameter
//  - a compound constructor
// However if we define the compound constructor for when it has a single arguments, then calling
// Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound
// constructor with a single argument, which is the copy constructor. We end up with three
// constructors:
//  - the scalar constructor
//  - the copy constructor
//  - the compound constructor for two or more arguments, hence the arg1, and arg2 here.
template <size_t Dimension, typename Type>
template <typename Arg1, typename Arg2, typename... Args>
VectorBase<Dimension, Type>::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args)
{
    initWithList<0>(arg1, arg2, args...);
}

template <size_t Dimension, typename Type>
template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
void VectorBase<Dimension, Type>::initWithList(const Vector<OtherDimension, OtherType> &arg1,
                                               const Args &...args)
{
    static_assert(CurrentIndex + OtherDimension <= Dimension,
                  "Too much data in the vector constructor.");
    for (size_t i = 0; i < OtherDimension; ++i)
    {
        mData[CurrentIndex + i] = static_cast<Type>(arg1.mData[i]);
    }
    initWithList<CurrentIndex + OtherDimension>(args...);
}

template <size_t Dimension, typename Type>
template <size_t CurrentIndex, typename OtherType, typename... Args>
typename std::enable_if<std::is_arithmetic<OtherType>::value>::type
VectorBase<Dimension, Type>::initWithList(OtherType arg1, const Args &...args)
{
    static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor.");
    mData[CurrentIndex] = static_cast<Type>(arg1);
    initWithList<CurrentIndex + 1>(args...);
}

template <size_t Dimension, typename Type>
template <size_t CurrentIndex>
void VectorBase<Dimension, Type>::initWithList() const
{
    static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor.");
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::Load(const Type *source)
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = source[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
void VectorBase<Dimension, Type>::Store(const Vector<Dimension, Type> &source, Type *destination)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        destination[i] = source.mData[i];
    }
}

// Implementation of basic arithmetic operations
template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+() const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = +mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-() const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = -mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+(
    const Vector<Dimension, Type> &other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] + other.mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-(
    const Vector<Dimension, Type> &other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] - other.mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(
    const Vector<Dimension, Type> &other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] * other.mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(
    const Vector<Dimension, Type> &other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] / other.mData[i];
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(Type other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] * other;
    }
    return result;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(Type other) const
{
    Vector<Dimension, Type> result;
    for (size_t i = 0; i < Dimension; ++i)
    {
        result.mData[i] = mData[i] / other;
    }
    return result;
}

// Implementation of compound arithmetic operations
template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator+=(
    const Vector<Dimension, Type> &other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] += other.mData[i];
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator-=(
    const Vector<Dimension, Type> &other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] -= other.mData[i];
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(
    const Vector<Dimension, Type> &other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] *= other.mData[i];
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(
    const Vector<Dimension, Type> &other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] /= other.mData[i];
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(Type other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] *= other;
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(Type other)
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        mData[i] /= other;
    }
    return *static_cast<Vector<Dimension, Type> *>(this);
}

// Implementation of comparison operators
template <size_t Dimension, typename Type>
bool VectorBase<Dimension, Type>::operator==(const VectorBase<Dimension, Type> &other) const
{
    for (size_t i = 0; i < Dimension; ++i)
    {
        if (mData[i] != other.mData[i])
        {
            return false;
        }
    }
    return true;
}

template <size_t Dimension, typename Type>
bool VectorBase<Dimension, Type>::operator!=(const VectorBase<Dimension, Type> &other) const
{
    return !(*this == other);
}

// Implementation of other arithmetic operations
template <size_t Dimension, typename Type>
Type VectorBase<Dimension, Type>::length() const
{
    static_assert(std::is_floating_point<Type>::value,
                  "VectorN::length is only defined for floating point vectors");
    return std::sqrt(lengthSquared());
}

template <size_t Dimension, typename Type>
Type VectorBase<Dimension, Type>::lengthSquared() const
{
    return dot(*this);
}

template <size_t Dimension, typename Type>
Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other) const
{
    Type sum = Type();
    for (size_t i = 0; i < Dimension; ++i)
    {
        sum += mData[i] * other.mData[i];
    }
    return sum;
}

template <size_t Dimension, typename Type>
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
{
    ostream << "[ ";
    for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
    {
        if (elementIdx > 0)
        {
            ostream << ", ";
        }
        ostream << vector.data()[elementIdx];
    }
    ostream << " ]";
    return ostream;
}

template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
{
    static_assert(std::is_floating_point<Type>::value,
                  "VectorN::normalized is only defined for floating point vectors");
    ASSERT(length() != Type());
    return *this / length();
}

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
{
    return ostream << static_cast<const VectorBase<2, Type> &>(vector);
}

template <typename Type>
Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
{
    return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
                           x() * other.y() - y() * other.x());
}

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
{
    return ostream << static_cast<const VectorBase<3, Type> &>(vector);
}

template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
{
    return ostream << static_cast<const VectorBase<4, Type> &>(vector);
}

}  // namespace angle

#endif  // COMMON_VECTOR_UTILS_H_
