#pragma once

#include "scalar.h"

class Vector3D;
class NotationFile;

//~~~~~~~~~~~~~~~~~~~~~~~~~ ExtentBox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class ExtentBox
{
 public:
	#if defined(USE_SIGNATURE)
		friend int Is_Signature_Bad(const volatile ExtentBox *);
	#endif

	Scalar minX, maxX, minY, maxY, minZ, maxZ;

	ExtentBox() {}
	ExtentBox(const Vector3D &min, const Vector3D &max);
	ExtentBox(const ExtentBox &box);

	const Scalar& operator[](int index) const
	{
		Check(this);
		return (&minX)[index];
	}
	Scalar& operator[](int index)
	{
		Check(this);
		return (&minX)[index];
	}

	ExtentBox& Intersect(const ExtentBox &box_1, const ExtentBox &box_2);
	Vector3D* Constrain(Vector3D *point) const;

	Logical Contains(const Vector3D &point) const;
	Logical Contains(const ExtentBox &box) const;
	Logical Intersects(const ExtentBox &box) const;

	Logical TestInstance() const;
	static Logical TestClass();
	friend std::ostream& operator<<(std::ostream& stream, const ExtentBox& e);
};

//~~~~~~~~~~~~~~~~~~~~~~~~~ ExtentBox functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void Convert_From_Ascii(const char *str, ExtentBox *extent_box);

inline MemoryStream& MemoryStream_Read(MemoryStream* stream, ExtentBox *output)
{
	return stream->ReadBytes(output, sizeof(*output));
}

inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const ExtentBox *input)
{
	return stream->WriteBytes(input, sizeof(*input));
}

ExtentBox *MakeExistanceBoxStream(NotationFile *notation_file, int *size);