// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_HOMOGENEOUS_H
#define EIGEN_HOMOGENEOUS_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

/** \geometry_module \ingroup Geometry_Module
 *
 * \class Homogeneous
 *
 * \brief Expression of one (or a set of) homogeneous vector(s)
 *
 * \param MatrixType the type of the object in which we are making homogeneous
 *
 * This class represents an expression of one (or a set of) homogeneous vector(s).
 * It is the return type of MatrixBase::homogeneous() and most of the time
 * this is the only way it is used.
 *
 * \sa MatrixBase::homogeneous()
 */

namespace internal {

template <typename MatrixType, int Direction>
struct traits<Homogeneous<MatrixType, Direction> > : traits<MatrixType> {
  typedef typename traits<MatrixType>::StorageKind StorageKind;
  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
  typedef std::remove_reference_t<MatrixTypeNested> MatrixTypeNested_;
  enum {
    RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ? int(MatrixType::RowsAtCompileTime) + 1 : Dynamic,
    ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ? int(MatrixType::ColsAtCompileTime) + 1 : Dynamic,
    RowsAtCompileTime = Direction == Vertical ? RowsPlusOne : MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = Direction == Horizontal ? ColsPlusOne : MatrixType::ColsAtCompileTime,
    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,
    TmpFlags = MatrixTypeNested_::Flags & HereditaryBits,
    Flags = ColsAtCompileTime == 1   ? (TmpFlags & ~RowMajorBit)
            : RowsAtCompileTime == 1 ? (TmpFlags | RowMajorBit)
                                     : TmpFlags
  };
};

template <typename MatrixType, typename Lhs>
struct homogeneous_left_product_impl;
template <typename MatrixType, typename Rhs>
struct homogeneous_right_product_impl;

}  // end namespace internal

template <typename MatrixType, int Direction_>
class Homogeneous : public MatrixBase<Homogeneous<MatrixType, Direction_> >, internal::no_assignment_operator {
 public:
  typedef MatrixType NestedExpression;
  enum { Direction = Direction_ };

  typedef MatrixBase<Homogeneous> Base;
  EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous)

  EIGEN_DEVICE_FUNC explicit inline Homogeneous(const MatrixType& matrix) : m_matrix(matrix) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const EIGEN_NOEXCEPT {
    return m_matrix.rows() + (int(Direction) == Vertical ? 1 : 0);
  }
  EIGEN_DEVICE_FUNC constexpr Index cols() const EIGEN_NOEXCEPT {
    return m_matrix.cols() + (int(Direction) == Horizontal ? 1 : 0);
  }

  EIGEN_DEVICE_FUNC const NestedExpression& nestedExpression() const { return m_matrix; }

  template <typename Rhs>
  EIGEN_DEVICE_FUNC inline const Product<Homogeneous, Rhs> operator*(const MatrixBase<Rhs>& rhs) const {
    eigen_assert(int(Direction) == Horizontal);
    return Product<Homogeneous, Rhs>(*this, rhs.derived());
  }

  template <typename Lhs>
  friend EIGEN_DEVICE_FUNC inline const Product<Lhs, Homogeneous> operator*(const MatrixBase<Lhs>& lhs,
                                                                            const Homogeneous& rhs) {
    eigen_assert(int(Direction) == Vertical);
    return Product<Lhs, Homogeneous>(lhs.derived(), rhs);
  }

  template <typename Scalar, int Dim, int Mode, int Options>
  friend EIGEN_DEVICE_FUNC inline const Product<Transform<Scalar, Dim, Mode, Options>, Homogeneous> operator*(
      const Transform<Scalar, Dim, Mode, Options>& lhs, const Homogeneous& rhs) {
    eigen_assert(int(Direction) == Vertical);
    return Product<Transform<Scalar, Dim, Mode, Options>, Homogeneous>(lhs, rhs);
  }

  template <typename Func>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::result_of<Func(Scalar, Scalar)>::type redux(
      const Func& func) const {
    return func(m_matrix.redux(func), Scalar(1));
  }

 protected:
  typename MatrixType::Nested m_matrix;
};

/** \geometry_module \ingroup Geometry_Module
 *
 * \returns a vector expression that is one longer than the vector argument, with the value 1 symbolically appended as
 * the last coefficient.
 *
 * This can be used to convert affine coordinates to homogeneous coordinates.
 *
 * \only_for_vectors
 *
 * Example: \include MatrixBase_homogeneous.cpp
 * Output: \verbinclude MatrixBase_homogeneous.out
 *
 * \sa VectorwiseOp::homogeneous(), class Homogeneous
 */
