#include "ParseInputFile.h"

void ParseInputFile::parseRadii(size_t nCells)
{
	_radii.reserve(nCells);
	for (size_t i = 0; i < nCells; i++)
	{
		std::string line;
		std::getline(_file, line);
		std::istringstream iss(line);
		double radius;
		iss >> radius;
		_radii.emplace_back(radius);
	}
	_hasRadii = true;
}

void ParseInputFile::parsePositions(size_t nPositions)
{
	_points.reserve(nPositions);
	for (size_t i = 0; i < nPositions; i++)
	{
		std::string line;
		std::getline(_file, line);
		std::istringstream iss(line);
		double x, y, z;
		iss >> x >> y >> z;
		_points.emplace_back(x, y, z);
	}

	_hasPositions = true;
}


/* Parsed Data */
ParseInputFile::ParseInputFile(std::string filepath)
	: _hasCells(false), _hasRadii(false), _hasCellSize(false), _hasPositions(false),
	_nx(0), _ny(0), _nz(0), _cx(0.0), _cy(0.0), _cz(0.0)
{
	_file.open(filepath);
	if (!_file.is_open())
	{
		_errors.emplace_back(ErrorCodes::FileNotFound);
		return;
	}

	std::string line;
	while (std::getline(_file, line))
	{
		// Skip commented line
		if (line[0] == '%')
			continue;

		// Read line argument
		std::istringstream iss(line);
		std::string argument;
		iss >> argument;
		if (argument == "Cells")
		{
			iss >> _nx >> _ny >> _nz;
			_hasCells = true;
		}
		else if (argument == "Size")
		{
			iss >> _cx >> _cy >> _cz;
			_hasCellSize = true;
		}
		else if (argument == "Radii")
		{
			size_t nCells;
			iss >> nCells;
			parseRadii(nCells);
		}
		else if (argument == "Positions")
		{
			size_t nPoints;
			iss >> nPoints;
			parsePositions(nPoints);
		}
	}

	if (!_hasRadii)
		_errors.emplace_back(ErrorCodes::StrutRadiusNotDefined);
	if (!_hasCellSize)
		_errors.emplace_back(ErrorCodes::CellSizeNotDefined);
}

void ParseInputFile::dumpErrors()
{
	for (const ErrorCodes code : _errors)
	{
		ERROR_MSG("ParseInputFile", code);
	}
}