#include"Material_Base.h"
#include <algorithm>

Material::Material()
{
	_mEpsr = Eigen::Matrix3cd::Identity(3, 3);
	_mMur = Eigen::Matrix3cd::Identity(3, 3);
	_mSigma = Eigen::Matrix3d::Zero(3, 3);
	_mChihe = Eigen::Matrix3cd::Zero(3, 3);
	_mChieh = Eigen::Matrix3cd::Zero(3, 3);
	_mN = 1;
	_mK = 0;
}

Material::~Material()
{
	if (_mNbrDomain > 0)
	{
		delete[] _mDomain;
	}
}

void Material::SetName(string name)
{
	_mName = name;
}

void Material::SetDomain(int nbrDomain, int domain[])
{
	if (_mNbrDomain > 0)
	{
		delete[] _mDomain;
	}

	_mNbrDomain = nbrDomain;
	_mDomain = new int[nbrDomain];
	for (int i = 0; i < nbrDomain; i++)
	{
		_mDomain[i] = domain[i];
	}
}

void Material::SetEpsr(complex<double> value)
{
	_mEpsr = Eigen::Matrix3cd::Identity(3, 3) * value;
}

void Material::SetEpsr(complex<double> value1, complex<double> value2, complex<double> value3)
{
	_mEpsr = Eigen::Matrix3cd::Zero(3, 3);
	_mEpsr(0, 0) = value1;
	_mEpsr(1, 1) = value2;
	_mEpsr(2, 2) = value3;
}

void Material::SetMur(complex<double> value)
{
	_mMur = Eigen::Matrix3cd::Identity(3, 3) * value;
}

void Material::SetMur(complex<double> value1, complex<double> value2, complex<double> value3)
{
	_mMur = Eigen::Matrix3cd::Zero(3, 3);
	_mMur(0, 0) = value1;
	_mMur(1, 1) = value2;
	_mMur(2, 2) = value3;
}

void Material::SetSimga(double value)
{
	_mSigma = Eigen::Matrix3d::Identity(3, 3) * value;
}

void Material::SetSimga(double value1, double value2, double value3)
{
	_mSigma = Eigen::Matrix3d::Zero(3, 3);
	_mSigma(0, 0) = value1;
	_mSigma(1, 1) = value2;
	_mSigma(2, 2) = value3;
}

void Material::SetChihe(complex<double> value1, complex<double> value2, complex<double> value3)
{
	_mChihe = Eigen::Matrix3cd::Zero(3, 3);
	_mChihe(0, 0) = value1;
	_mChihe(1, 1) = value2;
	_mChihe(2, 2) = value3;
}

void Material::SetChieh(complex<double> value1, complex<double> value2, complex<double> value3)
{
	_mChieh = Eigen::Matrix3cd::Zero(3, 3);
	_mChieh(0, 0) = value1;
	_mChieh(1, 1) = value2;
	_mChieh(2, 2) = value3;
}

void Material::SetNK(double n, double k)
{
	_mN = n;
	_mK = k;
	_mEpsr = Eigen::Matrix3cd::Identity(3, 3) * pow(complex<double>(n, k), 2);
	_mMur = Eigen::Matrix3cd::Identity(3, 3);
	_mSigma = Eigen::Matrix3d::Zero(3, 3);
	_mChihe = Eigen::Matrix3cd::Zero(3, 3);
	_mChieh = Eigen::Matrix3cd::Zero(3, 3);
}

string Material::GetName()
{
	return _mName;
}

bool  Material::IsContainDomain(int domainTag)
{
	for (int i = 0; i < _mNbrDomain; i++)
	{
		if (domainTag == _mDomain[i])
		{
			return true;
		}
	}
	return false;
}

Eigen::Matrix3cd Material::GetEpsr()
{
	return _mEpsr;
}

Eigen::Matrix3cd Material::GetMur()
{
	return _mMur;
}

Eigen::Matrix3d Material::GetSigma()
{
	return _mSigma;
}

Eigen::Matrix3cd Material::GetChihe()
{
	return _mChihe;
}

Eigen::Matrix3cd Material::GetChieh()
{
	return _mChieh;
}

double Material::GetN()
{
	return _mN;
}

double Material::GetK()
{
	return _mK;
}

bool Material::IsReal()
{
	if (_mK!= 0)
		return false;

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (_mEpsr(i, j).imag()!= 0.0)
				return false;

			if (_mMur(i, j).imag()!= 0.0)
				return false;

			if (_mSigma(i, j)!= 0.0)
				return false;

			if (_mChihe(i, j).real() != 0.0)
				return false;

			if (_mChihe(i, j).imag() != 0.0)
				return false;

			if (_mChieh(i, j).real() != 0.0)
				return false;

			if (_mChieh(i, j).imag() != 0.0)
				return false;
		}
	}

	return true;
}

MaterialLib::~MaterialLib()
{
	if (_mNbrMat > 0)
	{
		delete[] _mMat;
	}
}


Eigen::Matrix3cd MaterialLib::GetEpsr(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetEpsr();
}

Eigen::Matrix3cd MaterialLib::GetMur(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetMur();
}

Eigen::Matrix3d MaterialLib::GetSigma(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetSigma();
}

Eigen::Matrix3cd MaterialLib::GetChihe(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetChihe();
}

Eigen::Matrix3cd MaterialLib::GetChieh(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetChieh();
}

double MaterialLib::GetN(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetN();
}

double MaterialLib::GetK(int domain)
{
	int numMat = this->GetNumberMat(domain);

	return _mMat[numMat].GetK();
}

int MaterialLib::GetNumberMat(int domain)
{
	for (int i = 0; i < _mNbrMat; i++)
	{
		if (_mMat[i].IsContainDomain(domain))
		{
			return i;
		}
	}

	return -1;
}

bool MaterialLib::IsReal()
{
	for (int i = 0; i < _mNbrMat; i++)
	{
		if (!_mMat[i].IsReal())
			return false;
	}

	return true;
}