#ifndef matrixmap_h
#define matrixmap_h

// this defines things needed by ocmatrix
#include <OS/list.h>

#include "ocmatrix.h"
#include "nrnoc2iv.h"

class MatrixMap {
public:
	MatrixMap(Matrix*);
	MatrixMap(Matrix&);
	~MatrixMap();

	void alloc(int, int, Node**, int*);
	void mmfree();
	void add(double fac);

	// passthroughs for accessing m_
	inline void mulv(Vect& in, Vect& out) {m_.mulv(in, out);};
	inline void mulv(Vect* in, Vect* out) {m_.mulv(in, out);};
	inline void mulm(Matrix* in, Matrix* out) {m_.mulm(in, out);};
	inline void muls(double a, Matrix* out) {m_.muls(a, out);};
	inline void add(Matrix* a, Matrix* out) {m_.add(a, out);};
	inline void getrow(int r, Vect* out) {m_.getrow(r, out);};
	inline void getcol(int c, Vect* out) {m_.getcol(c, out);};
	inline double& operator() (int i, int j) {return m_(i, j);};
	inline int nrow() {return m_.nrow();};
	inline int ncol() {return m_.ncol();};
	inline double* mep(int i, int j) {return m_.mep(i, j);};
	inline void getdiag(int d, Vect* out) {m_.getdiag(d, out);}
	inline void setrow(int r, Vect* in){m_.setrow(r, in);}
	inline void setcol(int c, Vect* in){m_.setcol(c, in);}
	inline void setdiag(int d, Vect* in){m_.setdiag(d, in);}
	inline void setrow(int r, double in){m_.setrow(r, in);}
	inline void setcol(int c, double in){m_.setcol(c, in);}
	inline void setdiag(int d, double in){m_.setdiag(d, in);}
	inline void zero(){m_.zero();}
	inline void ident(){m_.ident();}
	inline void exp(Matrix* out){m_.exp(out);}
	inline void pow(int p, Matrix* out){m_.pow(p, out);}
	inline void inverse(Matrix* out){m_.inverse(out);}
	inline void solv(Vect* vin, Vect* vout, bool use_lu) {m_.solv(vin, vout, use_lu);}
	inline void copy(Matrix* out){m_.copy(out);}
	inline void bcopy(Matrix* mout, int i0, int j0, int n0, int m0, int i1, int j1) {
		m_.bcopy(mout, i0, j0, n0, m0, i1, j1);
	}
	inline void transpose(Matrix* out){m_.transpose(out);}
	inline void symmeigen(Matrix* mout, Vect* vout){m_.symmeigen(mout, vout);}
	inline void svd1(Matrix* u, Matrix* v, Vect* d){m_.svd1(u, v, d);}
	inline double det(int* e){return m_.det(e);}
	inline int sprowlen(int a){return m_.sprowlen(a);}
	inline double spgetrowval(int i, int jindx, int* j){return m_.spgetrowval(i, jindx, j);}


private:
	Matrix& m_;

	// the map
	int plen_;
	double** pm_;
	double** ptree_;
};

#endif
