%module pymatrices
%{
#include "matrices_headers.h"
#include "CompressedVector.h"
#include "Matrix.h"
#include "CRSMatrix.h"
#include "CCSMatrix.h"
#include "Feature.h"
#include "SuperMatrix.h"
#include "measures.h"
#include "io/SuperMatrixReader.h"
%}

%include "std_vector.i"
%include "std_map.i"
%include "std_string.i"
%include "std_set.i"

namespace std {
   %template(vectori) vector<int>;
   %template(mapsts) map<size_t, string>;
   %template(vectord) vector<double>;

   %template(mapstd) map<size_t,double>;
};

namespace boost {
  template<class T> class shared_ptr
  {
		public:
			shared_ptr();
			shared_ptr (T * p);
			T * operator-> () ;
		private:
			T * px;
			int pn;
  };
}

namespace Matrices
{
	class CompressedVector
	{
	public:
		CompressedVector(size_t uncompressedSize, double* uncompressedData = NULL);
		CompressedVector(const std::vector<double> &uncompressedData);
		void SetElement(size_t index, double val);
		std::map<size_t, double>* GetValues();
		size_t GetUncompresseSize() const;
		%rename(GetElement) operator[];
		double operator[](size_t n) const;
		virtual ~CompressedVector();
	};
};
	%template(CompressedVectorPtr) boost::shared_ptr<Matrices::CompressedVector>;
namespace Matrices
{
	typedef boost::shared_ptr<CompressedVector> CompressedVectorPtr;

	class Matrix
	{
	public:
		Matrix(const std::string &name, size_t rows, size_t columns);
		virtual ~Matrix(void){}
		virtual size_t NumberOfRows() const;
		virtual size_t NumberOfColumns();
		virtual void SetCell(double val, size_t rowInd, size_t colInd) = 0;
		virtual double GetCell(size_t rowInd, size_t colInd) = 0;
		virtual void Clear() = 0;
		virtual void AddToCell(double value, size_t rowIndex, size_t columnIndex) = 0;
		virtual void SetDescriptor(const std::string &name, size_t rows, size_t columns);
		const std::string& GetName() const;

	};

	class CRSMatrix : public Matrix
	{
	public:
		CRSMatrix(const std::string &name, size_t rows, size_t columns);
		virtual ~CRSMatrix(void);
		virtual void SetCell(double val, size_t rowInd, size_t colInd);
		virtual double GetCell(size_t rowInd, size_t colInd);
		virtual void Clear();
		virtual void AddToCell(double value, size_t rowIndex, size_t columnIndex);

		CompressedVectorPtr GetCompressedRow(size_t rowInd);

	};

	class CCSMatrix : public Matrix
	{
	public:
		CCSMatrix(const std::string &name, size_t rows, size_t columns);
		virtual ~CCSMatrix(void);
		virtual void SetCell(double val, size_t rowInd, size_t colInd);
		virtual double GetCell(size_t rowInd, size_t colInd);
		virtual void Clear();
		virtual void AddToCell(double value, size_t rowIndex, size_t columnIndex);

		CompressedVectorPtr GetCompressedColumn(size_t colInd);

	};


	class Feature
	{
	public:
		Feature(const std::string &label, size_t nz, size_t tf, size_t TF,
				double entropy);
		size_t GetNZ() const;
		size_t GetTermFrequency() const;
		size_t GetGlobalTermFrequency() const;
		double GetEntropy() const;
		const std::string & GetLabel() const;

		void SetNZ(size_t nz);
		void SetGlobalTermFrequency(size_t TF);
		void SetTermFrequnecy(size_t tf);
		void SetEntropy(size_t entropy);
		void SetLabel(const std::string& label);
	};
}
	%template(FeatureVector) std::vector<Matrices::Feature>;
	%template(FeatureVectorPtr) boost::shared_ptr<std::vector<Matrices::Feature> >;
	%template(CRSMatrixPtr) boost::shared_ptr<Matrices::CRSMatrix> ;
	%template(CCSMatrixPtr) boost::shared_ptr<Matrices::CCSMatrix> ;

namespace Matrices
{
	typedef boost::shared_ptr<CCSMatrix> CCSMatrixPtr;
	typedef boost::shared_ptr<CRSMatrix> CRSMatrixPtr;
	typedef std::vector<Feature> FeatureVector;
	typedef boost::shared_ptr<FeatureVector> FeatureVectorPtr;

	class SuperMatrix
	{
	public:
		SuperMatrix(const std::string &name, CCSMatrixPtr ccs, CRSMatrixPtr crs,
				FeatureVectorPtr rowFeatures, FeatureVectorPtr columnFeatures,
				size_t tokens, const std::string& corpus_desc);

		~SuperMatrix();
		std::string GetName() const;
		CompressedVectorPtr GetRow(const std::string & rowlabel);
		CompressedVectorPtr GetRow(size_t rowNo);
		CompressedVectorPtr GetColumn(const std::string &columnLabel);
		CompressedVectorPtr GetColumn(size_t columnNo);
		CCSMatrixPtr GetCCS();
		CRSMatrixPtr GetCRS();
		void SetCCS(CCSMatrixPtr  ccs);
		void SetCRS(CRSMatrixPtr crs);
		void SyncCRSToCCS();
		void SyncCCSToCRS();
		void SetNewName(std::string newName);
		size_t GetTokenCount() const;
		size_t NumberOfRows() const;
		size_t NumberOfColumns() const;
		const std::string& GetCorpusInfo() const;
		FeatureVectorPtr GetRowFeatures();
		FeatureVectorPtr GetColumnFeatures();
		void SetRowFeatures(FeatureVectorPtr fp);
		void SetColumnFeatures(FeatureVectorPtr fp);
		size_t GetRowIndex(const std::string & rowlabel);
		size_t GetColumnIndex(const std::string & columnlabel);
		std::map<size_t, std::string>& Boundaries();
    double GetCell(size_t rowInd, size_t colInd);
    double GetCell(const std::string &rowLabel, const std::string &columnLabel);
	};
}

	%template(SuperMatrixPtr) boost::shared_ptr<Matrices::SuperMatrix> ;
namespace Matrices
{
	typedef boost::shared_ptr<SuperMatrix> SuperMatrixPtr;
	namespace IO
	{
		SuperMatrixPtr LoadSuperMatrix(const std::string &dir,const std::string &name, bool ccs = true, bool crs = true);
		void WriteSuperMatrix(SuperMatrixPtr m, const std::string &dir);
		void WriteToSingleFile(CCSMatrixPtr pMatrix, const std::string &filename);
		SuperMatrixPtr LoadSuperMatrixFiltered(const std::string &words_file, const std::string &dir, const std::string &name,
			bool load_by_columns = true, bool load_by_rows = true, bool filter_rows = true,	bool filter_columns = true);
	};

};

namespace Matrices
{
	CCSMatrixPtr GetNewCCSMatrix(const std::string &name, size_t rows, size_t columns);
	CRSMatrixPtr GetNewCRSMatrix(const std::string &name, size_t rows, size_t columns);
};

namespace Measures
{
  double CountVectorSum(Matrices::CompressedVectorPtr v);
  double CountVectorEntropy(Matrices::CompressedVectorPtr v);
  double CountVectorSum(Matrices::CompressedVector& v);
  double CountVectorEntropy(Matrices::CompressedVector& v);
};

