/* ----------------------------------------------------------------------- *//**
 *
 * @file Matrix.hpp
 *
 * @brief MADlib mutable matrix class -- a thin wrapper around arma::Mat
 *
 *//* ----------------------------------------------------------------------- */

/**
 * @brief MADlib mutable matrix class -- a thin wrapper around arma::Mat
 *
 * Armadillo does not provide a public interface to rebind the chunk of memory 
 * an arma::Mat<eT> object is using. We therefore need this subclass to 
 * make matrix objects first-class citizen in the C++ DBAL.
 *
 * @internal Inheritance is not without issues here, and in a future version
 *     we might want to switch to composition instead of inheritance (in order
 *     to make it less likely that changes in the superclass break our
 *     implementation).
 */
template<typename eT>
class Matrix : public arma::Mat<eT> {
public:
    inline Matrix()
        : arma::Mat<eT>(
            NULL,
            0,
            0,
            false /* copy_aux_mem */,
            true /* strict */),
          mMemoryHandle() { }

    inline Matrix(
        AllocatorSPtr inAllocator,
        const uint32_t inNumRows,
        const uint32_t inNumCols)
        : arma::Mat<eT>(
            NULL,
            inNumRows,
            inNumCols,
            false /* copy_aux_mem */,
            true /* strict */),
          mMemoryHandle(
            inAllocator->allocateArray(
                inNumRows * inNumCols,
                static_cast<eT*>(NULL) /* pure type parameter */)) {
        
        arma::access::rw(arma::Mat<eT>::mem) = mMemoryHandle->ptr();
    }

    inline Matrix(
        const MemHandleSPtr inHandle,
        const uint32_t inNumRows,
        const uint32_t inNumCols)
        : arma::Mat<eT>(
            static_cast<eT*>(inHandle->ptr()),
            inNumRows,
            inNumCols,
            false /* copy_aux_mem */,
            true /* strict */),
          mMemoryHandle(inHandle)
        { }
    
    inline Matrix(
        const Matrix<eT> &inMat)
        : arma::Mat<eT>(
            NULL,
            inMat.n_rows,
            inMat.n_cols,
            false /* copy_aux_mem */,
            true /* strict */),
          mMemoryHandle(AbstractHandle::cloneIfNotGlobal(inMat.mMemoryHandle)) {
    
        arma::access::rw(arma::Mat<eT>::mem) = static_cast<eT*>(
            mMemoryHandle->ptr());
    }
    
    template<typename T1>
    inline const Matrix &operator=(const arma::Base<eT,T1>& X) {
        using arma::Mat;
    
        Mat<eT>::operator=(X.get_ref());
        return *this;
    }

    /**
     * @brief Rebind the array to a different chunk of memory (referred to by a
     *     memory handle)
     *
     * @param inHandle the memory handle
     * @param inNumRows number of rows after the reallocation
     * @param inNumCols number of columns after the reallocation
     */
    inline Matrix &rebind(
        const MemHandleSPtr inHandle,
        const uint32_t inNumRows,
        const uint32_t inNumCols) {
        
        using arma::access;
        using arma::Mat;
        
        access::rw(Mat<eT>::n_rows) = inNumRows;
        access::rw(Mat<eT>::n_cols) = inNumCols;
        access::rw(Mat<eT>::n_elem) = inNumRows * inNumCols;
        access::rw(Mat<eT>::mem) = static_cast<eT*>(inHandle->ptr());
        mMemoryHandle = inHandle;
        return *this;
    }

    inline MemHandleSPtr memoryHandle() const {
        return mMemoryHandle;
    }

protected:
    MemHandleSPtr mMemoryHandle;
};
