// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.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_SKYLINEMATRIXBASE_H
#define EIGEN_SKYLINEMATRIXBASE_H

#include "SkylineUtil.h"

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

namespace Eigen {

/** \ingroup Skyline_Module
 *
 * \class SkylineMatrixBase
 *
 * \brief Base class of any skyline matrices or skyline expressions
 *
 * \param Derived
 *
 */
template <typename Derived>
class SkylineMatrixBase : public EigenBase<Derived> {
 public:
  typedef typename internal::traits<Derived>::Scalar Scalar;
  typedef typename internal::traits<Derived>::StorageKind StorageKind;
  typedef typename internal::index<StorageKind>::type Index;

  enum {
    RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
    /**< The number of rows at compile-time. This is just a copy of the value provided
     * by the \a Derived type. If a value is not known at compile-time,
     * it is set to the \a Dynamic constant.
     * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */

    ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
    /**< The number of columns at compile-time. This is just a copy of the value provided
     * by the \a Derived type. If a value is not known at compile-time,
     * it is set to the \a Dynamic constant.
     * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */

    SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::ret),
    /**< This is equal to the number of coefficients, i.e. the number of
     * rows times the number of columns, or to \a Dynamic if this is not
     * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */

    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,

    MaxSizeAtCompileTime = (internal::size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime)),

    IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
    /**< This is set to true if either the number of rows or the number of
     * columns is known at compile-time to be equal to 1. Indeed, in that case,
     * we are dealing with a column-vector (if there is only one column) or with
     * a row-vector (if there is only one row). */

    Flags = internal::traits<Derived>::Flags,
    /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
     * constructed from this one. See the \ref flags "list of flags".
     */

    CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
    /**< This is a rough measure of how expensive it is to read one coefficient from
     * this expression.
     */

    IsRowMajor = Flags & RowMajorBit ? 1 : 0
  };

#ifndef EIGEN_PARSED_BY_DOXYGEN
  /** This is the "real scalar" type; if the \a Scalar type is already real numbers
   * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
   * \a Scalar is \a std::complex<T> then RealScalar is \a T.
   *
   * \sa class NumTraits
   */
  typedef typename NumTraits<Scalar>::Real RealScalar;

  /** type of the equivalent square matrix */
  typedef Matrix<Scalar, internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
                 internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)>
      SquareMatrixType;

  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }

  inline Derived& derived() { return *static_cast<Derived*>(this); }

  inline Derived& const_cast_derived() const { return *static_cast<Derived*>(const_cast<SkylineMatrixBase*>(this)); }
#endif  // not EIGEN_PARSED_BY_DOXYGEN

  /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
  inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }

  /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
  inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }

  /** \returns the number of coefficients, which is \a rows()*cols().
   * \sa rows(), cols(), SizeAtCompileTime. */
  inline EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return rows() * cols(); }

  /** \returns the number of nonzero coefficients which is in practice the number
   * of stored coefficients. */
  inline Index nonZeros() const { return derived().nonZeros(); }

  /** \returns the size of the storage major dimension,
   * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
  Index outerSize() const { return (int(Flags) & RowMajorBit) ? this->rows() : this->cols(); }

  /** \returns the size of the inner dimension according to the storage order,
   * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
  Index innerSize() const { return (int(Flags) & RowMajorBit) ? this->cols() : this->rows(); }

  bool isRValue() const { return m_isRValue; }

  Derived& markAsRValue() {
    m_isRValue = true;
    return derived();
  }

  SkylineMatrixBase() : m_isRValue(false) { /* TODO check flags */
  }

  inline Derived& operator=(const Derived& other) {
    this->operator= <Derived>(other);
    return derived();
  }

  template <typename OtherDerived>
  inline void assignGeneric(const OtherDerived& other) {
    derived().resize(other.rows(), other.cols());
    for (Index row = 0; row < rows(); row++)
      for (Index col = 0; col < cols(); col++) {
        if (other.coeff(row, col) != Scalar(0)) derived().insert(row, col) = other.coeff(row, col);
      }
    derived().finalize();
  }

  template <typename OtherDerived>
  inline Derived& operator=(const SkylineMatrixBase<OtherDerived>& other) {
    // TODO
  }

  template <typename Lhs, typename Rhs>
  inline Derived& operator=(const SkylineProduct<Lhs, Rhs, SkylineTimeSkylineProduct>& product);

  friend std::ostream& operator<<(std::ostream& s, const SkylineMatrixBase& m) {
    s << m.derived();
    return s;
  }

  template <typename OtherDerived>
  const typename SkylineProductReturnType<Derived, OtherDerived>::Type operator*(
      const MatrixBase<OtherDerived>& other) const;

  /** \internal use operator= */
  template <typename DenseDerived>
  void evalTo(MatrixBase<DenseDerived>& dst) const {
    dst.setZero();
    for (Index i = 0; i < rows(); i++)
      for (Index j = 0; j < rows(); j++) dst(i, j) = derived().coeff(i, j);
  }

  Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime> toDense() const { return derived(); }

  /** \returns the matrix or vector obtained by evaluating this expression.
   *
   * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
   * a const reference, in order to avoid a useless copy.
   */
  EIGEN_STRONG_INLINE const typename internal::eval<Derived, IsSkyline>::type eval() const {
    return typename internal::eval<Derived>::type(derived());
  }

 protected:
  bool m_isRValue;
};

}  // end namespace Eigen

#endif  // EIGEN_SKYLINEMATRIXBASE_H