template <typename Derived>
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::HomogeneousReturnType MatrixBase<Derived>::homogeneous() const {
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
  return HomogeneousReturnType(derived());
}

/** \geometry_module \ingroup Geometry_Module
 *
 * \returns an expression where the value 1 is symbolically appended as the final coefficient to each column (or row) of
 * the matrix.
 *
 * This can be used to convert affine coordinates to homogeneous coordinates.
 *
 * Example: \include VectorwiseOp_homogeneous.cpp
 * Output: \verbinclude VectorwiseOp_homogeneous.out
 *
 * \sa MatrixBase::homogeneous(), class Homogeneous */
template <typename ExpressionType, int Direction>
EIGEN_DEVICE_FUNC inline Homogeneous<ExpressionType, Direction> VectorwiseOp<ExpressionType, Direction>::homogeneous()
    const {
  return HomogeneousReturnType(_expression());
}

/** \geometry_module \ingroup Geometry_Module
  *
  * \brief homogeneous normalization
  *
  * \returns a vector expression of the N-1 first coefficients of \c *this divided by that last coefficient.
  *
  * This can be used to convert homogeneous coordinates to affine coordinates.
  *
  * It is essentially a shortcut for:
  * \code
    this->head(this->size()-1)/this->coeff(this->size()-1);
    \endcode
  *
  * Example: \include MatrixBase_hnormalized.cpp
  * Output: \verbinclude MatrixBase_hnormalized.out
  *
  * \sa VectorwiseOp::hnormalized() */
template <typename Derived>
EIGEN_DEVICE_FUNC inline const typename MatrixBase<Derived>::HNormalizedReturnType MatrixBase<Derived>::hnormalized()
    const {
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
  return ConstStartMinusOne(derived(), 0, 0, ColsAtCompileTime == 1 ? size() - 1 : 1,
                            ColsAtCompileTime == 1 ? 1 : size() - 1) /
         coeff(size() - 1);
}

/** \geometry_module \ingroup Geometry_Module
 *
 * \brief column or row-wise homogeneous normalization
 *
 * \returns an expression of the first N-1 coefficients of each column (or row) of \c *this divided by the last
 * coefficient of each column (or row).
 *
 * This can be used to convert homogeneous coordinates to affine coordinates.
 *
 * It is conceptually equivalent to calling MatrixBase::hnormalized() to each column (or row) of \c *this.
 *
 * Example: \include DirectionWise_hnormalized.cpp
 * Output: \verbinclude DirectionWise_hnormalized.out
 *
 * \sa MatrixBase::hnormalized() */
template <typename ExpressionType, int Direction>
EIGEN_DEVICE_FUNC inline const typename VectorwiseOp<ExpressionType, Direction>::HNormalizedReturnType
VectorwiseOp<ExpressionType, Direction>::hnormalized() const {
  return HNormalized_Block(_expression(), 0, 0, Direction == Vertical ? _expression().rows() - 1 : _expression().rows(),
                           Direction == Horizontal ? _expression().cols() - 1 : _expression().cols())
      .cwiseQuotient(Replicate < HNormalized_Factors, Direction == Vertical ? HNormalized_SizeMinusOne : 1,
                     Direction == Horizontal
                         ? HNormalized_SizeMinusOne
                         : 1 > (HNormalized_Factors(_expression(), Direction == Vertical ? _expression().rows() - 1 : 0,
                                                    Direction == Horizontal ? _expression().cols() - 1 : 0,
                                                    Direction == Vertical ? 1 : _expression().rows(),
                                                    Direction == Horizontal ? 1 : _expression().cols()),
                                Direction == Vertical ? _expression().rows() - 1 : 1,
                                Direction == Horizontal ? _expression().cols() - 1 : 1));
}

