// File: utils.h
#pragma once
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4127) // conditional expression is constant
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <assert.h>
#include <time.h>
#include <vector>
#include <string>
#include <random>
#include <utility>
#include <limits.h>
#include "dds_defs.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#define ASSUME(c) static_assert(c, #c)
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

#define VECTOR_TEXT_LINE_SIZE (30.0f)
#define VECTOR_TEXT_CORE_LINE_SIZE (21.0f)

#define UNUSED(x) (void)x

namespace utils
{
typedef std::vector<uint8_t> uint8_vec;

extern const uint32_t g_pretty_colors[];
extern const uint32_t g_num_pretty_colors;

const float cDegToRad = 0.01745329252f;
const float cRadToDeg = 57.29577951f;

enum eClear { cClear };
enum eZero { cZero };
enum eInitExpand { cInitExpand };

inline int iabs(int i) { if (i < 0) i = -i; return i; }
inline uint8_t clamp255(int32_t i) { return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i); }
template <typename S> inline S clamp(S value, S low, S high) { return (value < low) ? low : ((value > high) ? high : value); }
template<typename F> inline F lerp(F a, F b, F s) { return a + (b - a) * s; }
template<typename F> inline F square(F a) { return a * a; }

template <class T>
inline T prev_wrap(T i, T n)
{
	T temp = i - 1;
	if (temp < 0)
		temp = n - 1;
	return temp;
}

template <class T>
inline T next_wrap(T i, T n)
{
	T temp = i + 1;
	if (temp >= n)
		temp = 0;
	return temp;
}

inline int posmod(int x, int y)
{
	if (x >= 0)
		return (x < y) ? x : (x % y);
	int m = (-x) % y;
	return (m != 0) ? (y - m) : m;
}

inline float deg_to_rad(float f)
{
	return f * cDegToRad;
};

inline float rad_to_deg(float f)
{
	return f * cRadToDeg;
};

template <typename T>
struct rel_ops
{
	friend bool operator!=(const T& x, const T& y)
	{
		return (!(x == y));
	}
	friend bool operator>(const T& x, const T& y)
	{
		return (y < x);
	}
	friend bool operator<=(const T& x, const T& y)
	{
		return (!(y < x));
	}
	friend bool operator>=(const T& x, const T& y)
	{
		return (!(x < y));
	}
};

template <uint32_t N, typename T>
class vec : public rel_ops<vec<N, T> >
{
public:
	typedef T scalar_type;
	enum
	{
		num_elements = N
	};

	inline vec()
	{
	}

	inline vec(eClear)
	{
		clear();
	}

