#include "focus3d_parameters.h"
//#include "precompile.h"

focus3d_parameters::focus3d_parameters()
	{
	Nx = 0;
	Ny = 0;
	Nz = 0;
	Ntheta = 0;
	Nphi = 0;
	xmax = 0; xmin = 0;
	ymax = 0; ymin = 0;
	zmax = 0; zmin = 0;
	theta_max = 0; theta_min = 0;
	phi_max = 0; phi_min = 0;
	lambda = 0; f = 0;
	}
//------------------------

focus3d_parameters::focus3d_parameters(string filename)
	{
	if(!load(filename))
		{
		focus3d_parameters();
		}
	}
//------------------------

bool focus3d_parameters::load(string filename)
	{
	bool res = false;
	ifstream	fin;
	fin.open(filename.c_str());
	if(!fin)
		{
		cerr << "File error: Unable to read file " << filename << "!\n";
		res = false;
		}
	else
		{
		fin >> lambda
		>> f
		>> Nx
		>> Ny
		>> Nz
		>> Ntheta
		>> Nphi
		>> xmin
		>> xmax
		>> ymin
		>> ymax
		>> zmin
		>> zmax
		>> theta_min
		>> theta_max
		>> phi_min
		>> phi_max;
		res = true;
		}
	fin.close();
	return res;
	}
//-------------------------

bool focus3d_parameters::save(string filename)
	{
	bool result = false;
	ofstream fout;
	fout.open(filename.c_str(), ios::out);
	if(!fout)
		{
		cerr << "File error: Unable to write file " << filename << "!\n";
		result = false;
		}
	else
		{
		fout << lambda << "\n"
		<< f << "\n"
		<< Nx << "\n"
		<< Ny << "\n"
		<< Nz << "\n"
		<< Ntheta << "\n"
		<< Nphi << "\n"
		<< xmin << "\n"
		<< xmax << "\n"
		<< ymin << "\n"
		<< ymax << "\n"
		<< zmin << "\n"
		<< zmax << "\n"
		<< theta_min << "\n"
		<< theta_max << "\n"
		<< phi_min << "\n"
		<< phi_max << "\n";
		result = true;
		}
	fout.close();
	return result;
	}
//---------------------------

void focus3d_parameters::print()
	{
	cout << "Parameters:\n***********\nlambda       = " << lambda
	<< " µm\nfocal length = " << f
	<< " µm\nNx     = " << Nx 			<< "\txmin      = " << xmin 			<< " µm\txmax      = " << xmax
	<< " µm\nNy     = " << Ny 			<< "\tymin      = " << ymin 			<< " µm\txmax      = " << ymax
	<< " µm\nNz     = " << Nz 			<< "\tzmin      = " << zmin 			<< " µm\tzmax      = " << zmax
	<< " µm\nNtheta = " << Ntheta 	<< "\ttheta_min = " << theta_min << " rad\ttheta_max = " << theta_max
	<< " rad\nNphi   = " << Nphi 		<< "\tphi_min   = " << phi_min 		<< " rad\tphi_max   = " <<  phi_max << " rad\n\n";
	}
//--------------------------

bool focus3d_parameters::test()
	{
	bool result = false;
	if(xmax <= xmin)
		{result = false; cerr << "error: xmax must be greater than xmin!\n";}
	else if(ymax <= ymin)
		{result = false; cerr << "error: ymax must be greater than ymin!\n";}
	else if(zmax <= zmin)
		{result = false; cerr << "error: zmax must be greater than zmin!\n";}
	else if(theta_max <= theta_min)
		{result = false; cerr << "error: theta_max must be greater than theta_min!\n";}
	else if(phi_max <= phi_min)
		{result = false; cerr << "error: phi_max must be greater than phi_min!\n";}
	else if(f <= 0)
		{result = false; cerr << "error: f must be greater than 0!\n";}
	else if(lambda <= 0)
		{result = false; cerr << "error: lambda must be greater than 0!\n";}
	else if ( (Nx <= 0) || (Nx%2 ==0) )
		{result = false; cerr << "error: Nx must be an odd number and greater than 0!\n";}
	else if ( (Ny <= 0) || (Ny%2 ==0) )
		{result = false; cerr << "error: Ny must be an odd number and greater than 0!\n";}
	else if ( (Nz <= 0) || (Nz%2 ==0) )
		{result = false; cerr << "error: Nz must be an odd number and greater than 0!\n";}
	else if( (Ntheta <= 0) || ((Ntheta)%2  == 0) )
		{result = false; cerr << "error: Ntheta must be an odd number and greater than 0!\n";}
	else if( (Nphi <= 0) || ((Nphi)%2  == 0) )
		{result = false; cerr << "error: Nphi must be an odd number and greater than 0!\n";}
	else
		{result = true;}
	return result;
	}

void focus3d_parameters::set_default()
	{
	f = 1e3;
	lambda = 0.8;
	Nx = 31;
	Ny = 31;
	Nz = 61;
	Ntheta = 21;
	Nphi = 41;
	xmin = -1.5;
	xmax = 1.5;
	ymin = -1.5;
	ymax = 1.5;
	zmin = -3.0;
	zmax = 3.0;
	theta_min = 0;
	theta_max = 60.0*M_PI/180.0;
	phi_min = 0;
	phi_max = 2.0*M_PI;
	}

focus3d_parameters& focus3d_parameters::operator= (const focus3d_parameters& fp)
	{
	if(this == &fp)
		{
		return *this;
		}
	else
		{
		Nx = fp.Nx;
		Ny = fp.Ny;
		Nz = fp.Nz;
		Ntheta = fp.Ntheta;
		Nphi = fp.Nphi;
		xmin = fp.xmin;
		ymin = fp.ymin;
		zmin = fp.zmin;
		xmax = fp.xmax;
		ymax = fp.ymax;
		zmax = fp.zmax;
		theta_min = fp.theta_min;
		theta_max = fp.theta_max;
		phi_min = fp.phi_min;
		phi_max = fp.phi_max;
		f = fp.f;
		lambda = fp.lambda;
		return *this;
		}
	}

bool focus3d_parameters::operator==(const focus3d_parameters& fp) const
	{
	if ( (Nx == fp.Nx) &&
	        (Ny == fp.Ny) &&
	        (Nz == fp.Nz) &&
	        (Ntheta == fp.Ntheta) &&
	        (Nphi == fp.Nphi) &&
	        (xmin == fp.xmin) &&
	        (ymin == fp.ymin) &&
	        (zmin == fp.zmin) &&
	        (xmax == fp.xmax) &&
	        (ymax == fp.ymax) &&
	        (zmax == fp.zmax) &&
	        (theta_min == fp.theta_min) &&
	        (theta_max == fp.theta_max) &&
	        (phi_min == fp.phi_min) &&
	        (phi_max == fp.phi_max) &&
	        (f == fp.f) &&
	        (lambda == fp.lambda)
	   )
		{
		return true;
		}
	else
		{
		return false;
		}
	}

bool focus3d_parameters::operator!=(const focus3d_parameters& fp) const
	{
	return !(*this == fp);
	}