namespace internal {

template <typename MatrixOrTransformType>
struct take_matrix_for_product {
  typedef MatrixOrTransformType type;
  EIGEN_DEVICE_FUNC static const type& run(const type& x) { return x; }
};

template <typename Scalar, int Dim, int Mode, int Options>
struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> > {
  typedef Transform<Scalar, Dim, Mode, Options> TransformType;
  typedef std::add_const_t<typename TransformType::ConstAffinePart> type;
  EIGEN_DEVICE_FUNC static type run(const TransformType& x) { return x.affine(); }
};

template <typename Scalar, int Dim, int Options>
struct take_matrix_for_product<Transform<Scalar, Dim, Projective, Options> > {
  typedef Transform<Scalar, Dim, Projective, Options> TransformType;
  typedef typename TransformType::MatrixType type;
  EIGEN_DEVICE_FUNC static const type& run(const TransformType& x) { return x.matrix(); }
};

template <typename MatrixType, typename Lhs>
struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType, Vertical>, Lhs> > {
  typedef typename take_matrix_for_product<Lhs>::type LhsMatrixType;
  typedef remove_all_t<MatrixType> MatrixTypeCleaned;
  typedef remove_all_t<LhsMatrixType> LhsMatrixTypeCleaned;
  typedef typename make_proper_matrix_type<
      typename traits<MatrixTypeCleaned>::Scalar, LhsMatrixTypeCleaned::RowsAtCompileTime,
      MatrixTypeCleaned::ColsAtCompileTime, MatrixTypeCleaned::PlainObject::Options,
      LhsMatrixTypeCleaned::MaxRowsAtCompileTime, MatrixTypeCleaned::MaxColsAtCompileTime>::type ReturnType;
};

template <typename MatrixType, typename Lhs>
struct homogeneous_left_product_impl<Homogeneous<MatrixType, Vertical>, Lhs>
    : public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType, Vertical>, Lhs> > {
  typedef typename traits<homogeneous_left_product_impl>::LhsMatrixType LhsMatrixType;
  typedef remove_all_t<LhsMatrixType> LhsMatrixTypeCleaned;
  typedef remove_all_t<typename LhsMatrixTypeCleaned::Nested> LhsMatrixTypeNested;
  EIGEN_DEVICE_FUNC homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs)
      : m_lhs(take_matrix_for_product<Lhs>::run(lhs)), m_rhs(rhs) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
  EIGEN_DEVICE_FUNC constexpr Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }

  template <typename Dest>
  EIGEN_DEVICE_FUNC void evalTo(Dest& dst) const {
    // FIXME investigate how to allow lazy evaluation of this product when possible
    dst = Block < const LhsMatrixTypeNested, LhsMatrixTypeNested::RowsAtCompileTime,
    LhsMatrixTypeNested::ColsAtCompileTime == Dynamic
        ? Dynamic
        : LhsMatrixTypeNested::ColsAtCompileTime - 1 > (m_lhs, 0, 0, m_lhs.rows(), m_lhs.cols() - 1) * m_rhs;
    dst += m_lhs.col(m_lhs.cols() - 1).rowwise().template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols());
  }

  typename LhsMatrixTypeCleaned::Nested m_lhs;
  typename MatrixType::Nested m_rhs;
};

template <typename MatrixType, typename Rhs>
struct traits<homogeneous_right_product_impl<Homogeneous<MatrixType, Horizontal>, Rhs> > {
  typedef
      typename make_proper_matrix_type<typename traits<MatrixType>::Scalar, MatrixType::RowsAtCompileTime,
                                       Rhs::ColsAtCompileTime, MatrixType::PlainObject::Options,
                                       MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime>::type ReturnType;
};

template <typename MatrixType, typename Rhs>
struct homogeneous_right_product_impl<Homogeneous<MatrixType, Horizontal>, Rhs>
    : public ReturnByValue<homogeneous_right_product_impl<Homogeneous<MatrixType, Horizontal>, Rhs> > {
  typedef remove_all_t<typename Rhs::Nested> RhsNested;
  EIGEN_DEVICE_FUNC homogeneous_right_product_impl(const MatrixType& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
  EIGEN_DEVICE_FUNC constexpr Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }

  template <typename Dest>
  EIGEN_DEVICE_FUNC void evalTo(Dest& dst) const {
    // FIXME investigate how to allow lazy evaluation of this product when possible
    dst = m_lhs * Block < const RhsNested,
    RhsNested::RowsAtCompileTime == Dynamic ? Dynamic : RhsNested::RowsAtCompileTime - 1,
    RhsNested::ColsAtCompileTime > (m_rhs, 0, 0, m_rhs.rows() - 1, m_rhs.cols());
    dst += m_rhs.row(m_rhs.rows() - 1).colwise().template replicate<MatrixType::RowsAtCompileTime>(m_lhs.rows());
  }

  typename MatrixType::Nested m_lhs;
  typename Rhs::Nested m_rhs;
};