	inline vec(const vec& other)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] = other.m_s[i];
	}

	template <uint32_t O, typename U>
	inline vec(const vec<O, U>& other)
	{
		set(other);
	}

	template <uint32_t O, typename U>
	inline vec(const vec<O, U>& other, T w)
	{
		*this = other;
		m_s[N - 1] = w;
	}

	explicit inline vec(T val)
	{
		set(val);
	}

	inline vec(T val0, T val1)
	{
		set(val0, val1);
	}

	inline vec(T val0, T val1, T val2)
	{
		set(val0, val1, val2);
	}

	inline vec(T val0, T val1, T val2, T val3)
	{
		set(val0, val1, val2, val3);
	}

	inline vec(T val0, T val1, T val2, T val3, T val4, T val5)
	{
		set(val0, val1, val2, val3, val4, val5);
	}

	inline vec(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15)
	{
		set(val0, val1, val2, val3,
			val4, val5, val6, val7,
			val8, val9, val10, val11,
			val12, val13, val14, val15);
	}

	inline vec(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15,
		T val16, T val17, T val18, T val19)
	{
		set(val0, val1, val2, val3,
			val4, val5, val6, val7,
			val8, val9, val10, val11,
			val12, val13, val14, val15,
			val16, val17, val18, val19);
	}

	inline vec(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15,
		T val16, T val17, T val18, T val19,
		T val20, T val21, T val22, T val23,
		T val24)
	{
		set(val0, val1, val2, val3,
			val4, val5, val6, val7,
			val8, val9, val10, val11,
			val12, val13, val14, val15,
			val16, val17, val18, val19,
			val20, val21, val22, val23,
			val24);
	}

	inline void clear()
	{
		if (N > 4)
			memset(m_s, 0, sizeof(m_s));
		else
		{
			for (uint32_t i = 0; i < N; i++)
				m_s[i] = 0;
		}
	}

	template <uint32_t ON, typename OT>
	inline vec& set(const vec<ON, OT>& other)
	{
		if ((void*)this == (void*)&other)
			return *this;
		const uint32_t m = std::min(N, ON);
		uint32_t i;
		for (i = 0; i < m; i++)
			m_s[i] = static_cast<T>(other[i]);
		for (; i < N; i++)
			m_s[i] = 0;
		return *this;
	}

	inline vec& set_component(uint32_t index, T val)
	{
		assert(index < N);
		m_s[index] = val;
		return *this;
	}

	inline vec& set(T val)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] = val;
		return *this;
	}

	inline vec& set(T val0, T val1)
	{
		m_s[0] = val0;
		if (N >= 2)
		{
			m_s[1] = val1;

			for (uint32_t i = 2; i < N; i++)
				m_s[i] = 0;
		}
		return *this;
	}

	inline vec& set(T val0, T val1, T val2)
	{
		m_s[0] = val0;
		if (N >= 2)
		{
			m_s[1] = val1;

			if (N >= 3)
			{
				m_s[2] = val2;

				for (uint32_t i = 3; i < N; i++)
					m_s[i] = 0;
			}
		}
		return *this;
	}

	inline vec& set(T val0, T val1, T val2, T val3)
	{
		m_s[0] = val0;
		if (N >= 2)
		{
			m_s[1] = val1;

			if (N >= 3)
			{
				m_s[2] = val2;

				if (N >= 4)
				{
					m_s[3] = val3;

					for (uint32_t i = 4; i < N; i++)
						m_s[i] = 0;
				}
			}
		}
		return *this;
	}

	inline vec& set(T val0, T val1, T val2, T val3, T val4, T val5)
	{
		m_s[0] = val0;
		if (N >= 2)
		{
			m_s[1] = val1;

			if (N >= 3)
			{
				m_s[2] = val2;

				if (N >= 4)
				{
					m_s[3] = val3;

					if (N >= 5)
					{
						m_s[4] = val4;

						if (N >= 6)
						{
							m_s[5] = val5;

							for (uint32_t i = 6; i < N; i++)
								m_s[i] = 0;
						}
					}
				}
			}
		}
		return *this;
	}

	inline vec& set(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15)
	{
		m_s[0] = val0;
		if (N >= 2)
			m_s[1] = val1;
		if (N >= 3)
			m_s[2] = val2;
		if (N >= 4)
			m_s[3] = val3;

		if (N >= 5)
			m_s[4] = val4;
		if (N >= 6)
			m_s[5] = val5;
		if (N >= 7)
			m_s[6] = val6;
		if (N >= 8)
			m_s[7] = val7;

		if (N >= 9)
			m_s[8] = val8;
		if (N >= 10)
			m_s[9] = val9;
		if (N >= 11)
			m_s[10] = val10;
		if (N >= 12)
			m_s[11] = val11;

		if (N >= 13)
			m_s[12] = val12;
		if (N >= 14)
			m_s[13] = val13;
		if (N >= 15)
			m_s[14] = val14;
		if (N >= 16)
			m_s[15] = val15;

		for (uint32_t i = 16; i < N; i++)
			m_s[i] = 0;

		return *this;
	}

	inline vec& set(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15,
		T val16, T val17, T val18, T val19)
	{
		m_s[0] = val0;
		if (N >= 2)
			m_s[1] = val1;
		if (N >= 3)
			m_s[2] = val2;
		if (N >= 4)
			m_s[3] = val3;

		if (N >= 5)
			m_s[4] = val4;
		if (N >= 6)
			m_s[5] = val5;
		if (N >= 7)
			m_s[6] = val6;
		if (N >= 8)
			m_s[7] = val7;

		if (N >= 9)
			m_s[8] = val8;
		if (N >= 10)
			m_s[9] = val9;
		if (N >= 11)
			m_s[10] = val10;
		if (N >= 12)
			m_s[11] = val11;

		if (N >= 13)
			m_s[12] = val12;
		if (N >= 14)
			m_s[13] = val13;
		if (N >= 15)
			m_s[14] = val14;
		if (N >= 16)
			m_s[15] = val15;

		if (N >= 17)
			m_s[16] = val16;
		if (N >= 18)
			m_s[17] = val17;
		if (N >= 19)
			m_s[18] = val18;
		if (N >= 20)
			m_s[19] = val19;

		for (uint32_t i = 20; i < N; i++)
			m_s[i] = 0;

		return *this;
	}

	inline vec& set(
		T val0, T val1, T val2, T val3,
		T val4, T val5, T val6, T val7,
		T val8, T val9, T val10, T val11,
		T val12, T val13, T val14, T val15,
		T val16, T val17, T val18, T val19,
		T val20, T val21, T val22, T val23,
		T val24)
	{
		m_s[0] = val0;
		if (N >= 2)
			m_s[1] = val1;
		if (N >= 3)
			m_s[2] = val2;
		if (N >= 4)
			m_s[3] = val3;

		if (N >= 5)
			m_s[4] = val4;
		if (N >= 6)
			m_s[5] = val5;
		if (N >= 7)
			m_s[6] = val6;
		if (N >= 8)
			m_s[7] = val7;

		if (N >= 9)
			m_s[8] = val8;
		if (N >= 10)
			m_s[9] = val9;
		if (N >= 11)
			m_s[10] = val10;
		if (N >= 12)
			m_s[11] = val11;

		if (N >= 13)
			m_s[12] = val12;
		if (N >= 14)
			m_s[13] = val13;
		if (N >= 15)
			m_s[14] = val14;
		if (N >= 16)
			m_s[15] = val15;

		if (N >= 17)
			m_s[16] = val16;
		if (N >= 18)
			m_s[17] = val17;
		if (N >= 19)
			m_s[18] = val18;
		if (N >= 20)
			m_s[19] = val19;

		if (N >= 21)
			m_s[20] = val20;
		if (N >= 22)
			m_s[21] = val21;
		if (N >= 23)
			m_s[22] = val22;
		if (N >= 24)
			m_s[23] = val23;

		if (N >= 25)
			m_s[24] = val24;

		for (uint32_t i = 25; i < N; i++)
			m_s[i] = 0;

		return *this;
	}

	inline vec& set(const T* pValues)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] = pValues[i];
		return *this;
	}

	template <uint32_t ON, typename OT>
	inline vec& swizzle_set(const vec<ON, OT>& other, uint32_t i)
	{
		return set(static_cast<T>(other[i]));
	}

	template <uint32_t ON, typename OT>
	inline vec& swizzle_set(const vec<ON, OT>& other, uint32_t i, uint32_t j)
	{
		return set(static_cast<T>(other[i]), static_cast<T>(other[j]));
	}

	template <uint32_t ON, typename OT>
	inline vec& swizzle_set(const vec<ON, OT>& other, uint32_t i, uint32_t j, uint32_t k)
	{
		return set(static_cast<T>(other[i]), static_cast<T>(other[j]), static_cast<T>(other[k]));
	}

	template <uint32_t ON, typename OT>
	inline vec& swizzle_set(const vec<ON, OT>& other, uint32_t i, uint32_t j, uint32_t k, uint32_t l)
	{
		return set(static_cast<T>(other[i]), static_cast<T>(other[j]), static_cast<T>(other[k]), static_cast<T>(other[l]));
	}

	inline vec& operator=(const vec& rhs)
	{
		if (this != &rhs)
		{
			for (uint32_t i = 0; i < N; i++)
				m_s[i] = rhs.m_s[i];
		}
		return *this;
	}

	template <uint32_t O, typename U>
	inline vec& operator=(const vec<O, U>& other)
	{
		if ((void*)this == (void*)&other)
			return *this;

		uint32_t s = std::min(N, O);

		uint32_t i;
		for (i = 0; i < s; i++)
			m_s[i] = static_cast<T>(other[i]);

		for (; i < N; i++)
			m_s[i] = 0;

		return *this;
	}

	inline bool operator==(const vec& rhs) const
	{
		for (uint32_t i = 0; i < N; i++)
			if (!(m_s[i] == rhs.m_s[i]))
				return false;
		return true;
	}

	inline bool operator<(const vec& rhs) const
	{
		for (uint32_t i = 0; i < N; i++)
		{
			if (m_s[i] < rhs.m_s[i])
				return true;
			else if (!(m_s[i] == rhs.m_s[i]))
				return false;
		}

		return false;
	}

	inline T operator[](uint32_t i) const
	{
		assert(i < N);
		return m_s[i];
	}

	inline T& operator[](uint32_t i)
	{
		assert(i < N);
		return m_s[i];
	}

	template <uint32_t index>
	inline uint64_t get_component_as_uint() const
	{
		ASSUME(index < N);
		if (sizeof(T) == sizeof(float))
			return *reinterpret_cast<const uint32_t*>(&m_s[index]);
		else
			return *reinterpret_cast<const uint64_t*>(&m_s[index]);
	}

	inline T get_x(void) const
	{
		return m_s[0];
	}
	inline T get_y(void) const
	{
		ASSUME(N >= 2);
		return m_s[1];
	}
	inline T get_z(void) const
	{
		ASSUME(N >= 3);
		return m_s[2];
	}
	inline T get_w(void) const
	{
		ASSUME(N >= 4);
		return m_s[3];
	}

	inline vec get_x_vector() const
	{
		return broadcast<0>();
	}
	inline vec get_y_vector() const
	{
		return broadcast<1>();
	}
	inline vec get_z_vector() const
	{
		return broadcast<2>();
	}
	inline vec get_w_vector() const
	{
		return broadcast<3>();
	}

	inline T get_component(uint32_t i) const
	{
		return (*this)[i];
	}

	inline vec& set_x(T v)
	{
		m_s[0] = v;
		return *this;
	}
	inline vec& set_y(T v)
	{
		ASSUME(N >= 2);
		m_s[1] = v;
		return *this;
	}
	inline vec& set_z(T v)
	{
		ASSUME(N >= 3);
		m_s[2] = v;
		return *this;
	}
	inline vec& set_w(T v)
	{
		ASSUME(N >= 4);
		m_s[3] = v;
		return *this;
	}

	inline const T* get_ptr() const
	{
		return reinterpret_cast<const T*>(&m_s[0]);
	}
	inline T* get_ptr()
	{
		return reinterpret_cast<T*>(&m_s[0]);
	}

	inline vec as_point() const
	{
		vec result(*this);
		result[N - 1] = 1;
		return result;
	}

	inline vec as_dir() const
	{
		vec result(*this);
		result[N - 1] = 0;
		return result;
	}

	inline vec<2, T> select2(uint32_t i, uint32_t j) const
	{
		assert((i < N) && (j < N));
		return vec<2, T>(m_s[i], m_s[j]);
	}

	inline vec<3, T> select3(uint32_t i, uint32_t j, uint32_t k) const
	{
		assert((i < N) && (j < N) && (k < N));
		return vec<3, T>(m_s[i], m_s[j], m_s[k]);
	}

	inline vec<4, T> select4(uint32_t i, uint32_t j, uint32_t k, uint32_t l) const
	{
		assert((i < N) && (j < N) && (k < N) && (l < N));
		return vec<4, T>(m_s[i], m_s[j], m_s[k], m_s[l]);
	}

	inline bool is_dir() const
	{
		return m_s[N - 1] == 0;
	}
	inline bool is_vector() const
	{
		return is_dir();
	}
	inline bool is_point() const
	{
		return m_s[N - 1] == 1;
	}

	inline vec project() const
	{
		vec result(*this);
		if (result[N - 1])
			result /= result[N - 1];
		return result;
	}

	inline vec broadcast(unsigned i) const
	{
		return vec((*this)[i]);
	}

	template <uint32_t i>
	inline vec broadcast() const
	{
		return vec((*this)[i]);
	}

	inline vec swizzle(uint32_t i, uint32_t j) const
	{
		return vec((*this)[i], (*this)[j]);
	}

	inline vec swizzle(uint32_t i, uint32_t j, uint32_t k) const
	{
		return vec((*this)[i], (*this)[j], (*this)[k]);
	}

	inline vec swizzle(uint32_t i, uint32_t j, uint32_t k, uint32_t l) const
	{
		return vec((*this)[i], (*this)[j], (*this)[k], (*this)[l]);
	}

	inline vec operator-() const
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = -m_s[i];
		return result;
	}

	inline vec operator+() const
	{
		return *this;
	}

	inline vec& operator+=(const vec& other)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] += other.m_s[i];
		return *this;
	}

	inline vec& operator-=(const vec& other)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] -= other.m_s[i];
		return *this;
	}

	inline vec& operator*=(const vec& other)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] *= other.m_s[i];
		return *this;
	}

	inline vec& operator/=(const vec& other)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] /= other.m_s[i];
		return *this;
	}

	inline vec& operator*=(T s)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] *= s;
		return *this;
	}

	inline vec& operator/=(T s)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] /= s;
		return *this;
	}

	// component-wise multiply (not a dot product like in previous versions)
	// just remarking it out because it's too ambiguous, use dot() or mul_components() instead
