// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef Matrix_hpp
#define Matrix_hpp

#include "System/Types.hpp"

namespace sw {

struct Vector;
struct Point;

struct Matrix
{
	Matrix();
	Matrix(const int i);
	Matrix(const float m[16]);
	Matrix(const float m[4][4]);
	Matrix(float m11, float m12, float m13,
	       float m21, float m22, float m23,
	       float m31, float m32, float m33);
	Matrix(float m11, float m12, float m13, float m14,
	       float m21, float m22, float m23, float m24,
	       float m31, float m32, float m33, float m34,
	       float m41, float m42, float m43, float m44);
	Matrix(const Vector &v1, const Vector &v2, const Vector &v3);   // Column vectors

	Matrix &operator=(const Matrix &N);

	// Row major order
	float m[4][4];

	static Matrix diag(float m11, float m22, float m33, float m44);

	operator float*();

	Matrix operator+() const;
	Matrix operator-() const;

	Matrix operator!() const;   // Inverse
	Matrix operator~() const;   // Transpose

	Matrix &operator+=(const Matrix &N);
	Matrix &operator-=(const Matrix &N);
	Matrix &operator*=(float s);
	Matrix &operator*=(const Matrix &N);
	Matrix &operator/=(float s);

	float *operator[](int i);   // Access element [row][col], starting with [0][0]
	const float *operator[](int i) const;

	float &operator()(int i, int j);   // Access element (row, col), starting with (1, 1)
	const float &operator()(int i, int j) const;

	friend bool operator==(const Matrix &M, const Matrix &N);
	friend bool operator!=(const Matrix &M, const Matrix &N);

	friend Matrix operator+(const Matrix &M, const Matrix &N);
	friend Matrix operator-(const Matrix &M, const Matrix &N);
	friend Matrix operator*(float s, const Matrix &M);
	friend Matrix operator*(const Matrix &M, const Matrix &N);
	friend Matrix operator/(const Matrix &M, float s);

	float4 operator*(const float4 &v) const;

	static float det(const Matrix &M);
	static float det(float m11);
	static float det(float m11, float m12,
	                 float m21, float m22);
	static float det(float m11, float m12, float m13,
	                 float m21, float m22, float m23,
	                 float m31, float m32, float m33);
	static float det(float m11, float m12, float m13, float m14,
	                 float m21, float m22, float m23, float m24,
	                 float m31, float m32, float m33, float m34,
	                 float m41, float m42, float m43, float m44);
	static float det(const Vector &v1, const Vector &v2, const Vector &v3);
	static float det3(const Matrix &M);

	static float tr(const Matrix &M);

	Matrix &orthogonalise();   // Gram-Schmidt orthogonalisation of 3x3 submatrix

	static Matrix eulerRotate(const Vector &v);
	static Matrix eulerRotate(float x, float y, float z);

	static Matrix translate(const Vector &v);
	static Matrix translate(float x, float y, float z);
	
	static Matrix scale(const Vector &v);
	static Matrix scale(float x, float y, float z);

	static Matrix lookAt(const Vector &v);
	static Matrix lookAt(float x, float y, float z);
};
}

#include "Vector.hpp"