template <typename ArgType, int Direction>
struct evaluator_traits<Homogeneous<ArgType, Direction> > {
  typedef typename storage_kind_to_evaluator_kind<typename ArgType::StorageKind>::Kind Kind;
  typedef HomogeneousShape Shape;
};

template <>
struct AssignmentKind<DenseShape, HomogeneousShape> {
  typedef Dense2Dense Kind;
};

template <typename ArgType, int Direction>
struct unary_evaluator<Homogeneous<ArgType, Direction>, IndexBased>
    : evaluator<typename Homogeneous<ArgType, Direction>::PlainObject> {
  typedef Homogeneous<ArgType, Direction> XprType;
  typedef typename XprType::PlainObject PlainObject;
  typedef evaluator<PlainObject> Base;

  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op) : Base(), m_temp(op) {
    internal::construct_at<Base>(this, m_temp);
  }

 protected:
  PlainObject m_temp;
};

// dense = homogeneous
template <typename DstXprType, typename ArgType, typename Scalar>
struct Assignment<DstXprType, Homogeneous<ArgType, Vertical>, internal::assign_op<Scalar, typename ArgType::Scalar>,
                  Dense2Dense> {
  typedef Homogeneous<ArgType, Vertical> SrcXprType;
  EIGEN_DEVICE_FUNC static void run(DstXprType& dst, const SrcXprType& src,
                                    const internal::assign_op<Scalar, typename ArgType::Scalar>&) {
    Index dstRows = src.rows();
    Index dstCols = src.cols();
    if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);

    dst.template topRows<ArgType::RowsAtCompileTime>(src.nestedExpression().rows()) = src.nestedExpression();
    dst.row(dst.rows() - 1).setOnes();
  }
};

// dense = homogeneous
template <typename DstXprType, typename ArgType, typename Scalar>
struct Assignment<DstXprType, Homogeneous<ArgType, Horizontal>, internal::assign_op<Scalar, typename ArgType::Scalar>,
                  Dense2Dense> {
  typedef Homogeneous<ArgType, Horizontal> SrcXprType;
  EIGEN_DEVICE_FUNC static void run(DstXprType& dst, const SrcXprType& src,
                                    const internal::assign_op<Scalar, typename ArgType::Scalar>&) {
    Index dstRows = src.rows();
    Index dstCols = src.cols();
    if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);

    dst.template leftCols<ArgType::ColsAtCompileTime>(src.nestedExpression().cols()) = src.nestedExpression();
    dst.col(dst.cols() - 1).setOnes();
  }
};

template <typename LhsArg, typename Rhs, int ProductTag>
struct generic_product_impl<Homogeneous<LhsArg, Horizontal>, Rhs, HomogeneousShape, DenseShape, ProductTag> {
  template <typename Dest>
  EIGEN_DEVICE_FUNC static void evalTo(Dest& dst, const Homogeneous<LhsArg, Horizontal>& lhs, const Rhs& rhs) {
    homogeneous_right_product_impl<Homogeneous<LhsArg, Horizontal>, Rhs>(lhs.nestedExpression(), rhs).evalTo(dst);
  }
};

template <typename Lhs, typename Rhs>
struct homogeneous_right_product_refactoring_helper {
  enum { Dim = Lhs::ColsAtCompileTime, Rows = Lhs::RowsAtCompileTime };
  typedef typename Rhs::template ConstNRowsBlockXpr<Dim>::Type LinearBlockConst;
  typedef std::remove_const_t<LinearBlockConst> LinearBlock;
  typedef typename Rhs::ConstRowXpr ConstantColumn;
  typedef Replicate<const ConstantColumn, Rows, 1> ConstantBlock;
  typedef Product<Lhs, LinearBlock, LazyProduct> LinearProduct;
  typedef CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar, typename Rhs::Scalar>, const LinearProduct,
                        const ConstantBlock>
      Xpr;
};