#if 0
	friend inline vec operator*(const vec& lhs, const vec& rhs)
	{
		return vec::mul_components(lhs, rhs);
	}
#endif

	friend inline vec operator*(const vec& lhs, T val)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = lhs.m_s[i] * val;
		return result;
	}

	friend inline vec operator*(T val, const vec& rhs)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = val * rhs.m_s[i];
		return result;
	}

	friend inline vec operator/(const vec& lhs, const vec& rhs)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = lhs.m_s[i] / rhs.m_s[i];
		return result;
	}

	friend inline vec operator/(const vec& lhs, T val)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = lhs.m_s[i] / val;
		return result;
	}

	friend inline vec operator+(const vec& lhs, const vec& rhs)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = lhs.m_s[i] + rhs.m_s[i];
		return result;
	}

	friend inline vec operator-(const vec& lhs, const vec& rhs)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result.m_s[i] = lhs.m_s[i] - rhs.m_s[i];
		return result;
	}

	static inline vec<3, T> cross2(const vec& a, const vec& b)
	{
		ASSUME(N >= 2);
		return vec<3, T>(0, 0, a[0] * b[1] - a[1] * b[0]);
	}

	inline vec<3, T> cross2(const vec& b) const
	{
		return cross2(*this, b);
	}

	static inline vec<3, T> cross3(const vec& a, const vec& b)
	{
		ASSUME(N >= 3);
		return vec<3, T>(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
	}

	inline vec<3, T> cross3(const vec& b) const
	{
		return cross3(*this, b);
	}

	static inline vec<3, T> cross(const vec& a, const vec& b)
	{
		ASSUME(N >= 2);

		if (N == 2)
			return cross2(a, b);
		else
			return cross3(a, b);
	}

	inline vec<3, T> cross(const vec& b) const
	{
		ASSUME(N >= 2);
		return cross(*this, b);
	}

	inline T dot(const vec& rhs) const
	{
		return dot(*this, rhs);
	}

	inline vec dot_vector(const vec& rhs) const
	{
		return vec(dot(*this, rhs));
	}

	static inline T dot(const vec& lhs, const vec& rhs)
	{
		T result = lhs.m_s[0] * rhs.m_s[0];
		for (uint32_t i = 1; i < N; i++)
			result += lhs.m_s[i] * rhs.m_s[i];
		return result;
	}

	inline T dot2(const vec& rhs) const
	{
		ASSUME(N >= 2);
		return m_s[0] * rhs.m_s[0] + m_s[1] * rhs.m_s[1];
	}

	inline T dot3(const vec& rhs) const
	{
		ASSUME(N >= 3);
		return m_s[0] * rhs.m_s[0] + m_s[1] * rhs.m_s[1] + m_s[2] * rhs.m_s[2];
	}

	inline T dot4(const vec& rhs) const
	{
		ASSUME(N >= 4);
		return m_s[0] * rhs.m_s[0] + m_s[1] * rhs.m_s[1] + m_s[2] * rhs.m_s[2] + m_s[3] * rhs.m_s[3];
	}

	inline T norm(void) const
	{
		T sum = m_s[0] * m_s[0];
		for (uint32_t i = 1; i < N; i++)
			sum += m_s[i] * m_s[i];
		return sum;
	}

	inline T length(void) const
	{
		return sqrt(norm());
	}

	inline T squared_distance(const vec& rhs) const
	{
		T dist2 = 0;
		for (uint32_t i = 0; i < N; i++)
		{
			T d = m_s[i] - rhs.m_s[i];
			dist2 += d * d;
		}
		return dist2;
	}

	inline T squared_distance(const vec& rhs, T early_out) const
	{
		T dist2 = 0;
		for (uint32_t i = 0; i < N; i++)
		{
			T d = m_s[i] - rhs.m_s[i];
			dist2 += d * d;
			if (dist2 > early_out)
				break;
		}
		return dist2;
	}

	inline T distance(const vec& rhs) const
	{
		T dist2 = 0;
		for (uint32_t i = 0; i < N; i++)
		{
			T d = m_s[i] - rhs.m_s[i];
			dist2 += d * d;
		}
		return sqrt(dist2);
	}

	inline vec inverse() const
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result[i] = m_s[i] ? (1.0f / m_s[i]) : 0;
		return result;
	}

	// returns squared length (norm)
	inline double normalize(const vec* pDefaultVec = NULL)
	{
		double n = m_s[0] * m_s[0];
		for (uint32_t i = 1; i < N; i++)
			n += m_s[i] * m_s[i];

		if (n != 0)
			*this *= static_cast<T>(1.0f / sqrt(n));
		else if (pDefaultVec)
			*this = *pDefaultVec;
		return n;
	}

	inline double normalize3(const vec* pDefaultVec = NULL)
	{
		ASSUME(N >= 3);

		double n = m_s[0] * m_s[0] + m_s[1] * m_s[1] + m_s[2] * m_s[2];

		if (n != 0)
			*this *= static_cast<T>((1.0f / sqrt(n)));
		else if (pDefaultVec)
			*this = *pDefaultVec;
		return n;
	}

	inline vec& normalize_in_place(const vec* pDefaultVec = NULL)
	{
		normalize(pDefaultVec);
		return *this;
	}

	inline vec& normalize3_in_place(const vec* pDefaultVec = NULL)
	{
		normalize3(pDefaultVec);
		return *this;
	}

	inline vec get_normalized(const vec* pDefaultVec = NULL) const
	{
		vec result(*this);
		result.normalize(pDefaultVec);
		return result;
	}

	inline vec get_normalized3(const vec* pDefaultVec = NULL) const
	{
		vec result(*this);
		result.normalize3(pDefaultVec);
		return result;
	}

	inline vec& clamp(T l, T h)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] = static_cast<T>(clamp(m_s[i], l, h));
		return *this;
	}

	inline vec& saturate()
	{
		return clamp(0.0f, 1.0f);
	}

	inline vec& clamp(const vec& l, const vec& h)
	{
		for (uint32_t i = 0; i < N; i++)
			m_s[i] = static_cast<T>(clamp(m_s[i], l[i], h[i]));
		return *this;
	}

	inline bool is_within_bounds(const vec& l, const vec& h) const
	{
		for (uint32_t i = 0; i < N; i++)
			if ((m_s[i] < l[i]) || (m_s[i] > h[i]))
				return false;

		return true;
	}

	inline bool is_within_bounds(T l, T h) const
	{
		for (uint32_t i = 0; i < N; i++)
			if ((m_s[i] < l) || (m_s[i] > h))
				return false;

		return true;
	}

	inline uint32_t get_major_axis(void) const
	{
		T m = fabs(m_s[0]);
		uint32_t r = 0;
		for (uint32_t i = 1; i < N; i++)
		{
			const T c = fabs(m_s[i]);
			if (c > m)
			{
				m = c;
				r = i;
			}
		}
		return r;
	}

	inline uint32_t get_minor_axis(void) const
	{
		T m = fabs(m_s[0]);
		uint32_t r = 0;
		for (uint32_t i = 1; i < N; i++)
		{
			const T c = fabs(m_s[i]);
			if (c < m)
			{
				m = c;
				r = i;
			}
		}
		return r;
	}

	inline void get_projection_axes(uint32_t& u, uint32_t& v) const
	{
		const int axis = get_major_axis();
		if (m_s[axis] < 0.0f)
		{
			v = next_wrap<uint32_t>(axis, N);
			u = next_wrap<uint32_t>(v, N);
		}
		else
		{
			u = next_wrap<uint32_t>(axis, N);
			v = next_wrap<uint32_t>(u, N);
		}
	}

	inline T get_absolute_minimum(void) const
	{
		T result = fabs(m_s[0]);
		for (uint32_t i = 1; i < N; i++)
			result = std::min(result, fabs(m_s[i]));
		return result;
	}

	inline T get_absolute_maximum(void) const
	{
		T result = fabs(m_s[0]);
		for (uint32_t i = 1; i < N; i++)
			result = std::max(result, fabs(m_s[i]));
		return result;
	}

	inline T get_minimum(void) const
	{
		T result = m_s[0];
		for (uint32_t i = 1; i < N; i++)
			result = std::min(result, m_s[i]);
		return result;
	}

	inline T get_maximum(void) const
	{
		T result = m_s[0];
		for (uint32_t i = 1; i < N; i++)
			result = std::max(result, m_s[i]);
		return result;
	}

	inline vec& remove_unit_direction(const vec& dir)
	{
		*this -= (dot(dir) * dir);
		return *this;
	}

	inline vec get_remove_unit_direction(const vec& dir) const
	{
		return *this - (dot(dir) * dir);
	}

	inline bool all_less(const vec& b) const
	{
		for (uint32_t i = 0; i < N; i++)
			if (m_s[i] >= b.m_s[i])
				return false;
		return true;
	}

	inline bool all_less_equal(const vec& b) const
	{
		for (uint32_t i = 0; i < N; i++)
			if (m_s[i] > b.m_s[i])
				return false;
		return true;
	}

	inline bool all_greater(const vec& b) const
	{
		for (uint32_t i = 0; i < N; i++)
			if (m_s[i] <= b.m_s[i])
				return false;
		return true;
	}

	inline bool all_greater_equal(const vec& b) const
	{
		for (uint32_t i = 0; i < N; i++)
			if (m_s[i] < b.m_s[i])
				return false;
		return true;
	}

	inline vec negate_xyz() const
	{
		vec ret;

		ret[0] = -m_s[0];
		if (N >= 2)
			ret[1] = -m_s[1];
		if (N >= 3)
			ret[2] = -m_s[2];

		for (uint32_t i = 3; i < N; i++)
			ret[i] = m_s[i];

		return ret;
	}

	inline vec& invert()
	{
		for (uint32_t i = 0; i < N; i++)
			if (m_s[i] != 0.0f)
				m_s[i] = 1.0f / m_s[i];
		return *this;
	}

	inline scalar_type perp_dot(const vec& b) const
	{
		ASSUME(N == 2);
		return m_s[0] * b.m_s[1] - m_s[1] * b.m_s[0];
	}

	inline vec perp() const
	{
		ASSUME(N == 2);
		return vec(-m_s[1], m_s[0]);
	}

	inline vec get_floor() const
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result[i] = floor(m_s[i]);
		return result;
	}

	inline vec get_ceil() const
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result[i] = ceil(m_s[i]);
		return result;
	}

	// static helper methods

	static inline vec mul_components(const vec& lhs, const vec& rhs)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result[i] = lhs.m_s[i] * rhs.m_s[i];
		return result;
	}

	static inline vec mul_add_components(const vec& a, const vec& b, const vec& c)
	{
		vec result;
		for (uint32_t i = 0; i < N; i++)
			result[i] = a.m_s[i] * b.m_s[i] + c.m_s[i];
		return result;
	}

	static inline vec make_axis(uint32_t i)
	{
		vec result;
		result.clear();
		result[i] = 1;
		return result;
	}

	static inline vec equals_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] == b[i]);
		return ret;
	}

	static inline vec not_equals_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] != b[i]);
		return ret;
	}

	static inline vec less_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] < b[i]);
		return ret;
	}

	static inline vec less_equals_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] <= b[i]);
		return ret;
	}

	static inline vec greater_equals_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] >= b[i]);
		return ret;
	}

	static inline vec greater_mask(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret[i] = (a[i] > b[i]);
		return ret;
	}

	static inline vec component_max(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret.m_s[i] = std::max(a.m_s[i], b.m_s[i]);
		return ret;
	}

	static inline vec component_min(const vec& a, const vec& b)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret.m_s[i] = std::min(a.m_s[i], b.m_s[i]);
		return ret;
	}

	static inline vec lerp(const vec& a, const vec& b, float t)
	{
		vec ret;
		for (uint32_t i = 0; i < N; i++)
			ret.m_s[i] = a.m_s[i] + (b.m_s[i] - a.m_s[i]) * t;
		return ret;
	}

	static inline bool equal_tol(const vec& a, const vec& b, float t)
	{
		for (uint32_t i = 0; i < N; i++)
			if (!equal_tol(a.m_s[i], b.m_s[i], t))
				return false;
		return true;
	}

	inline bool equal_tol(const vec& b, float t) const
	{
		return equal_tol(*this, b, t);
	}

