/*
    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_MATRIX
#define MATRICES_MATRIX

#include "matrices_headers.h"

/**
  * Namesapce with operation on abstract matrices
  */
namespace Matrices
{
	/**
	  * Abstract matrix class. Defines operations that all matrices should implement.
	  * \note Matrices derived from this class are used in developing of measures of semantic relatedness mainly.
	  * \todo Is common (dynamic) matrix interface really needed when boost::ublas is available? Probably not
	  */
	class MATRICES_API Matrix
	{
	protected:
		/// Name of a matrix
		std::string m_sName;
		/// Number of rows
		size_t	m_stRows;
		/// Number of columns
		size_t	m_stColumns;


	public:
		/**
		  * Matrix is constructed by using at least three parameters:
		  * - name of a matrix
		  * - number of rows in a matrix
		  * - number of columns in a matrix
		  */
		Matrix(const std::string &name, size_t rows, size_t columns)
			: m_sName(name), m_stRows(rows), m_stColumns(columns)
		{
		}

		virtual ~Matrix(void){}
		/**
		  * Returns column of a matrix as a double array. Memory management is defined by derived class.
		  *	\param colNo Number of column to retrieve.
		  * \deprecated Will be removed in future version - basically it is unused in dealing with sparse matrices
		  */
		virtual double* GetColumn(size_t colNo) = 0;
		/**
		  * Returns row of a matrix as a double array. Memory management is defined by derived class.
		  *	\param rowNo Number of row to retrieve.
		  * \deprecated Will be removed in future version - basically it is unused in dealing with sparse matrices
		  */
		virtual double* GetRow(size_t rowNo) = 0;
		/**
		  * Returns number of rows in a matrix.
		  */
		virtual size_t NumberOfRows() const{ return m_stRows; }
		/**
		  * Returns number of columns in a matrix.
		  */
		virtual size_t NumberOfColumns() const { return m_stColumns;}
		/**
		  * Returns number of rows in a matrix.
		  */
		virtual double* operator[](size_t rowNo) = 0;
		/**
		  * Sets row in a matrix.
		  */
		virtual void SetRow(std::vector<double> &row, size_t rowIndex) = 0;
		/**
		  * Sets row in a matrix. Assumes that size of row is equal to number of columns in a matrix.
		  */
		virtual void SetRow(double* row, size_t rowIndex) = 0;
		/**
		 * Sets column in a matrix.
		 */
		virtual void SetColumn(double* col, size_t colIndex) = 0;
		/**
		 * Adds given row to a pointed row in a matrix by rowIndex.
		 */
		virtual void SumRows(double *row, size_t rowIndex)=0;
		/**
		 * Matrix transposition. 
		 * \param returnMatrix Pointer to matrix which will hold transposed matrix.
		 * \return returnMatrix
		 * \deprecated This should be a helper function and not a core matrix functionality.
		 */
		virtual Matrix*& Transpose(Matrix*&  returnMatrix)=0;
		/**
		 * Sets a value in a cell identified by row index (rowInd) and column index (colInd)
		 **/
		virtual void SetCell(double val, size_t rowInd, size_t colInd) = 0;
		/**
		 * Retrieves a cell identified by row index (rowInd) and column index (colInd)
		 **/
		virtual double GetCell(size_t rowInd, size_t colInd) = 0;
		/**
		  * Clears a matrix (sets all cells = 0)
		  **/
		virtual void Clear() = 0;
		/**
		  * Adds value to cell identified by row index (rowInd) and column index (colInd)
		  **/
		virtual void AddToCell(double value, size_t rowIndex, size_t columnIndex) = 0;
		/**
		  * Clones a matrix
		  */ 
		virtual void Clone(Matrix* matrix) = 0;
		/**
		  * Frees memory assigned by f.e. GetRow (if needed, see description of a implementation of a function for given
		  * matrix)
		  */
		virtual void FreeMem(double * &ptr) const
		{
			delete[] ptr;
			ptr = NULL;
		}
		/**
		 * Changes description of a matrix.
		 * \deprecated This function was left from previous implementation of Matrix, where descriptor was independent
		 * object. It will be removed from future versions.
		 */ 
		virtual void SetDescriptor(const std::string &name, size_t rows, size_t columns)
		{
			m_sName = name;
			m_stRows = rows;
			m_stColumns = columns;
		}

		/**
		 * Retrieves matrix name
		 */ 
		const std::string& GetName() const
		{
			return m_sName;
		}

	};


	typedef boost::shared_ptr<Matrix> MatrixPtr;
}

#endif //MATRICES_MATRIX