template <typename Lhs, typename Rhs, int ProductTag>
struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, HomogeneousShape, DenseShape>
    : public evaluator<
          typename homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression, Rhs>::Xpr> {
  typedef Product<Lhs, Rhs, LazyProduct> XprType;
  typedef homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression, Rhs> helper;
  typedef typename helper::ConstantBlock ConstantBlock;
  typedef typename helper::Xpr RefactoredXpr;
  typedef evaluator<RefactoredXpr> Base;

  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
      : Base(xpr.lhs().nestedExpression().lazyProduct(
                 xpr.rhs().template topRows<helper::Dim>(xpr.lhs().nestedExpression().cols())) +
             ConstantBlock(xpr.rhs().row(xpr.rhs().rows() - 1), xpr.lhs().rows(), 1)) {}
};

template <typename Lhs, typename RhsArg, int ProductTag>
struct generic_product_impl<Lhs, Homogeneous<RhsArg, Vertical>, DenseShape, HomogeneousShape, ProductTag> {
  template <typename Dest>
  EIGEN_DEVICE_FUNC static void evalTo(Dest& dst, const Lhs& lhs, const Homogeneous<RhsArg, Vertical>& rhs) {
    homogeneous_left_product_impl<Homogeneous<RhsArg, Vertical>, Lhs>(lhs, rhs.nestedExpression()).evalTo(dst);
  }
};

// TODO: the following specialization is to address a regression from 3.2 to 3.3
// In the future, this path should be optimized.
template <typename Lhs, typename RhsArg, int ProductTag>
struct generic_product_impl<Lhs, Homogeneous<RhsArg, Vertical>, TriangularShape, HomogeneousShape, ProductTag> {
  template <typename Dest>
  static void evalTo(Dest& dst, const Lhs& lhs, const Homogeneous<RhsArg, Vertical>& rhs) {
    dst.noalias() = lhs * rhs.eval();
  }
};

template <typename Lhs, typename Rhs>
struct homogeneous_left_product_refactoring_helper {
  enum { Dim = Rhs::RowsAtCompileTime, Cols = Rhs::ColsAtCompileTime };
  typedef typename Lhs::template ConstNColsBlockXpr<Dim>::Type LinearBlockConst;
  typedef std::remove_const_t<LinearBlockConst> LinearBlock;
  typedef typename Lhs::ConstColXpr ConstantColumn;
  typedef Replicate<const ConstantColumn, 1, Cols> ConstantBlock;
  typedef Product<LinearBlock, Rhs, LazyProduct> LinearProduct;
  typedef CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar, typename Rhs::Scalar>, const LinearProduct,
                        const ConstantBlock>
      Xpr;
};

template <typename Lhs, typename Rhs, int ProductTag>
struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, HomogeneousShape>
    : public evaluator<typename homogeneous_left_product_refactoring_helper<Lhs, typename Rhs::NestedExpression>::Xpr> {
  typedef Product<Lhs, Rhs, LazyProduct> XprType;
  typedef homogeneous_left_product_refactoring_helper<Lhs, typename Rhs::NestedExpression> helper;
  typedef typename helper::ConstantBlock ConstantBlock;
  typedef typename helper::Xpr RefactoredXpr;
  typedef evaluator<RefactoredXpr> Base;

  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
      : Base(xpr.lhs()
                 .template leftCols<helper::Dim>(xpr.rhs().nestedExpression().rows())
                 .lazyProduct(xpr.rhs().nestedExpression()) +
             ConstantBlock(xpr.lhs().col(xpr.lhs().cols() - 1), 1, xpr.rhs().cols())) {}
};

template <typename Scalar, int Dim, int Mode, int Options, typename RhsArg, int ProductTag>
struct generic_product_impl<Transform<Scalar, Dim, Mode, Options>, Homogeneous<RhsArg, Vertical>, DenseShape,
                            HomogeneousShape, ProductTag> {
  typedef Transform<Scalar, Dim, Mode, Options> TransformType;
  template <typename Dest>
  EIGEN_DEVICE_FUNC static void evalTo(Dest& dst, const TransformType& lhs, const Homogeneous<RhsArg, Vertical>& rhs) {
    homogeneous_left_product_impl<Homogeneous<RhsArg, Vertical>, TransformType>(lhs, rhs.nestedExpression())
        .evalTo(dst);
  }
};

template <typename ExpressionType, int Side, bool Transposed>
struct permutation_matrix_product<ExpressionType, Side, Transposed, HomogeneousShape>
    : public permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape> {};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_HOMOGENEOUS_H
