#include"Post_Base.h"
#include"../function/BF.h"

#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include "../parser/mpParser.h"
#include"../Eigen/Sparse"
#include"../Eigen/Dense"


using namespace Eigen;

void Post_2D_Scatter::GetEb()
{
	int nbrVertex = _mMesh->GetNbrVertex();
	int nbrEdge = _mMesh->GetNbrEdge();
	_mEbx = Eigen::VectorXcd::Zero(nbrVertex);
	_mEby = Eigen::VectorXcd::Zero(nbrVertex);
	_mEbz = Eigen::VectorXcd::Zero(nbrVertex);

	string Ebx, Eby, Ebz;
	_mPhy->GetEb(Ebx, Eby, Ebz);

	//inite parser
	mup::ParserX p(mup::pckALL_COMPLEX);
	p.EnableAutoCreateVar(true);
	mup::Value xx, yy;
	p.DefineVar(_T("x"), mup::Variable(&xx));
	p.DefineVar(_T("y"), mup::Variable(&yy));

	Eigen::Vector3d vertex;
	for (int i = 0; i < nbrVertex; i++)
	{

		_mMesh->GetVertex(i, vertex);

		xx = vertex[0];
		yy = vertex[1];

		p.SetExpr(_T(Ebx));
		_mEbx[i].real(p.Eval().GetFloat());
		_mEbx[i].imag(p.Eval().GetImag());
		p.SetExpr(_T(Eby));
		_mEby[i].real(p.Eval().GetFloat());
		_mEby[i].imag(p.Eval().GetImag());
		p.SetExpr(_T(Ebz));
		_mEbz[i].real(p.Eval().GetFloat());
		_mEbz[i].imag(p.Eval().GetImag());
	}

	//loop over tri
	int NbrTri = _mMesh->GetNbrTri();
	for (int i = 0; i < NbrTri; i++)
	{
		int domain = _mMesh->GetDomainOfTri(i);
		Eigen::VectorXi PMLDomain;
		_mPhy->GetPMLDomain(PMLDomain);
		if (std::find(PMLDomain.begin(), PMLDomain.end(), domain) != PMLDomain.end())
		{
			int tri;
			for (int j = 0; j < 3; j++)
			{
				tri = _mMesh->GetTri(i, j);
				_mEbx(tri) = 0;
				_mEby(tri) = 0;
				_mEbz(tri) = 0;
			}
		}
	}
}

void Post_3D_Scatter::GetEb()
{
	const int nbrVertex = _mMesh->GetNbrVertex();
	_mEbx = Eigen::VectorXcd::Zero(nbrVertex);
	_mEby = Eigen::VectorXcd::Zero(nbrVertex);
	_mEbz = Eigen::VectorXcd::Zero(nbrVertex);

	std::string Ebx, Eby, Ebz;
	_mPhy->GetEb(Ebx, Eby, Ebz);

	mup::ParserX p(mup::pckALL_COMPLEX);
	p.EnableAutoCreateVar(true);
	mup::Value xx, yy, zz;
	p.DefineVar(_T("x"), mup::Variable(&xx));
	p.DefineVar(_T("y"), mup::Variable(&yy));
	p.DefineVar(_T("z"), mup::Variable(&zz));

	Eigen::Vector3d vertex;
	for (int i = 0; i < nbrVertex; i++)
	{
		_mMesh->GetVertex(i, vertex);
		xx = vertex(0);
		yy = vertex(1);
		zz = vertex(2);

		p.SetExpr(_T(Ebx.c_str()));
		_mEbx(i) = std::complex<double>(p.Eval().GetFloat(), p.Eval().GetImag());
		p.SetExpr(_T(Eby.c_str()));
		_mEby(i) = std::complex<double>(p.Eval().GetFloat(), p.Eval().GetImag());
		p.SetExpr(_T(Ebz.c_str()));
		_mEbz(i) = std::complex<double>(p.Eval().GetFloat(), p.Eval().GetImag());
	}

	Eigen::VectorXi pmlDomain;
	_mPhy->GetPMLDomain(pmlDomain);
	for (int i = 0; i < _mMesh->GetNbrTet(); i++)
	{
		const int domain = _mMesh->GetDomainOfTet(i);
		if (std::find(pmlDomain.begin(), pmlDomain.end(), domain) == pmlDomain.end())
			continue;
		for (int j = 0; j < 4; j++)
		{
			const int vid = _mMesh->GetTet(i, j);
			_mEbx(vid) = 0.0;
			_mEby(vid) = 0.0;
			_mEbz(vid) = 0.0;
		}
	}
}