protected:
	T m_s[N];
};

typedef vec<1, double> vec1D;
typedef vec<2, double> vec2D;
typedef vec<3, double> vec3D;
typedef vec<4, double> vec4D;

typedef vec<1, float> vec1F;

typedef vec<2, float> vec2F;
typedef std::vector<vec2F> vec2F_array;

typedef vec<3, float> vec3F;
typedef std::vector<vec3F> vec3F_array;

typedef vec<4, float> vec4F;
typedef std::vector<vec4F> vec4F_array;

typedef vec<2, uint32_t> vec2U;
typedef vec<3, uint32_t> vec3U;
typedef vec<2, int> vec2I;
typedef vec<3, int> vec3I;
typedef vec<4, int> vec4I;

typedef vec<2, int16_t> vec2I16;
typedef vec<3, int16_t> vec3I16;

inline vec2F rotate_point(const vec2F& p, float rad)
{
	float c = cos(rad);
	float s = sin(rad);

	float x = p[0];
	float y = p[1];

	return vec2F(x * c - y * s, x * s + y * c);
}

class rect
{
public:
	inline rect()
	{
	}

	inline rect(eClear)
	{
		clear();
	}

	inline rect(eInitExpand)
	{
		init_expand();
	}

	// up to, but not including right/bottom
	inline rect(int left, int top, int right, int bottom)
	{
		set(left, top, right, bottom);
	}

	inline rect(const vec2I& lo, const vec2I& hi)
	{
		m_corner[0] = lo;
		m_corner[1] = hi;
	}

	inline rect(const vec2I& point)
	{
		m_corner[0] = point;
		m_corner[1].set(point[0] + 1, point[1] + 1);
	}

	inline bool operator==(const rect& r) const
	{
		return (m_corner[0] == r.m_corner[0]) && (m_corner[1] == r.m_corner[1]);
	}

	inline bool operator<(const rect& r) const
	{
		for (uint32_t i = 0; i < 2; i++)
		{
			if (m_corner[i] < r.m_corner[i])
				return true;
			else if (!(m_corner[i] == r.m_corner[i]))
				return false;
		}

		return false;
	}

	inline void clear()
	{
		m_corner[0].clear();
		m_corner[1].clear();
	}

	inline void set(int left, int top, int right, int bottom)
	{
		m_corner[0].set(left, top);
		m_corner[1].set(right, bottom);
	}

	inline void set(const vec2I& lo, const vec2I& hi)
	{
		m_corner[0] = lo;
		m_corner[1] = hi;
	}

	inline void set(const vec2I& point)
	{
		m_corner[0] = point;
		m_corner[1].set(point[0] + 1, point[1] + 1);
	}

	inline uint32_t get_width() const
	{
		return m_corner[1][0] - m_corner[0][0];
	}
	inline uint32_t get_height() const
	{
		return m_corner[1][1] - m_corner[0][1];
	}

	inline int get_left() const
	{
		return m_corner[0][0];
	}
	inline int get_top() const
	{
		return m_corner[0][1];
	}
	inline int get_right() const
	{
		return m_corner[1][0];
	}
	inline int get_bottom() const
	{
		return m_corner[1][1];
	}

	inline bool is_empty() const
	{
		return (m_corner[1][0] <= m_corner[0][0]) || (m_corner[1][1] <= m_corner[0][1]);
	}

	inline uint32_t get_dimension(uint32_t axis) const
	{
		return m_corner[1][axis] - m_corner[0][axis];
	}
	inline uint32_t get_area() const
	{
		return get_dimension(0) * get_dimension(1);
	}