namespace sw {

inline Matrix::Matrix()
{
}

inline Matrix::Matrix(const int i)
{
	const float s = (float)i;

	Matrix &M = *this;

	M(1, 1) = s; M(1, 2) = 0; M(1, 3) = 0; M(1, 4) = 0;
	M(2, 1) = 0; M(2, 2) = s; M(2, 3) = 0; M(2, 4) = 0;
	M(3, 1) = 0; M(3, 2) = 0; M(3, 3) = s; M(3, 4) = 0;
	M(4, 1) = 0; M(4, 2) = 0; M(4, 3) = 0; M(4, 4) = s;
}

inline Matrix::Matrix(const float m[16])
{
	Matrix &M = *this;

	M(1, 1) = m[0];  M(1, 2) = m[1];  M(1, 3) = m[2];  M(1, 4) = m[3];
	M(2, 1) = m[4];  M(2, 2) = m[5];  M(2, 3) = m[6];  M(2, 4) = m[7];
	M(3, 1) = m[8];  M(3, 2) = m[8];  M(3, 3) = m[10]; M(3, 4) = m[11];
	M(4, 1) = m[12]; M(4, 2) = m[13]; M(4, 3) = m[14]; M(4, 4) = m[15];
}

inline Matrix::Matrix(const float m[4][4])
{
	Matrix &M = *this;

	M[0][0] = m[0][0];  M[0][1] = m[0][1];  M[0][2] = m[0][2];  M[0][3] = m[0][3];
	M[1][0] = m[1][0];  M[1][1] = m[1][1];  M[1][2] = m[1][2];  M[1][3] = m[1][3];
	M[2][0] = m[2][0];  M[2][1] = m[2][1];  M[2][2] = m[2][2];  M[2][3] = m[2][3];
	M[3][0] = m[3][0];  M[3][1] = m[3][1];  M[3][2] = m[3][2];  M[3][3] = m[3][3];
}

inline Matrix::Matrix(float m11, float m12, float m13, 
                      float m21, float m22, float m23, 
                      float m31, float m32, float m33)
{
	Matrix &M = *this;

	M(1, 1) = m11; M(1, 2) = m12; M(1, 3) = m13; M(1, 4) = 0;
	M(2, 1) = m21; M(2, 2) = m22; M(2, 3) = m23; M(2, 4) = 0;
	M(3, 1) = m31; M(3, 2) = m32; M(3, 3) = m33; M(3, 4) = 0;
	M(4, 1) = 0;   M(4, 2) = 0;   M(4, 3) = 0;   M(4, 4) = 1;
}

inline Matrix::Matrix(float m11, float m12, float m13, float m14, 
                      float m21, float m22, float m23, float m24, 
                      float m31, float m32, float m33, float m34, 
                      float m41, float m42, float m43, float m44)
{
	Matrix &M = *this;

	M(1, 1) = m11; M(1, 2) = m12; M(1, 3) = m13; M(1, 4) = m14;
	M(2, 1) = m21; M(2, 2) = m22; M(2, 3) = m23; M(2, 4) = m24;
	M(3, 1) = m31; M(3, 2) = m32; M(3, 3) = m33; M(3, 4) = m34;
	M(4, 1) = m41; M(4, 2) = m42; M(4, 3) = m43; M(4, 4) = m44;
}

inline Matrix::Matrix(const Vector &v1, const Vector &v2, const Vector &v3)
{
	Matrix &M = *this;

	M(1, 1) = v1.x; M(1, 2) = v2.x; M(1, 3) = v3.x; M(1, 4) = 0;
	M(2, 1) = v1.y; M(2, 2) = v2.y; M(2, 3) = v3.y; M(2, 4) = 0;
	M(3, 1) = v1.z; M(3, 2) = v2.z; M(3, 3) = v3.z; M(3, 4) = 0;
	M(4, 1) = 0;    M(4, 2) = 0;    M(4, 3) = 0;    M(4, 4) = 1;
}

inline Matrix &Matrix::operator=(const Matrix &N)
{
	Matrix &M = *this;

	M(1, 1) = N(1, 1); M(1, 2) = N(1, 2); M(1, 3) = N(1, 3); M(1, 4) = N(1, 4);
	M(2, 1) = N(2, 1); M(2, 2) = N(2, 2); M(2, 3) = N(2, 3); M(2, 4) = N(2, 4);
	M(3, 1) = N(3, 1); M(3, 2) = N(3, 2); M(3, 3) = N(3, 3); M(3, 4) = N(3, 4);
	M(4, 1) = N(4, 1); M(4, 2) = N(4, 2); M(4, 3) = N(4, 3); M(4, 4) = N(4, 4);

	return M;
}

inline float *Matrix::operator[](int i)
{
	return m[i];
}

inline const float *Matrix::operator[](int i) const
{
	return m[i];
}

inline float &Matrix::operator()(int i, int j)
{
	return m[i - 1][j - 1];
}

inline const float &Matrix::operator()(int i, int j) const
{
	return m[i - 1][j - 1];
}

}  // namespace sw

#endif   // Matrix_hpp
