/**
 * @file mathlib.h
 * @brief Mathematical library for calculator project
 */

#ifndef MATHLIB_H
#define MATHLIB_H

namespace mathlib {

enum MathError {
    OK,
    DIVISION_BY_ZERO,
    NEGATIVE_FACTORIAL,
    INVALID_ROOT,
    INVALID_ARGUMENT,
};

// Basic operations

/**
 * @brief Add two numbers
 * @param a first number
 * @param b second number
 * @return sum of a and b
 */
double add(double a, double b);

/**
 * @brief Subtract two numbers
 * @param a first number
 * @param b second number
 * @return difference of a and b
 */
double subtract(double a, double b);

/**
 * @brief Multiply two numbers
 * @param a first number
 * @param b second number
 * @return product of a and b
 */
double multiply(double a, double b);

/**
 * @brief Divide two numbers
 * @param a first number
 * @param b second number
 * @param err error code (division by zero)
 * @return quotient of a and b
 */
double divide(double a, double b, MathError &err);

// Advanced operations

/**
 * @brief Compute factorial of a number
 * @param a input number (must be >= 0)
 * @param err error code (negative input)
 * @return factorial of a
 */
double factorial(int a, MathError &err);

/**
 * @brief Raise a number to a natural exponent
 * @param base input number
 * @param exp exponent (must be >= 0)
 * @return base raised to the power of exponent
 */
double power(double base, int exp);

/**
 * @brief Compute n-th root of a number
 * @param base input number
 * @param n degree of the root (must be > 0)
 * @param err error code (invalid root)
 * @return n-th root of base
 */
double root(double base, int n, MathError &err);

/**
 * @brief Compute modulo of two numbers
 * @param a first number
 * @param b second number
 * @param err error code (division by zero)
 * @return remainder of a divided by b
 */
double modulo(double a, double b, MathError &err);

} // namespace mathlib

#endif