	inline const vec2I& operator[](uint32_t i) const
	{
		assert(i < 2);
		return m_corner[i];
	}
	inline vec2I& operator[](uint32_t i)
	{
		assert(i < 2);
		return m_corner[i];
	}

	inline rect& translate(int x_ofs, int y_ofs)
	{
		m_corner[0][0] += x_ofs;
		m_corner[0][1] += y_ofs;
		m_corner[1][0] += x_ofs;
		m_corner[1][1] += y_ofs;
		return *this;
	}

	inline rect& init_expand()
	{
		m_corner[0].set(INT_MAX);
		m_corner[1].set(INT_MIN);
		return *this;
	}

	inline rect& expand(int x, int y)
	{
		m_corner[0][0] = std::min(m_corner[0][0], x);
		m_corner[0][1] = std::min(m_corner[0][1], y);
		m_corner[1][0] = std::max(m_corner[1][0], x + 1);
		m_corner[1][1] = std::max(m_corner[1][1], y + 1);
		return *this;
	}

	inline rect& expand(const rect& r)
	{
		m_corner[0][0] = std::min(m_corner[0][0], r[0][0]);
		m_corner[0][1] = std::min(m_corner[0][1], r[0][1]);
		m_corner[1][0] = std::max(m_corner[1][0], r[1][0]);
		m_corner[1][1] = std::max(m_corner[1][1], r[1][1]);
		return *this;
	}

	inline bool touches(const rect& r) const
	{
		for (uint32_t i = 0; i < 2; i++)
		{
			if (r[1][i] <= m_corner[0][i])
				return false;
			else if (r[0][i] >= m_corner[1][i])
				return false;
		}

		return true;
	}

	inline bool fully_within(const rect& r) const
	{
		for (uint32_t i = 0; i < 2; i++)
		{
			if (m_corner[0][i] < r[0][i])
				return false;
			else if (m_corner[1][i] > r[1][i])
				return false;
		}

		return true;
	}

	inline bool intersect(const rect& r)
	{
		if (!touches(r))
		{
			clear();
			return false;
		}

		for (uint32_t i = 0; i < 2; i++)
		{
			m_corner[0][i] = std::max<int>(m_corner[0][i], r[0][i]);
			m_corner[1][i] = std::min<int>(m_corner[1][i], r[1][i]);
		}

		return true;
	}

	inline bool contains(int x, int y) const
	{
		return (x >= m_corner[0][0]) && (x < m_corner[1][0]) &&
			(y >= m_corner[0][1]) && (y < m_corner[1][1]);
	}

	inline bool contains(const vec2I& p) const
	{
		return contains(p[0], p[1]);
	}

private:
	vec2I m_corner[2];
};

inline rect make_rect(uint32_t width, uint32_t height)
{
	return rect(0, 0, width, height);
}

struct color_quad_u8
{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4201)
#endif
	union
	{
		uint8_t m_c[4];
		struct
		{
			uint8_t r;
			uint8_t g;
			uint8_t b;
			uint8_t a;
		};
	};
#ifdef _MSC_VER
#pragma warning(pop)
#endif

	inline color_quad_u8(eClear) : color_quad_u8(0, 0, 0, 0) { }

	inline color_quad_u8(uint8_t cr, uint8_t cg, uint8_t cb, uint8_t ca)
	{
		set(cr, cg, cb, ca);
	}

	inline color_quad_u8(uint8_t cy = 0, uint8_t ca = 255)
	{
		set(cy, ca);
	}

	inline void clear()
	{
		set(0, 0, 0, 0);
	}

	inline color_quad_u8& set(uint8_t cy, uint8_t ca = 255)
	{
		m_c[0] = cy;
		m_c[1] = cy;
		m_c[2] = cy;
		m_c[3] = ca;
		return *this;
	}

	inline color_quad_u8& set(uint8_t cr, uint8_t cg, uint8_t cb, uint8_t ca)
	{
		m_c[0] = cr;
		m_c[1] = cg;
		m_c[2] = cb;
		m_c[3] = ca;
		return *this;
	}

	inline color_quad_u8& set_clamped(int cr, int cg, int cb, int ca)
	{
		m_c[0] = (uint8_t)clamp(cr, 0, 255);
		m_c[1] = (uint8_t)clamp(cg, 0, 255);
		m_c[2] = (uint8_t)clamp(cb, 0, 255);
		m_c[3] = (uint8_t)clamp(ca, 0, 255);
		return *this;
	}

	color_quad_u8& set_alpha(int ca) { a = (uint8_t)clamp(ca, 0, 255); return *this; }

	inline uint8_t& operator[] (uint32_t i) { assert(i < 4);  return m_c[i]; }
	inline uint8_t operator[] (uint32_t i) const { assert(i < 4); return m_c[i]; }
		
	inline int get_luma() const { return (13938U * m_c[0] + 46869U * m_c[1] + 4729U * m_c[2] + 32768U) >> 16U; } // REC709 weightings

	inline bool operator== (const color_quad_u8& other) const
	{
		return (m_c[0] == other.m_c[0]) && (m_c[1] == other.m_c[1]) && (m_c[2] == other.m_c[2]) && (m_c[3] == other.m_c[3]);
	}

	inline bool operator!= (const color_quad_u8& other) const
	{
		return !(*this == other);
	}

	inline uint32_t squared_distance(const color_quad_u8& c, bool alpha = true) const
	{
		return square(r - c.r) + square(g - c.g) + square(b - c.b) + (alpha ? square(a - c.a) : 0);
	}

	inline bool rgb_equals(const color_quad_u8& rhs) const
	{
		return (r == rhs.r) && (g == rhs.g) && (b == rhs.b);
	}
};
typedef std::vector<color_quad_u8> color_quad_u8_vec;

inline uint32_t color_distance(bool perceptual, const color_quad_u8& e1, const color_quad_u8& e2, bool alpha)
{
	if (perceptual)
	{
		const float l1 = e1.r * .2126f + e1.g * .715f + e1.b * .0722f;
		const float cr1 = e1.r - l1;
		const float cb1 = e1.b - l1;

		const float l2 = e2.r * .2126f + e2.g * .715f + e2.b * .0722f;
		const float cr2 = e2.r - l2;
		const float cb2 = e2.b - l2;

		const float dl = l1 - l2;
		const float dcr = cr1 - cr2;
		const float dcb = cb1 - cb2;

		uint32_t d = static_cast<uint32_t>(
			32.0f * 4.0f * dl * dl +
			32.0f * 2.0f * (.5f / (1.0f - .2126f)) * (.5f / (1.0f - .2126f)) * dcr * dcr +
			32.0f * .25f * (.5f / (1.0f - .0722f)) * (.5f / (1.0f - .0722f)) * dcb * dcb);
		
		if (alpha)
		{
			int da = (int)e1.a - (int)e2.a;

			d += static_cast<uint32_t>(128.0f * da * da);
		}

		return d;
	}
	else
		return e1.squared_distance(e2, alpha);
}

extern color_quad_u8 g_white_color_u8, g_black_color_u8, g_red_color_u8, g_green_color_u8, g_blue_color_u8, g_yellow_color_u8, g_purple_color_u8, g_magenta_color_u8, g_cyan_color_u8;

class image_u8
{
public:
	image_u8() :
		m_width(0), m_height(0),
		m_clip_rect(cClear)
	{
	}

	image_u8(uint32_t width, uint32_t height) :
		m_width(width), m_height(height),
		m_clip_rect(0, 0, width, height)
	{
		m_pixels.resize(width * height);
	}

	inline const color_quad_u8_vec& get_pixels() const { return m_pixels; }
	inline color_quad_u8_vec& get_pixels() { return m_pixels; }

	inline uint32_t width() const { return m_width; }
	inline uint32_t height() const { return m_height; }
	inline uint32_t total_pixels() const { return m_width * m_height; }
	
	inline const rect& get_clip_rect() const { return m_clip_rect; }

	inline void set_clip_rect(const rect& r)
	{
		assert((r.get_left() >= 0) && (r.get_top() >= 0) && (r.get_right() <= (int)m_width) && (r.get_bottom() <= (int)m_height));

		m_clip_rect = r;
	}

	inline void clear_clip_rect() { m_clip_rect.set(0, 0, m_width, m_height); }

