/* geo.h */

#pragma once

#include <math.h>
#include <stdint.h>

#include "config.h"
#ifdef GEO_DEBUG
#include <stdio.h>
#endif

#define PI 				3.14159265
#define EPS				1E-5

/* Macros */

#define MAX(x,y)		(((x)>(y))?(y):(x))
#define ABS(x)			((x>0)?(x):(-x))
#define NEW_RAY(p,d)	{ray_nudge(p,d),d}

/* Types */

typedef uint32_t u32;

typedef double num;

typedef struct {
	num a,b,c;
} tuple;

typedef struct {
	tuple start, dir;
} ray;

/* Reals */

num	  minf(num a, num b);
num   maxf(num a, num b);
void  swapf(num *a, num *b);

/* Tuples */

tuple geo_new  (num x,   num y,   num z);
tuple geo_add  (tuple a, tuple b);
tuple geo_neg  (tuple a);
tuple geo_sub  (tuple l, tuple r);
tuple geo_scale(tuple a, num f);
tuple geo_cross(tuple l, tuple r);
tuple geo_unit (tuple t);
tuple geo_abs  (tuple t);
num   geo_dot  (tuple l, tuple r);
num   geo_len  (tuple t);
int   geo_eq   (tuple a, tuple b);
int   geo_isset(tuple a);

/* Ray */

tuple ray_pos  (ray r, num t);
tuple ray_nudge(tuple point, tuple dir);

/* Packing */

u32   geo_as_u32  (tuple t);
tuple geo_from_u32(uint32_t col);