// This is core/vnl/vnl_crs_index.h
#ifndef vnl_crs_index_h_
#define vnl_crs_index_h_
//:
// \file
// \brief Compressed Row Storage (CRS) indexing
// \author Matt Leotta (Brown)
// \date   April 13, 2005
//
// \verbatim
//  Modifications
// \endverbatim
//
#include <vector>
#include <utility>
#ifdef _MSC_VER
#  include <vcl_msvc_warnings.h>
#endif
#include "vnl/vnl_export.h"

//: Represents the configuration of a sparse matrix but not the data
//  This is essentially a sparse matrix of indices into a data vector
//  Compressed row storage is used for representation
//  This class is useful when working with several sparse matrices that
//  share a common sparse structure.
class VNL_EXPORT vnl_crs_index
{
public:
  typedef std::pair<int, int> idx_pair;
  typedef std::vector<idx_pair> sparse_vector;

  //: Constructor - default
  vnl_crs_index()
    : col_idx_()
    , row_ptr_()
  {}

  //: Constructor - from a binary mask
  vnl_crs_index(const std::vector<std::vector<bool>> & mask);

  //: Destructor
  ~vnl_crs_index() = default;

  //: number of rows in the sparse matrix
  int
  num_rows() const
  {
    return int(row_ptr_.size()) - 1;
  }

  //: number of columns in the sparse matrix
  int
  num_cols() const
  {
    return num_cols_;
  }

  //: number of non-zero elements
  int
  num_non_zero() const
  {
    return int(col_idx_.size());
  }

  //: returns row \p i as a vector of index-column pairs
  sparse_vector
  sparse_row(int i) const;

  //: returns column \p j as a vector of index-row pairs
  // \note because of CRS this method is a bit less efficient than sparse_row
  sparse_vector
  sparse_col(int j) const;

  //: return the index at location (i,j)
  //  returns -1 if the entry is 0
  int
  operator()(int i, int j) const;

private:
  //: The number of columns in the matrix
  unsigned int num_cols_{ 0 };
  //: The column for each non-zero element
  std::vector<int> col_idx_;
  //: The index of the first non-zero element in each row
  std::vector<int> row_ptr_;
};

#endif // vnl_crs_index_h_