	inline bool is_clipped(int x, int y) const { return !m_clip_rect.contains(x, y); }
	
	inline rect get_bounds() const { return rect(0, 0, m_width, m_height); }

	inline color_quad_u8& operator()(uint32_t x, uint32_t y) { assert((x < m_width) && (y < m_height));  return m_pixels[x + m_width * y]; }
	inline const color_quad_u8& operator()(uint32_t x, uint32_t y) const { assert((x < m_width) && (y < m_height));  return m_pixels[x + m_width * y]; }

	image_u8& clear()
	{
		m_width = m_height = 0;
		m_clip_rect.clear();
		m_pixels.clear();
		return *this;
	}

	image_u8& init(uint32_t width, uint32_t height)
	{
		clear();

		m_width = width;
		m_height = height;
		m_clip_rect.set(0, 0, width, height);
		m_pixels.resize(width * height);
		return *this;
	}

	image_u8& set_all(const color_quad_u8& p)
	{
		for (uint32_t i = 0; i < m_pixels.size(); i++)
			m_pixels[i] = p;
		return *this;
	}

	inline const color_quad_u8& get_clamped(int x, int y) const { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }
	inline color_quad_u8& get_clamped(int x, int y) { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }

	inline image_u8& set_pixel_clipped(int x, int y, const color_quad_u8& c)
	{
		if (!is_clipped(x, y))
			(*this)(x, y) = c;
		return *this;
	}

	inline image_u8& fill_box(int x, int y, int w, int h, const color_quad_u8& c)
	{
		for (int y_ofs = 0; y_ofs < h; y_ofs++)
			for (int x_ofs = 0; x_ofs < w; x_ofs++)
				set_pixel_clipped(x + x_ofs, y + y_ofs, c);
		return *this;
	}

	void invert_box(int inX, int inY, int inW, int inH)
	{
		for (int y = 0; y < inH; y++)
		{
			const uint32_t yy = inY + y;

			for (int x = 0; x < inW; x++)
			{
				const uint32_t xx = inX + x;

				if (is_clipped(xx, yy))
					continue;

				color_quad_u8 c((*this)(xx, yy));

				c.r = 255 - c.r;
				c.g = 255 - c.g;
				c.b = 255 - c.b;

				set_pixel_clipped(xx, yy, c);
			}
		}
	}

	image_u8& crop_dup_borders(uint32_t w, uint32_t h)
	{
		const uint32_t orig_w = m_width, orig_h = m_height;

		crop(w, h);

		if (orig_w && orig_h)
		{
			if (m_width > orig_w)
			{
				for (uint32_t x = orig_w; x < m_width; x++)
					for (uint32_t y = 0; y < m_height; y++)
						set_pixel_clipped(x, y, get_clamped(std::min(x, orig_w - 1U), std::min(y, orig_h - 1U)));
			}

			if (m_height > orig_h)
			{
				for (uint32_t y = orig_h; y < m_height; y++)
					for (uint32_t x = 0; x < m_width; x++)
						set_pixel_clipped(x, y, get_clamped(std::min(x, orig_w - 1U), std::min(y, orig_h - 1U)));
			}
		}
		return *this;
	}

	image_u8& crop(uint32_t new_width, uint32_t new_height)
	{
		if ((m_width == new_width) && (m_height == new_height))
			return *this;

		image_u8 new_image(new_width, new_height);

		const uint32_t w = std::min(m_width, new_width);
		const uint32_t h = std::min(m_height, new_height);

		for (uint32_t y = 0; y < h; y++)
			for (uint32_t x = 0; x < w; x++)
				new_image(x, y) = (*this)(x, y);

		return swap(new_image);
	}

	image_u8& swap(image_u8& other)
	{
		std::swap(m_width, other.m_width);
		std::swap(m_height, other.m_height);
		std::swap(m_pixels, other.m_pixels);
		std::swap(m_clip_rect, other.m_clip_rect);
		return *this;
	}

	// No clipping
	inline void get_block(uint32_t bx, uint32_t by, uint32_t width, uint32_t height, color_quad_u8* pPixels) const
	{
		assert((bx * width + width) <= m_width);
		assert((by * height + height) <= m_height);

		for (uint32_t y = 0; y < height; y++)
			memcpy(pPixels + y * width, &(*this)(bx * width, by * height + y), width * sizeof(color_quad_u8));
	}

	inline void get_block_clamped(uint32_t bx, uint32_t by, uint32_t width, uint32_t height, color_quad_u8* pPixels) const
	{
		for (uint32_t y = 0; y < height; y++)
			for (uint32_t x = 0; x < width; x++)
				pPixels[x + y * width] = get_clamped(bx * width + x, by * height + y);
	}
		
	// No clipping
	inline void set_block(uint32_t bx, uint32_t by, uint32_t width, uint32_t height, const color_quad_u8* pPixels)
	{
		assert((bx * width + width) <= m_width);
		assert((by * height + height) <= m_height);

		for (uint32_t y = 0; y < height; y++)
			memcpy(&(*this)(bx * width, by * height + y), pPixels + y * width, width * sizeof(color_quad_u8));
	}

	image_u8& swizzle(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
	{
		assert((r | g | b | a) <= 3);
		for (uint32_t y = 0; y < m_height; y++)
		{
			for (uint32_t x = 0; x < m_width; x++)
			{
				color_quad_u8 tmp((*this)(x, y));
				(*this)(x, y).set(tmp[r], tmp[g], tmp[b], tmp[a]);
			}
		}

		return *this;
	}

	struct pixel_coord
	{
		uint16_t m_x, m_y;
		pixel_coord() { }
		pixel_coord(uint32_t x, uint32_t y) : m_x((uint16_t)x), m_y((uint16_t)y) { }
	};
		
	uint32_t flood_fill(int x, int y, const color_quad_u8& c, const color_quad_u8& b, std::vector<pixel_coord>* pSet_pixels = nullptr);

	void draw_line(int xs, int ys, int xe, int ye, const color_quad_u8& color);
		
	inline void set_pixel_clipped_alphablend(int x, int y, const color_quad_u8& c)
	{
		if (is_clipped(x, y))
			return;

		color_quad_u8 ct(m_pixels[x + y * m_width]);

		ct.r = static_cast<uint8_t>(ct.r + ((c.r - ct.r) * c.a) / 255);
		ct.g = static_cast<uint8_t>(ct.g + ((c.g - ct.g) * c.a) / 255);
		ct.b = static_cast<uint8_t>(ct.b + ((c.b - ct.b) * c.a) / 255);
		
		m_pixels[x + y * m_width] = ct;
	}

private:
	color_quad_u8_vec m_pixels;
	uint32_t m_width, m_height;
	rect m_clip_rect;

	struct fill_segment
	{
		int16_t m_y, m_xl, m_xr, m_dy;

		fill_segment(int y, int xl, int xr, int dy) :
			m_y((int16_t)y), m_xl((int16_t)xl), m_xr((int16_t)xr), m_dy((int16_t)dy)
		{
		}
	};

	inline bool flood_fill_is_inside(int x, int y, const color_quad_u8& b) const
	{
		if (is_clipped(x, y))
			return false;

		return (*this)(x, y) == b;
	}

	void rasterize_line(int xs, int ys, int xe, int ye, int pred, int inc_dec, int e, int e_inc, int e_no_inc, const color_quad_u8& color);

	void draw_aaline_pixel(int x, int y, int a, color_quad_u8 color)
	{
		color.a = static_cast<uint8_t>(255 - a);
		set_pixel_clipped_alphablend(x, y, color);
	}
};

//bool load_png(const char* pFilename, image_u8& img);

//bool save_png(const char* pFilename, const image_u8& img, bool save_alpha);

// Writes an uncompressed (no-RLE) Windows .BMP. Self-contained (no PNG library needed). save_alpha=true writes
// 32-bpp BGRA using a BITMAPV4HEADER with explicit channel masks (so the alpha channel is unambiguously
// recognized by viewers/tools); save_alpha=false writes 24-bpp BGR (rows padded to 4 bytes). Returns false on
// file I/O error.
bool save_bmp(const char* pFilename, const image_u8& img, bool save_alpha);

class image_metrics
{
public:
	double m_max, m_mean, m_mean_squared, m_root_mean_squared, m_peak_snr;

	image_metrics()
	{
		clear();
	}

