/****************************************************************************************

		MatrixMN.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Vector Math Library, Release 2.0,  1/1/96 
		Copyright 1996 Alec Miller, All Rights Reserved 

		Revision History

		when		who			what & why
		==========	==========	======================================================
		5/15/96		Alec		new today - added vector math library to InfiniD project

*****************************************************************************************/

#ifndef H_MATRIXMN
#define H_MATRIXMN

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCBasicTypes.h"
#include "MCArray.h"
#include "MCPtrArray.h"
#include "VectorN.h"


/// This is never used, so it might be buggy...
///
template<class T> class TMatrixMN : public TMCObject
{
	public:
		TMatrixMN				(void);
		TMatrixMN				(const uint32 rows, const uint32 columns);
		TMatrixMN				(const TMatrixMN& m);
		~TMatrixMN				(void);

		
		// dynamically grow the matrix
		void SetDimension		(const int32 rowDimension, const int32 columnDimension);
		
		// destruction		
		void ReleaseStorage		(void); // eliminates storage (dimensions set to 0)
		
		// current row and column dimension access					
		inline uint32 GetRowDimension		(void) const;
		inline uint32 GetColumnDimension	(void) const;

		inline uint32 GetRowCount() const	 { return fCurrentColumnDimension; }
		inline uint32 GetColumnCount() const { return fCurrentRowDimension; }
		
		// element access
		inline T  operator()				(const uint32 row, const uint32 col) const;
		inline T& operator()				(const uint32 row, const uint32 col);


		void	AddRow(TVectorN<T>& row);
		void	AddColumn(TVectorN<T>& column);

		void	RemoveColumn(int32 colToDelete);
		void	RemoveLine(int32 lineToDelete);

		void	SwapLines(int32 l1,int32 l2);
		void	SwapColumns(int32 c1,int32 c2);

		void	MoveLineToTheEnd(int32 rowIndex);
		void	MoveColumnToTheEnd(int32 columnIndex);


		// direct access
		inline const T&		operator[]		(const uint32 i) const;
		inline T&			operator[]		(const uint32 i);
		
		// convenience functions to create zero and identity transforms
		void		SetDiagonal				(const TVectorN<T>& v);
		void		SetValuesToIdentity		(void); // 1's down the diagonal, 0's elsewhere
		void		SetValuesToZero			(void);
		
		// matrix modification
		void		SetToTranspose			(void);
		void		SetToTransposeOf		(const TMatrixMN<T>& m);
		
		// retrieval and modification of rows and columns
		void		GetRow					(const uint32 rowNum, TVectorN<T>&	v) const;
		void		SetRow					(const uint32 rowNum, const TVectorN<T>& v);
		
		void		GetColumn				(const uint32 colNum, TVectorN<T>& v) const;
		void		SetColumn				(const uint32 colNum, const TVectorN<T>& v);
		
		// dynamic copy operator - may grow the destination
		TMatrixMN&	operator=				(const TMatrixMN& m);
		
		// fast matrix operation		
		void		operator*=				(const T scalar);

		// multiplication operations for matrices and vectors
		void		Multiply				(const TMatrixMN<T>& m, const TMatrixMN<T>& n);
		
		void		MultiplyRows			(const TVectorN<T>& v);
		void		MultiplyColumns			(const TVectorN<T>& v);
		
		static void MultiplyVector			(const TMatrixMN<T>& m, const TVectorN<T>& v, TVectorN<T>& result); 	
		static void MultiplyVector			(const TVectorN<T>& v, const TMatrixMN<T>& m, TVectorN<T>& result); 		
						
	private:
		int32 			fCurrentRowDimension;
		int32 			fCurrentColumnDimension;
		
		TMCArray<T>		fData;		// a block array
};

// [inline implementation] -------------------------------------------------------------//

template<class T> inline T TMatrixMN<T>::operator() (const uint32 row, const uint32 col) const
	{ return fData[row*fCurrentRowDimension+col]; }
				
template<class T> inline T& TMatrixMN<T>::operator() (const uint32 row, const uint32 col)
	{ return fData[row*fCurrentRowDimension+col]; }

template<class T> inline uint32	TMatrixMN<T>::GetRowDimension		(void) const
	{ return fCurrentRowDimension; }
	
template<class T> inline uint32	TMatrixMN<T>::GetColumnDimension	(void) const	
	{ return fCurrentColumnDimension; }

template<class T> inline const T& TMatrixMN<T>::operator[](const uint32 i) const
{
	return fData[i];
}

template<class T> inline T& TMatrixMN<T>::operator[](const uint32 i)
{
	return fData[i];
}




#endif /* H_MATRIXMN */