// Copyright (c) 2021 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once

#define MATH_PI ((float)M_PI)

/**
 * Returns the modulous a result for b. Consdiders negative numbers correctly.
 * @param a Number to modulo against. (a % b)
 * @param b Number to modulo with. (a % b)
 * @returns The modulo result.
 */
#define mathMod(a,b)  ((a)%(b)+(b))%(b)

/**
 * Returns the modulous a result for b. Works for floating point numbers.
 * @param a Number to modulo against. (a % b)
 * @param b Number to modulo with. (a % b)
 * @returns The modulo result.
 */
#define mathModFloat(a, b) (float)fmod(a, b)

/**
 * Returns the maximum of two numbers.
 * @param a Number A.
 * @param b Number B.
 * @returns B if greater than A, otherwise B.
 */
#define mathMax(a,b)  (a<b?b:a)

/**
 * Returns the minimum of two numbers.
 * @param a Number A.
 * @param b Number B.
 * @returns B if smaller than A, otherwise A.
 */
#define mathMin(a,b)  (a>b?b:a)

/**
 * Clamp a number between two numbers.
 * @param val Value to clamp.
 * @param min The minimum number to clamp to.
 * @param max The maximum number to clamp to.
 */
#define mathClamp(val,min,max) mathMin(mathMax(val,min),max)

/**
 * Returns the absolute value. This will make -n equal n and y equal y.
 * @param n Number to abs.
 * @returns The absolute number.
 */
#define mathAbs(n)    (n<0?-n:n)

/**
 * Convert degrees to radians.
 * @param n Degrees to convert.
 * @returns The number in radians.
 */
#define mathDeg2Rad(n) (n * MATH_PI / 180.0f)

/**
 * Convert radians to degrees.
 * @param n Radians to convert.
 * @returns The number in degrees.
 */
#define mathRad2Deg(n) (n * 180.0f / MATH_PI)

/**
 * Sign the given number, essentially clamps > 0 to 1, and < 0 to -1.
 * @param n Number to sign.
 * @returns The signed number.
 */
#define mathSign(n) (n>=0 ? 1.0f : -1.0f)

/**
 * Round a number down to the nearest whole number.
 * @param n Floating number to round down.
 * @returns The floor of the input.
 */
#define mathFloor(n) (floorf(n))