/**
* Copyright (C) 2019 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.unitConverter.unit;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.unitConverter.math.DecimalComparison;
/**
* A prefix that can be applied to a {@code LinearUnit} to multiply it by some value
*
* @author Adrien Hopkins
* @since 2019-10-16
*/
public final class UnitPrefix {
/**
* Gets a {@code UnitPrefix} from a multiplier
*
* @param multiplier
* multiplier of prefix
* @return prefix
* @since 2019-10-16
*/
public static UnitPrefix valueOf(final double multiplier) {
return new UnitPrefix(multiplier, NameSymbol.EMPTY);
}
/**
* Gets a {@code UnitPrefix} from a multiplier and a name
*
* @param multiplier
* multiplier of prefix
* @param ns
* name(s) and symbol of prefix
* @return prefix
* @since 2019-10-16
* @throws NullPointerException
* if ns is null
*/
public static UnitPrefix valueOf(final double multiplier, final NameSymbol ns) {
return new UnitPrefix(multiplier, Objects.requireNonNull(ns, "ns must not be null."));
}
/**
* This prefix's primary name
*/
private final Optional primaryName;
/**
* This prefix's symbol
*/
private final Optional symbol;
/**
* Other names and symbols used by this prefix
*/
private final Set otherNames;
/**
* The number that this prefix multiplies units by
*
* @since 2019-10-16
*/
private final double multiplier;
/**
* Creates the {@code DefaultUnitPrefix}.
*
* @param multiplier
* @since 2019-01-14
* @since v0.2.0
*/
private UnitPrefix(final double multiplier, final NameSymbol ns) {
this.multiplier = multiplier;
this.primaryName = ns.getPrimaryName();
this.symbol = ns.getSymbol();
this.otherNames = ns.getOtherNames();
}
/**
* Divides this prefix by a scalar
*
* @param divisor
* number to divide by
* @return quotient of prefix and scalar
* @since 2019-10-16
*/
public UnitPrefix dividedBy(final double divisor) {
return valueOf(this.getMultiplier() / divisor);
}
/**
* Divides this prefix by {@code other}.
*
* @param other
* prefix to divide by
* @return quotient of prefixes
* @since 2019-04-13
* @since v0.2.0
*/
public UnitPrefix dividedBy(final UnitPrefix other) {
return valueOf(this.getMultiplier() / other.getMultiplier());
}
/**
* {@inheritDoc}
*
* Uses the prefix's multiplier to determine equality.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof UnitPrefix))
return false;
final UnitPrefix other = (UnitPrefix) obj;
return DecimalComparison.equals(this.getMultiplier(), other.getMultiplier());
}
/**
* @return prefix's multiplier
* @since 2019-11-26
*/
public double getMultiplier() {
return this.multiplier;
}
/**
* @return other names
* @since 2019-11-26
*/
public final Set getOtherNames() {
return this.otherNames;
}
/**
* @return primary name
* @since 2019-11-26
*/
public final Optional getPrimaryName() {
return this.primaryName;
}
/**
* @return symbol
* @since 2019-11-26
*/
public final Optional getSymbol() {
return this.symbol;
}
/**
* {@inheritDoc}
*
* Uses the prefix's multiplier to determine a hash code.
*/
@Override
public int hashCode() {
return DecimalComparison.hash(this.getMultiplier());
}
/**
* Multiplies this prefix by a scalar
*
* @param multiplicand
* number to multiply by
* @return product of prefix and scalar
* @since 2019-10-16
*/
public UnitPrefix times(final double multiplicand) {
return valueOf(this.getMultiplier() * multiplicand);
}
/**
* Multiplies this prefix by {@code other}.
*
* @param other
* prefix to multiply by
* @return product of prefixes
* @since 2019-04-13
* @since v0.2.0
*/
public UnitPrefix times(final UnitPrefix other) {
return valueOf(this.getMultiplier() * other.getMultiplier());
}
/**
* Raises this prefix to an exponent.
*
* @param exponent
* exponent to raise to
* @return result of exponentiation.
* @since 2019-04-13
* @since v0.2.0
*/
public UnitPrefix toExponent(final double exponent) {
return valueOf(Math.pow(this.getMultiplier(), exponent));
}
/**
* @return a string describing the prefix and its multiplier
*/
@Override
public String toString() {
if (this.primaryName.isPresent())
return String.format("%s (\u00D7 %s)", this.primaryName.get(), this.multiplier);
else if (this.symbol.isPresent())
return String.format("%s (\u00D7 %s)", this.symbol.get(), this.multiplier);
else
return String.format("Unit Prefix (\u00D7 %s)", this.multiplier);
}
/**
* @param ns
* name(s) and symbol to use
* @return copy of this prefix with provided name(s) and symbol
* @since 2019-11-26
* @throws NullPointerException
* if ns is null
*/
public UnitPrefix withName(final NameSymbol ns) {
return valueOf(this.multiplier, ns);
}
}