/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#ifndef MATRICES_SUPERMATRIX_H
#define MATRICES_SUPERMATRIX_H

#include "matrices_headers.h"
#include "CCSMatrix.h"
#include "CRSMatrix.h"
#include "Feature.h"

namespace Matrices
{
	/**
	  * Universal storage for compressed matrices. Assumes that access ot both columns and rows can be
	  * needed.
	  * \note Row and column matrices are not autmatically synchronized. For synchronization one should call
	  * SyncCRSToCCS and SyncCCSToCRS
	  * \note Most important class in terms of extraction of Measures of Semantic Relatednes..
	  */
	class MATRICES_API SuperMatrix
	{
	public:
		/**
		  * Creates SuperMatrix class instance. Builds indices of labels based on rowFeatures and columnFeatures.
		  *
		  * \param name Name of the matrix
		  * \param ccs column part of the matrix
		  * \param crs row part of the matrix
		  * \param rowFeatures features of row (crs) matrix
		  * \param columnFeatures features of column (ccs) matrix
		  * \param tokens number of tokens in the corpus
		  * \param corpus_desc description of corpus (corpora) used to create this matrix
		  * \param boundaries operator/relation boundaries or empty set if no boundaries are defined for this matrix
		  **/
		SuperMatrix(const std::string &name, CCSMatrixPtr ccs, CRSMatrixPtr crs,
					FeatureVectorPtr rowFeatures, FeatureVectorPtr columnFeatures,
					size_t tokens, const std::string& corpus_desc, std::map<size_t, std::string> boundaries);
		/**
		  * Almost the same as above, but without the last parameter (compatibility with older gcc)
		  */
		SuperMatrix(const std::string &name, CCSMatrixPtr ccs, CRSMatrixPtr crs,
					FeatureVectorPtr rowFeatures, FeatureVectorPtr columnFeatures,
					size_t tokens, const std::string& corpus_desc);

		~SuperMatrix();
		void SetCorpusInfo(std::string newInfo);
		/// Retrieves name of the matrix
		const std::string& GetName() const;
		/// Retrieves row index by row label
		size_t GetRowIndex(const std::string & rowlabel);
		/// Retrieves row by row label (null pointer when row was not found)
		CompressedVectorPtr GetRow(const std::string & rowlabel);
		/// Retrieves row by row number (null pointer when row was not found)
		CompressedVectorPtr GetRow(size_t rowNo);
		/// Retrieves column index by column label
		size_t GetColumnIndex(const std::string & columnlabel);
		/// Retrieves column by label
		CompressedVectorPtr GetColumn(const std::string &columnLabel);
		/// Retrieves column by column number
		CompressedVectorPtr GetColumn(size_t columnNo);

		/// Retrieves a cell identified by row index (rowInd) and column index (colInd)
		double GetCell(size_t rowInd, size_t colInd);
		/// Retrieves a cell identified by row name (rowLabel) and column name (columnlabel)
		double GetCell(const std::string &rowLabel, const std::string &columnLabel);

		/**
		  * Retrives CCSMatrix part of SuperMatrix
		  * \note Does not update featurs or labels or label index
		  */
		CCSMatrixPtr GetCCS();
		/**
		  * Retrives CRSMatrix part of SuperMatrix
		  * \note Does not update featurs or labels or label index
		  **/
		CRSMatrixPtr GetCRS();
		/// Sets CCSMatrix part of SuperMatrix
		void SetCCS(CCSMatrixPtr  ccs);
		/// Sets CRSMatrix part of SuperMatrix
		void SetCRS(CRSMatrixPtr crs);

		/**
		  * Synchronizes row matrix to column matrix. In ONLY_CCS mode (when ccs matrix was not set) this does nothing.
		  *
		  */
		void SyncCRSToCCS();
		/**
		  * Synchronizes column matrix to row matrix. In ONLY_CRS mode (when crs matrix was not set) this does nothing.
		  *
		  */
		void SyncCCSToCRS();
		/// Sets new name for this matrix
		void SetNewName(std::string newName);

		/**
		  * \return Number of tokes used to create this matrix. -1 if this number is unknown
		*/
		size_t GetTokenCount() const;
		/// Retrieves number of rows
		size_t NumberOfRows() const;
		/// Retrieves number of columns
		size_t NumberOfColumns() const;
		/// Retrieves corpus info
		const std::string& GetCorpusInfo() const;
		/// Retrieves pointer on row feature vector
		FeatureVectorPtr GetRowFeatures();
		/// Retrieves pointer on column feature vector
		FeatureVectorPtr GetColumnFeatures();
		/// Sets new row feature vector and rebuilds the rows labels index
		void SetRowFeatures(FeatureVectorPtr fp);
		/// Sets new column feature vector and rebuilds the columns labels index
		void SetColumnFeatures(FeatureVectorPtr fp);

		/// Access to operator/relation boundaries
		std::map<size_t, std::string >& Boundaries();

		void SetBoundaries(std::map<size_t, std::string > newBoundaries);

		void Clone(boost::shared_ptr<SuperMatrix> &matrix);
		void SetTokenCount(size_t newCount);

	private:
		std::map<size_t, std::string> m_mapOperatorBoundaries;
		/**
		  Number of tokens (words, lexical units, or whatever is defined as a token) processed during creation of this matrix
		*/
		size_t m_cTokens;
		/**
		 * Name of this matrix
		 */
		std::string m_sName;
		/**
		 * CCS part of this matrix
		 */
		CCSMatrixPtr m_pCCSMatrix;
		/**
		 * CRS part of this matrix
		*/
		CRSMatrixPtr m_pCRSMatrix;
		/// Row features
		FeatureVectorPtr m_pRowFeatures;
		/// Column features
		FeatureVectorPtr m_pColumnFeatures;
		/// Row labels index
		LabelIndex m_RowLabelIndex;
		/// Column labels index
		LabelIndex m_ColumnLabelIndex;
		/// Corpus description
		std::string m_sCorpusDescription;

	};
	/// Shared pointer on SuperMatrix
	typedef boost::shared_ptr<SuperMatrix> SuperMatrixPtr;

}// namespace Matrices

#endif //MATRICES_SUPERMATRIX_H
