#pragma once
#include <stdint.h>

const double PI = 3.1415926535;
const double GRAD2RAD = PI/180.;

namespace M3D
{
#pragma pack(push, 1)
/**
 * структура описывающая координаты объекта в 3д пространстве
 * @param x_pos координата x
 * @param y_pos координата y
 * @param z_pos координата z
 */
struct Coords
{
	float x_pos;
	float y_pos;
	float z_pos;
	Coords() : x_pos( 0.0 ), y_pos( 0.0 ), z_pos( 0.0 ) {};
	Coords(float x, float y, float z) : x_pos( x ), y_pos( y ), z_pos( z ) {};
};
#pragma pack(pop)
/**
 * структура описывающая положение объекта в 3д пространстве
 * @param x_angle угол поворота вокруг оси x в градусах
 * @param y_angle угол поворота вокруг оси y в градусах
 * @param z_angle угол поворота вокруг оси z в градусах
 */
struct Rotation
{
	float x_angle;
	float y_angle;
	float z_angle;
	Rotation() : x_angle( 0.0 ), y_angle( 0.0 ), z_angle( 0.0 ) {};
};
/**
 * структура описывающая масштаб объекта
 * @param x_scale масштаб по оси x
 * @param y_scale масштаб по оси y
 * @param z_scale масштаб по оси z
 */
struct Scale
{
	float x_scale;
	float y_scale;
	float z_scale;
	Scale() : x_scale( 1.0 ), y_scale( 1.0 ), z_scale( 1.0 ) {};
};
#pragma pack(push, 1)
/**
 * Структура, хранящая в себе цветовую информацию в виде чисел с плавающей запятой одинарной точности
 * @param r красная компонента цвета
 * @param g зеленая компонента цвета
 * @param b синяя компонента цвета
 * @param a коэффициент непрозрачности (1.0 - абсолютно непрозрачный)
 */
struct Color4f
{
	float r;
	float g;
	float b;
	float a;
	Color4f() : r( 0.0 ), g( 0.0 ), b( 0.0 ), a( 0.0 ) {};
};
#pragma pack(pop)
/**
 * Структура, хранящая в себе цветовую информацию в виде однобайтовых целых
 * @param r красная компонента цвета
 * @param g зеленая компонента цвета
 * @param b синяя компонента цвета
 * @param a коэффициент непрозрачности (1.0 - абсолютно непрозрачный)
 */
struct Color4i
{
	uint8_t r;
	uint8_t g;
	uint8_t b;
	uint8_t a;
	Color4i() : r( 0 ), g( 0 ), b( 0 ), a( 0 ) {};
	Color4i( const Color4f &color )
	{
		r = (uint8_t)(256. * color.r);
		g = (uint8_t)(256. * color.g);
		b = (uint8_t)(256. * color.b);
		a = (uint8_t)(256. * color.a);
	};
};
/**
 * Структура для хранения параметров камеры
 * @param fov_y угол обзора камеры в радианах, по оси y всегда строго >0 (по умолчанию равен углу в 60 градусов)
 * @param z_near расстояние от камеры до ближней плоскости отсечения всегда строго >0 (по умолчанию 0.1)
 * @param z_far расстояние от камеры до дальней плоскости отсечения всегда строго >0 (по умолчанию 1000)
 * @param aspect соотношение width/height всегда строго >0 (по умолчанию 16:9)
 */
struct CameraParams
{
	float fov_y;
	float z_near;
	float z_far;
	float aspect;
	CameraParams() : fov_y(1.0471975512), z_near(0.1), z_far(1000.0), aspect(16./9.){};
	/**
	 * Инициализация параметров камеры
	 * @param f угол обзора камеры в ГРАДУСАХ по оси y всегда строго >0
	 * @param z_near расстояние от камеры до ближней плоскости отсечения всегда строго >0
	 * @param z_far расстояние от камеры до дальней плоскости отсечения всегда строго >0
	 * @param aspect соотношение width/height всегда строго >0
	 */
	CameraParams(float f, float zn, float zf, float asp);
	/**
	 * Инициализация параметров камеры
	 * @param f угол обзора камеры в ГРАДУСАХ по оси y всегда строго >0
	 * @param z_near расстояние от камеры до ближней плоскости отсечения всегда строго >0
	 * @param z_far расстояние от камеры до дальней плоскости отсечения всегда строго >0
	 * @param aspect соотношение width/height всегда строго >0
	 */
	void set_params(float f, float zn, float zf, float asp);
};

}

