// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// THIS FILE WAS AUTO-GENERATED BY ./wpiunits/generate_units.py. DO NOT MODIFY

package edu.wpi.first.units.measure;

import static edu.wpi.first.units.Units.*;
import edu.wpi.first.units.*;

@SuppressWarnings({"unchecked", "cast", "checkstyle", "PMD"})
public interface {{ helpers['type_decl'](name) }} extends Measure<{{ helpers['mtou'](name) }}> {
  static {{ helpers['generics_list'](name) }} {{ helpers['type_usage'](name) }} ofRelativeUnits(double magnitude, {{ helpers['mtou'](name) }} unit) {
    return new Immutable{{ helpers['type_usage'](name) }}(magnitude, unit.toBaseUnits(magnitude), unit);
  }

  static {{ helpers['generics_list'](name) }} {{ helpers['type_usage'](name) }} ofBaseUnits(double baseUnitMagnitude, {{ helpers['mtou'](name) }} unit) {
    return new Immutable{{ helpers['type_usage'](name) }}(unit.fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, unit);
  }

  @Override
  {{ helpers['type_usage'](name) }} copy();

  @Override
  default Mut{{ helpers['type_usage'](name) }} mutableCopy() {
    return new Mut{{ helpers['type_usage'](name) }}(magnitude(), baseUnitMagnitude(), unit());
  }

  @Override
  {{ helpers['mtou'](name) }} unit();

  @Override
  default {{ helpers['mtou'](name) }} baseUnit() { return ({{ helpers['mtou'](name) }}) unit().getBaseUnit(); }

  @Override
  default double in({{ helpers['mtou'](name) }} unit) {
    return unit.fromBaseUnits(baseUnitMagnitude());
  }

  @Override
  default {{ helpers['type_usage'](name) }} unaryMinus() {
    return ({{ helpers['type_usage'](name) }}) unit().ofBaseUnits(0 - baseUnitMagnitude());
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use unaryMinus() instead. This was renamed for consistency with other WPILib classes like Rotation2d
  */
  @Override
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  default {{ helpers['type_usage'](name) }} negate() {
    return ({{ helpers['type_usage'](name) }}) unaryMinus();
  }

  @Override
  default {{ helpers['type_usage'](name) }} plus(Measure<? extends {{ helpers['mtou'](name) }}> other) {
    return ({{ helpers['type_usage'](name) }}) unit().ofBaseUnits(baseUnitMagnitude() + other.baseUnitMagnitude());
  }

  @Override
  default {{ helpers['type_usage'](name) }} minus(Measure<? extends {{ helpers['mtou'](name) }}> other) {
    return ({{ helpers['type_usage'](name) }}) unit().ofBaseUnits(baseUnitMagnitude() - other.baseUnitMagnitude());
  }

  @Override
  default {{ helpers['type_usage'](name) }} times(double multiplier) {
    return ({{ helpers['type_usage'](name) }}) unit().ofBaseUnits(baseUnitMagnitude() * multiplier);
  }

  @Override
  default {{ helpers['type_usage'](name) }} div(double divisor) {
    return ({{ helpers['type_usage'](name) }}) unit().ofBaseUnits(baseUnitMagnitude() / divisor);
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Override
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  default {{ helpers['type_usage'](name) }} divide(double divisor) {
    return ({{ helpers['type_usage'](name) }}) div(divisor);
  }

  @Override
  default {{ config[name]['divide']['Time'] or "Velocity<{}>".format(helpers['mtou'](name)) }} per(TimeUnit period) {
    return div(period.of(1));
  }
{% for unit in math_units -%}
{% if unit == "Dimensionless" %}
  @Override
  default {{ helpers['type_usage'](name) }} div({{ unit }} divisor) {
    return ({{ helpers['type_usage'](name) }}) {{ config[name]['base_unit'] }}.of(baseUnitMagnitude() / divisor.baseUnitMagnitude());
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Override
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  default {{ helpers['type_usage'](name) }} divide({{ unit }} divisor) {
    return ({{ helpers['type_usage'](name) }}) div(divisor);
  }

  @Override
  default {{ helpers['type_usage'](name) }} times({{ unit }} multiplier) {
    return ({{ helpers['type_usage'](name) }}) {{ config[name]['base_unit'] }}.of(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
  }
{% else %}
{% if unit in config[name]['multiply'] %}
{%- if 'implementation' in config[name]['multiply'][unit] -%}
{{ helpers['indent'](config[name]['multiply'][unit]['implementation'], 2) }}
{%- else %}
  @Override
  default {{ config[name]['multiply'][unit] }} times({{ unit }} multiplier) {
    return {{ config[config[name]['multiply'][unit]]['base_unit'] }}.of(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
  }
{%- endif %}
{% else %}
  @Override
  default Mult<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}> times({{ unit }} multiplier) {
    return (Mult<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}>) Measure.super.times(multiplier);
  }
{% endif -%}
{% if unit in config[name]['divide'] %}
  @Override
  default {{ config[name]['divide'][unit] }} div({{ unit }} divisor) {
    return {{ config[config[name]['divide'][unit]]['base_unit'] }}.of(baseUnitMagnitude() / divisor.baseUnitMagnitude());
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Override
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  default {{ config[name]['divide'][unit] }} divide({{ unit }} divisor) {
    return div(divisor);
  }
{% elif unit == "Time" %}
  @Override
  default Velocity<{{ helpers['mtou'](name) }}> div({{ unit }} divisor) {
    return VelocityUnit.combine(unit(), divisor.unit()).ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  @Override
  default Velocity<{{ helpers['mtou'](name) }}> divide({{ unit }} divisor) {
    return div(divisor);
  }
{% elif unit == name %}
  @Override
  default Dimensionless div({{ unit }} divisor) {
    return Value.of(baseUnitMagnitude() / divisor.baseUnitMagnitude());
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  @Override
  default Dimensionless divide({{ unit }} divisor) {
    return div(divisor);
  }
{% else %}
  @Override
  default Per<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}> div({{ unit }} divisor) {
    return (Per<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}>) Measure.super.div(divisor);
  }

  /**
  * {@inheritDoc}
  *
  * @deprecated use div instead. This was renamed for consistency with other languages like Kotlin
  */
  @Deprecated(since = "2025", forRemoval = true)
  @SuppressWarnings({"deprecation", "removal"})
  @Override
  default Per<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}> divide({{ unit }} divisor) {
    return div(divisor);
  }
{% endif -%}
{% endif -%}
{% endfor -%}
{{ config[name]['extra'] }}
}