	void clear()
	{
		memset(this, 0, sizeof(*this));
	}

	void compute(const image_u8& a, const image_u8& b, uint32_t first_channel, uint32_t num_channels)
	{
		const bool average_component_error = true;

		const uint32_t width = std::min(a.width(), b.width());
		const uint32_t height = std::min(a.height(), b.height());

		assert((first_channel < 4U) && (first_channel + num_channels <= 4U));

		// Histogram approach originally due to Charles Bloom.
		double hist[256];
		memset(hist, 0, sizeof(hist));

		for (uint32_t y = 0; y < height; y++)
		{
			for (uint32_t x = 0; x < width; x++)
			{
				const color_quad_u8& ca = a(x, y);
				const color_quad_u8& cb = b(x, y);

				if (!num_channels)
					hist[iabs(ca.get_luma() - cb.get_luma())]++;
				else
				{
					for (uint32_t c = 0; c < num_channels; c++)
						hist[iabs(ca[first_channel + c] - cb[first_channel + c])]++;
				}
			}
		}

		m_max = 0;
		double sum = 0.0f, sum2 = 0.0f;
		for (uint32_t i = 0; i < 256; i++)
		{
			if (!hist[i])
				continue;

			m_max = std::max<double>(m_max, i);

			double x = i * hist[i];

			sum += x;
			sum2 += i * x;
		}

		// See http://richg42.blogspot.com/2016/09/how-to-compute-psnr-from-old-berkeley.html
		double total_values = width * height;

		if (average_component_error)
			total_values *= clamp<uint32_t>(num_channels, 1, 4);

		m_mean = clamp<double>(sum / total_values, 0.0f, 255.0f);
		m_mean_squared = clamp<double>(sum2 / total_values, 0.0f, 255.0f * 255.0f);

		m_root_mean_squared = sqrt(m_mean_squared);

		if (!m_root_mean_squared)
			m_peak_snr = 100.0f;
		else
			m_peak_snr = clamp<double>(log10(255.0f / m_root_mean_squared) * 20.0f, 0.0f, 100.0f);
	}
};

class imagef
{
public:
	imagef() :
		m_width(0), m_height(0), m_pitch(0)
	{
	}

	imagef(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX) :
		m_width(0), m_height(0), m_pitch(0)
	{
		resize(w, h, p);
	}

	imagef(const imagef& other) :
		m_width(0), m_height(0), m_pitch(0)
	{
		*this = other;
	}

	imagef& swap(imagef& other)
	{
		std::swap(m_width, other.m_width);
		std::swap(m_height, other.m_height);
		std::swap(m_pitch, other.m_pitch);
		m_pixels.swap(other.m_pixels);
		return *this;
	}

	imagef& operator= (const imagef& rhs)
	{
		if (this != &rhs)
		{
			m_width = rhs.m_width;
			m_height = rhs.m_height;
			m_pitch = rhs.m_pitch;
			m_pixels = rhs.m_pixels;
		}
		return *this;
	}

	imagef& clear()
	{
		m_width = 0;
		m_height = 0;
		m_pitch = 0;
		m_pixels.resize(0);
		return *this;
	}

	imagef& set(const image_u8& src, const vec4F& scale = vec4F(1), const vec4F& bias = vec4F(0))
	{
		const uint32_t width = src.width();
		const uint32_t height = src.height();

		resize(width, height);

		for (int y = 0; y < (int)height; y++)
		{
			for (uint32_t x = 0; x < width; x++)
			{
				const color_quad_u8& src_pixel = src(x, y);
				(*this)(x, y).set((float)src_pixel.r * scale[0] + bias[0], (float)src_pixel.g * scale[1] + bias[1], (float)src_pixel.b * scale[2] + bias[2], (float)src_pixel.a * scale[3] + bias[3]);
			}
		}

		return *this;
	}

	imagef& resize(const imagef& other, uint32_t p = UINT32_MAX, const vec4F& background = vec4F(0, 0, 0, 1))
	{
		return resize(other.get_width(), other.get_height(), p, background);
	}

	imagef& resize(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const vec4F& background = vec4F(0, 0, 0, 1))
	{
		return crop(w, h, p, background);
	}

	imagef& set_all(const vec4F& c)
	{
		for (uint32_t i = 0; i < m_pixels.size(); i++)
			m_pixels[i] = c;
		return *this;
	}

	imagef& fill_box(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const vec4F& c)
	{
		for (uint32_t iy = 0; iy < h; iy++)
			for (uint32_t ix = 0; ix < w; ix++)
				set_pixel_clipped(x + ix, y + iy, c);
		return *this;
	}

	imagef& crop(uint32_t w, uint32_t h, uint32_t p = UINT32_MAX, const vec4F& background = vec4F(0, 0, 0, 1))
	{
		if (p == UINT32_MAX)
			p = w;

		if ((w == m_width) && (m_height == h) && (m_pitch == p))
			return *this;

		if ((!w) || (!h) || (!p))
		{
			clear();
			return *this;
		}

		vec4F_array cur_state;
		cur_state.swap(m_pixels);

		m_pixels.resize(p * h);

		for (uint32_t y = 0; y < h; y++)
		{
			for (uint32_t x = 0; x < w; x++)
			{
				if ((x < m_width) && (y < m_height))
					m_pixels[x + y * p] = cur_state[x + y * m_pitch];
				else
					m_pixels[x + y * p] = background;
			}
		}

		m_width = w;
		m_height = h;
		m_pitch = p;

		return *this;
	}

	inline const vec4F& operator() (uint32_t x, uint32_t y) const { assert(x < m_width&& y < m_height); return m_pixels[x + y * m_pitch]; }
	inline vec4F& operator() (uint32_t x, uint32_t y) { assert(x < m_width&& y < m_height); return m_pixels[x + y * m_pitch]; }

	inline const vec4F& get_clamped(int x, int y) const { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }
	inline vec4F& get_clamped(int x, int y) { return (*this)(clamp<int>(x, 0, m_width - 1), clamp<int>(y, 0, m_height - 1)); }

	inline const vec4F& get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v) const
	{
		x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
		y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
		return m_pixels[x + y * m_pitch];
	}

	inline vec4F& get_clamped_or_wrapped(int x, int y, bool wrap_u, bool wrap_v)
	{
		x = wrap_u ? posmod(x, m_width) : clamp<int>(x, 0, m_width - 1);
		y = wrap_v ? posmod(y, m_height) : clamp<int>(y, 0, m_height - 1);
		return m_pixels[x + y * m_pitch];
	}

	inline imagef& set_pixel_clipped(int x, int y, const vec4F& c)
	{
		if ((static_cast<uint32_t>(x) < m_width) && (static_cast<uint32_t>(y) < m_height))
			(*this)(x, y) = c;
		return *this;
	}

	// Very straightforward blit with full clipping. Not fast, but it works.
	imagef& blit(const imagef& src, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y)
	{
		for (int y = 0; y < src_h; y++)
		{
			const int sy = src_y + y;
			if (sy < 0)
				continue;
			else if (sy >= (int)src.get_height())
				break;

			for (int x = 0; x < src_w; x++)
			{
				const int sx = src_x + x;
				if (sx < 0)
					continue;
				else if (sx >= (int)src.get_height())
					break;

				set_pixel_clipped(dst_x + x, dst_y + y, src(sx, sy));
			}
		}

		return *this;
	}

	const imagef& extract_block_clamped(vec4F* pDst, uint32_t src_x, uint32_t src_y, uint32_t w, uint32_t h) const
	{
		for (uint32_t y = 0; y < h; y++)
			for (uint32_t x = 0; x < w; x++)
				*pDst++ = get_clamped(src_x + x, src_y + y);
		return *this;
	}

	imagef& set_block_clipped(const vec4F* pSrc, uint32_t dst_x, uint32_t dst_y, uint32_t w, uint32_t h)
	{
		for (uint32_t y = 0; y < h; y++)
			for (uint32_t x = 0; x < w; x++)
				set_pixel_clipped(dst_x + x, dst_y + y, *pSrc++);
		return *this;
	}

	inline uint32_t get_width() const { return m_width; }
	inline uint32_t get_height() const { return m_height; }
	inline uint32_t get_pitch() const { return m_pitch; }
	inline uint32_t get_total_pixels() const { return m_width * m_height; }

