// MoonSteel - 工具函数

// ==================== 基本数学运算 ====================

///|
/// 计算平方
pub fn square(x : Double) -> Double {
  x * x
}

///|
/// 计算立方
pub fn cube(x : Double) -> Double {
  x * x * x
}

///|
/// 计算四次方
pub fn pow4(x : Double) -> Double {
  let x2 = x * x
  x2 * x2
}

///|
/// 计算绝对值
pub fn abs(x : Double) -> Double {
  if x < 0.0 {
    -x
  } else {
    x
  }
}

///|
/// 计算最大值
pub fn max(a : Double, b : Double) -> Double {
  if a > b {
    a
  } else {
    b
  }
}

///|
/// 计算最小值
pub fn min(a : Double, b : Double) -> Double {
  if a < b {
    a
  } else {
    b
  }
}

///|
/// 安全除法,分母为零时返回默认值
pub fn safe_div(num : Double, den : Double, fallback : Double) -> Double {
  if abs(den) <= EPSILON {
    fallback
  } else {
    num / den
  }
}

///|
/// 判断两个浮点数是否近似相等
pub fn approx_equal(a : Double, b : Double, tolerance : Double) -> Bool {
  abs(a - b) < tolerance
}

///|
/// 限制值在范围内
pub fn clamp(value : Double, min_val : Double, max_val : Double) -> Double {
  if value < min_val {
    min_val
  } else if value > max_val {
    max_val
  } else {
    value
  }
}

// ==================== 角度转换 ====================

///|
/// 角度转弧度
pub fn deg_to_rad(deg : Double) -> Double {
  deg * PI / 180.0
}

///|
/// 弧度转角度
pub fn rad_to_deg(rad : Double) -> Double {
  rad * 180.0 / PI
}

// ==================== 三角函数 ====================

///|
/// 正弦函数
pub fn sin(x : Double) -> Double {
  @math.sin(x)
}

///|
/// 余弦函数
pub fn cos(x : Double) -> Double {
  @math.cos(x)
}

///|
/// 正切函数
pub fn tan(x : Double) -> Double {
  @math.tan(x)
}

///|
/// 反正切函数 (返回弧度)
pub fn atan2(y : Double, x : Double) -> Double {
  @math.atan2(y, x)
}

// ==================== 截面几何性质 ====================

///|
/// 矩形截面惯性矩
/// I = b * h³ / 12
pub fn rect_inertia(b : Double, h : Double) -> Double {
  b * cube(h) / 12.0
}

///|
/// 矩形截面面积
pub fn rect_area(b : Double, h : Double) -> Double {
  b * h
}

///|
/// 矩形截面抗弯模量
/// W = b * h² / 6
pub fn rect_section_modulus(b : Double, h : Double) -> Double {
  b * square(h) / 6.0
}

///|
/// 圆形截面惯性矩
/// I = π * d⁴ / 64
pub fn circle_inertia(d : Double) -> Double {
  PI * pow4(d) / 64.0
}

///|
/// 圆形截面面积
pub fn circle_area(d : Double) -> Double {
  PI * square(d) / 4.0
}

///|
/// 圆形截面抗弯模量
/// W = π * d³ / 32
pub fn circle_section_modulus(d : Double) -> Double {
  PI * cube(d) / 32.0
}

///|
/// 工字钢截面面积 (简化)
/// A = 2*b*t_f + h_w*t_w
pub fn i_section_area(
  b : Double,
  tf : Double,
  hw : Double,
  tw : Double,
) -> Double {
  2.0 * b * tf + hw * tw
}

///|
/// 工字钢截面惯性矩 (简化,忽略圆角)
/// I_x = b*h³/12 - (b-t_w)*(h-2*t_f)³/12
pub fn i_section_inertia_x(
  b : Double,
  h : Double,
  tf : Double,
  tw : Double,
) -> Double {
  let i_outer = b * cube(h) / 12.0
  let h_inner = h - 2.0 * tf
  let i_inner = (b - tw) * cube(h_inner) / 12.0
  i_outer - i_inner
}

///|
/// 工字钢截面抗弯模量
/// W = I / (h/2)
pub fn i_section_modulus(i : Double, h : Double) -> Double {
  i / (h / 2.0)
}

///|
/// 回转半径
/// i = √(I/A)
pub fn radius_of_gyration(i : Double, a : Double) -> Double {
  if a <= 0.0 {
    return 0.0
  }
  (i / a).sqrt()
}

// ==================== 长细比计算 ====================

///|
/// 长细比
/// λ = l₀ / i
pub fn slenderness_ratio(l0 : Double, i : Double) -> Double {
  if i <= 0.0 {
    return 0.0
  }
  l0 / i
}

///|
/// 换算长细比 (双角钢等)
/// λₑ = √(λ² + λ₁²)
pub fn equivalent_slenderness_ratio(
  lambda : Double,
  lambda1 : Double,
) -> Double {
  (square(lambda) + square(lambda1)).sqrt()
}

// ==================== 稳定系数 (简化计算) ====================

///|
/// 轴心受压构件稳定系数 (简化公式)
/// 实际应查表,这里用近似公式
/// φ ≈ 1 - 0.65 * (λ/100)² (当 λ < 100)
pub fn stability_coefficient_approx(lambda : Double) -> Double {
  if lambda <= 0.0 {
    return 1.0
  }
  if lambda < 20.0 {
    1.0
  } else if lambda < 100.0 {
    let ratio = lambda / 100.0
    1.0 - 0.65 * square(ratio)
  } else if lambda < 150.0 {
    let ratio = lambda / 100.0
    0.35 - 0.15 * (ratio - 1.0)
  } else {
    0.2
  }
}

// ==================== 有效宽度计算 ====================

///|
/// 板件有效宽度 (局部稳定)
/// b_e = ρ * b
pub fn effective_width(b : Double, rho : Double) -> Double {
  b * rho
}

///|
/// 板件有效宽度系数 (简化)
/// ρ = 1.0 (当宽厚比满足要求时)
pub fn effective_width_coefficient(
  b_t_ratio : Double,
  limit : Double,
) -> Double {
  if b_t_ratio <= limit {
    1.0
  } else {
    limit / b_t_ratio
  }
}