#ifndef GRAMMARRAWSTRUCTS_H
#define GRAMMARRAWSTRUCTS_H

#include <boost/fusion/include/adapt_struct.hpp>
#include <string>

namespace GST
{
namespace Parsers
{

//
// data classes (structs)
//
struct RawPoint3
{
	double x;
	double y;
	double z;

	RawPoint3()
	{
	}
	RawPoint3(const double &x, const double &y, const double &z)
		: x(x)
		, y(y)
		, z(z)
	{
	}
};

struct NameValuePair
{
	std::string name;
	std::string value;
};

struct IdxTriangle
{
	unsigned long v1;
	unsigned long v2;
	unsigned long v3;

	IdxTriangle()
	{
	}
	IdxTriangle(const unsigned long &v1,
				const unsigned long &v2,
				const unsigned long &v3)
		: v1(v1)
		, v2(v2)
		, v3(v3)
	{
	}
};

struct IdxTetrahedron
{
	unsigned long v1;
	unsigned long v2;
	unsigned long v3;
	unsigned long v4;

	IdxTetrahedron()
	{
	}
	IdxTetrahedron(const unsigned long &v1,
				   const unsigned long &v2,
				   const unsigned long &v3,
				   const unsigned long &v4)
		: v1(v1)
		, v2(v2)
		, v3(v3)
		, v4(v4)
	{
	}
};

struct GridOrientation
{
	RawPoint3 x_axis;
	RawPoint3 y_axis;
	RawPoint3 z_axis;
	GridOrientation(const RawPoint3 &x_axis = RawPoint3(),
					const RawPoint3 &y_axis = RawPoint3(),
					const RawPoint3 &z_axis = RawPoint3())
		: x_axis(x_axis)
		, y_axis(y_axis)
		, z_axis(z_axis)
	{
	}
};

struct GridSize
{
	unsigned int x;
	unsigned int y;
	unsigned int z;
	GridSize(const unsigned int &x = 0,
			 const unsigned int &y = 0,
			 const unsigned int &z = 0)
		: x(x)
		, y(y)
		, z(z)
	{
	}
};
/**
 *	This struct describes the position, orientation and size (in terms of
 *elements) of a Grid. Axis-Order is defined as X, Y, Z 'position' describes the
 *origin-point of the outer border of the Grid as a x,y,z coordinate.
 *	'orientation' describes the orientation and length of a single grid-cell in
 *x,y,z length. 'size' describes the amount of grid-cells in x,y and z direction
 *respectively.
 */
struct GridDescription
{
	RawPoint3 position;
	GridSize size;
	GridOrientation orientation;

	GridDescription(const RawPoint3 &position = RawPoint3(),
					const GridOrientation &orientation = GridOrientation(),
					const GridSize &size = GridSize())
		: position(position)
		, orientation(orientation)
		, size(size) {};
};

} // namespace Parsers
} // namespace GST

//
// data classes as boost.fusion struct (must be in global namespace)
//
// clang-format off
// Format messes up because of the macros here.
BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::RawPoint3,
    (double, x)
	(double, y)
	(double, z)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::NameValuePair,
    (std::string, name)
    (std::string, value)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::IdxTriangle,
	(unsigned long, v1)
	(unsigned long, v2)
	(unsigned long, v3)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::IdxTetrahedron,
	(unsigned long, v1)
	(unsigned long, v2)
	(unsigned long, v3)
	(unsigned long, v4)
)
// clang-format on
#endif // GRAMMARRAWSTRUCTS_H