	inline uint32_t get_block_width(uint32_t w) const { return (m_width + (w - 1)) / w; }
	inline uint32_t get_block_height(uint32_t h) const { return (m_height + (h - 1)) / h; }
	inline uint32_t get_total_blocks(uint32_t w, uint32_t h) const { return get_block_width(w) * get_block_height(h); }

	inline const vec4F_array& get_pixels() const { return m_pixels; }
	inline vec4F_array& get_pixels() { return m_pixels; }

	inline const vec4F* get_ptr() const { return &m_pixels[0]; }
	inline vec4F* get_ptr() { return &m_pixels[0]; }

private:
	uint32_t m_width, m_height, m_pitch;  // all in pixels
	vec4F_array m_pixels;
};

enum
{
	cComputeGaussianFlagNormalize = 1,
	cComputeGaussianFlagPrint = 2,
	cComputeGaussianFlagNormalizeCenterToOne = 4
};

// size_x/y should be odd
void compute_gaussian_kernel(float* pDst, int size_x, int size_y, float sigma_sqr, uint32_t flags);

void gaussian_filter(imagef& dst, const imagef& orig_img, uint32_t odd_filter_width, float sigma_sqr, bool wrapping = false, uint32_t width_divisor = 1, uint32_t height_divisor = 1);

vec4F compute_ssim(const imagef& a, const imagef& b);

vec4F compute_ssim(const image_u8& a, const image_u8& b, bool luma);

struct block8
{
	uint64_t m_vals[1];
};

typedef std::vector<block8> block8_vec;

struct block16
{
	uint64_t m_vals[2];
};

typedef std::vector<block16> block16_vec;

bool save_dds(const char* pFilename, uint32_t width, uint32_t height, const void* pBlocks, uint32_t pixel_format_bpp, DXGI_FORMAT dxgi_format, bool srgb, bool force_dx10_header);

void strip_extension(std::string& s);
void strip_path(std::string& s);

uint32_t hash_hsieh(const uint8_t* pBuf, size_t len);

// https://www.johndcook.com/blog/standard_deviation/
// This class is for small numbers of integers, so precision shouldn't be an issue.
class tracked_stat
{
public:
	tracked_stat() { clear(); }

	void clear() { m_num = 0; m_total = 0; m_total2 = 0; }

	void update(uint32_t val) { m_num++; m_total += val; m_total2 += val * val; }

	tracked_stat& operator += (uint32_t val) { update(val); return *this; }

	uint32_t get_number_of_values() const { return m_num; }
	uint64_t get_total() const { return m_total; }
	uint64_t get_total2() const { return m_total2; }

	float get_mean() const { return m_num ? (float)m_total / m_num : 0.0f; };
		
	float get_variance() const { return m_num ? ((float)(m_num * m_total2 - m_total * m_total)) / (m_num * m_num) : 0.0f; }
	float get_std_dev() const { return m_num ? sqrtf((float)(m_num * m_total2 - m_total * m_total)) / m_num : 0.0f; }

	float get_sample_variance() const { return (m_num > 1) ? ((float)(m_num * m_total2 - m_total * m_total)) / (m_num * (m_num - 1)) : 0.0f; }
	float get_sample_std_dev() const { return (m_num > 1) ? sqrtf(get_sample_variance()) : 0.0f; }

private:
	uint32_t m_num;
	uint64_t m_total;
	uint64_t m_total2;
};

inline float compute_covariance(const float* pA, const float* pB, const tracked_stat& a, const tracked_stat& b, bool sample)
{
	const uint32_t n = a.get_number_of_values();
	assert(n == b.get_number_of_values());

	if (!n)
	{
		assert(0);
		return 0.0f;
	}
	if ((sample) && (n == 1))
	{
		assert(0);
		return 0;
	}

	const float mean_a = a.get_mean();
	const float mean_b = b.get_mean();
	
	float total = 0.0f;
	for (uint32_t i = 0; i < n; i++)
		total += (pA[i] - mean_a) * (pB[i] - mean_b);

	return total / (sample ? (n - 1) : n);
}

inline float compute_correlation_coefficient(const float* pA, const float* pB, const tracked_stat& a, const tracked_stat& b, float c, bool sample)
{
	if (!a.get_number_of_values())
		return 1.0f;

	float covar = compute_covariance(pA, pB, a, b, sample);
	float std_dev_a = sample ? a.get_sample_std_dev() : a.get_std_dev();
	float std_dev_b = sample ? b.get_sample_std_dev() : b.get_std_dev();
	float denom = std_dev_a * std_dev_b + c;

	if (denom < .0000125f)
		return 1.0f;

	float result = (covar + c) / denom;
	
	return clamp(result, -1.0f, 1.0f);
}

float compute_block_max_std_dev(const color_quad_u8* pPixels, uint32_t block_width, uint32_t block_height, uint32_t num_comps);

class rand
{
	std::mt19937 m_mt;

public:
	rand() {	}

	rand(uint32_t s) { seed(s); }
	void seed(uint32_t s) { m_mt.seed(s); }

	// between [l,h]
	int irand(int l, int h) { std::uniform_int_distribution<int> d(l, h); return d(m_mt); }

	uint32_t urand32() { return static_cast<uint32_t>(irand(INT32_MIN, INT32_MAX)); }

	bool bit() { return irand(0, 1) == 1; }

	uint8_t byte() { return static_cast<uint8_t>(urand32()); }

	// between [l,h)
	float frand(float l, float h) { std::uniform_real_distribution<float> d(l, h); return d(m_mt); }

	float gaussian(float mean, float stddev) { std::normal_distribution<float> d(mean, stddev); return d(m_mt); }
};

bool save_astc_file(const char* pFilename, block16_vec& blocks, uint32_t width, uint32_t height, uint32_t block_width, uint32_t block_height);
bool load_astc_file(const char* pFilename, block16_vec& blocks, uint32_t& width, uint32_t& height, uint32_t& block_width, uint32_t& block_height);

class value_stats
{
public:
	value_stats()
	{
		clear();
	}

	void clear()
	{
		m_sum = 0;
		m_sum2 = 0;
		m_num = 0;
		m_min = 1e+39;
		m_max = -1e+39;
		m_vals.clear();
	}

	void add(double val)
	{
		m_sum += val;
		m_sum2 += val * val;

		m_num++;

		m_min = std::min(m_min, val);
		m_max = std::max(m_max, val);

		m_vals.push_back(val);
	}

	void add(int val)
	{
		add(static_cast<double>(val));
	}

	void add(uint32_t val)
	{
		add(static_cast<double>(val));
	}

	void add(int64_t val)
	{
		add(static_cast<double>(val));
	}

	void add(uint64_t val)
	{
		add(static_cast<double>(val));
	}

	void print(const char* pPrefix = "")
	{
		if (!m_vals.size())
			printf("%s: Empty\n", pPrefix);
		else
			printf("%s: Samples: %llu, Total: %f, Avg: %f, Std Dev: %f, Min: %f, Max: %f, Mean: %f\n",
				pPrefix, (unsigned long long)get_num(), get_total(), get_average(), get_std_dev(), get_min(), get_max(), get_mean());
	}

	double get_total() const
	{
		return m_sum;
	}

	double get_average() const
	{
		return m_num ? (m_sum / m_num) : 0.0f;
	}

	double get_min() const
	{
		return m_min;
	}

	double get_max() const
	{
		return m_max;
	}

	uint64_t get_num() const
	{
		return m_num;
	}

	double get_val(uint32_t index) const
	{
		return m_vals[index];
	}

	// Returns population standard deviation
	double get_std_dev() const
	{
		if (!m_num)
			return 0.0f;
		
		// TODO: FP precision
		return sqrt((m_sum2 - ((m_sum * m_sum) / m_num)) / m_num);
	}

	double get_mean() const
	{
		if (!m_num)
			return 0.0f;

		std::vector<double> sorted_vals(m_vals);
		std::sort(sorted_vals.begin(), sorted_vals.end());
		
		return sorted_vals[sorted_vals.size() / 2];
	}

private:
	double m_sum;
	double m_sum2;

	uint64_t m_num;

	double m_min;
	double m_max;

	mutable std::vector<double> m_vals;
};

//uint32_t get_deflate_size(const void* pData, size_t data_size);

bool read_file(const char* pFilename, uint8_vec& buf);

} // namespace utils

#ifdef _MSC_VER
#pragma warning (pop)
#endif