#include "cell_math.h"
#include <math.h>

JSValue js_math_e (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double power = 1.0;
  if (argc > 0 && !JS_IsNull (argv[0])) {
    if (JS_ToFloat64 (ctx, &power, argv[0]) < 0) return JS_EXCEPTION;
  }
  return JS_NewFloat64 (ctx, exp (power));
}

JSValue js_math_ln (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, log (x));
}

JSValue js_math_log10 (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, log10 (x));
}

JSValue js_math_log2 (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, log2 (x));
}

JSValue js_math_power (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x, y;
  if (argc < 2) return JS_NULL;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  if (JS_ToFloat64 (ctx, &y, argv[1]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, pow (x, y));
}

JSValue js_math_root (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x, n;
  if (argc < 2) return JS_NULL;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  if (JS_ToFloat64 (ctx, &n, argv[1]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, pow (x, 1.0 / n));
}

JSValue js_math_sqrt (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  double x;
  if (JS_ToFloat64 (ctx, &x, argv[0]) < 0) return JS_EXCEPTION;
  return JS_NewFloat64 (ctx, sqrt (x));
}
