/// Returns a single list on the scale
///
/// @param {Number} $index - Number of the scale to return.
/// @param {String} $font [''] - The font to get the scale number for, as fonts may have different scales. Uses the default scale if not specified.
/// @returns {List} List of the requested scale value.
@function oTypographyGetScale($index: 0, $font: '') {
	$scale: map-get($_o-typography-font-scale-by-font, oFontsGetFontFamilyWithoutFallbacks($font));
	$scale: if(type-of($scale) == 'map', $scale, $_o-typography-font-scale);
	@return map-get($scale, $index);
}

/// Returns a maximum line width based on the given scale
///
/// @param {Number} $optimal-characters-per-line - number of the characters per line
/// @returns {String} maximum line width in ch
@function oTypographyMaxLineWidth($optimal-characters-per-line: 65) {
	// a ch unit represents the width of the glyph "0"
	// it's a wide glyph so we'll reduce the ch value by an arbitrary amount
	// to bring our characters per line closer to the requested number on average
	$magic-number: 0.75;
	@return $optimal-characters-per-line * $magic-number * 1ch;
}

/// Get font family for o-typography type i.e "sans", "serif", or "display".
/// Note: we do not recommend setting `font-family` this way. Instead use
/// mixins `oTypographySans`, `oTypographySerif`, `oTypographyDisplay` without
/// any arguments.
///
/// @param {String} $type - One of 'sans', 'serif', or 'display'.
/// @return {String} The font-family set for the given font style.
@function oTypographyGetFontFamily($type) {
	@if not index($_o-typography-types, $type) {
		@error 'Could not get the font-family for font of style "#{$type}", style must be one of "#{$_o-typography-types}".';
	}
	@if $type == 'sans' {
		@return #{$_o-typography-sans};
	}
	@if $type == 'serif' {
		@return #{$_o-typography-serif};
	}
	@if $type == 'display' {
		@return #{$_o-typography-display};
	}
}

/// Returns the font-size value from the scale passed in
/// modified by the font-adjust if present
///
/// @param {Number} $scale - number of the scale to return
/// @param {Number} $font-adjust - multiplier if used as a progressive font
/// @param {String} $font [''] - The font to get the font size for, as fonts may have different scales. Uses the default scale if not specified.
/// @returns {Number} size in px
@function _oTypographyFontSizeFromScale($scale, $font-adjust: 1, $font: '') {
	$settings: oTypographyGetScale($scale, $font);
	@return _oTypographyAddUnit(nth($settings, 1) * $font-adjust);
}

/// Returns the line-height value from the scale passed in or
/// the line-height setting if one is passed
///
/// @param {Number} $scale - number of the scale to return
/// @param {Number} $line-height - size to output if not false
/// @param {String} $font [''] - The font to get the line height for, as fonts may have different scales. Uses the default scale if not specified.
/// @returns {Number} size in px
@function _oTypographyLineHeightFromScale($scale, $line-height, $font: '') {
	$settings: oTypographyGetScale($scale, $font);

	@if $line-height {
		@return _oTypographyAdjustUnit($line-height);
	} @else {
		$line-height: nth($settings, 2);
		@return if($line-height, _oTypographyAddUnit($line-height), null);
	}
}

/// Changes a px value to a rem value if relative units are enabled.
/// Useful for user input such as custom line-heights, where a px value
/// should become a rem value but otherwise the value should remain unchanged.
/// @access private
/// @param {Number|String} $value - Any none numbers are returned as is (e.g. "unset")
@function _oTypographyAdjustUnit($value) {
	@if(type-of($value) != 'number') {
		@return $value;
	}

	@if ($o-typography-relative-units and unit($value) == 'px') {
		@return div(div($value, 1px), 16) * 1rem;
	}
	@return $value;
}

/// Adds a px unit to a unitless pixel value, or converts to a rem unit if relative units are enabled.
/// Useful as the public typographic scales are currently defined in px but unitless.
/// @access private
/// @param {Number} $value
@function _oTypographyAddUnit($value) {
	@if ($o-typography-relative-units) {
		@return div($value, 16) * 1rem;
	}
	@return $value * 1px;
}

/// Throw a warning if it hasn't been thrown before.
/// @return {Null}
@function _oTypographyWarnOnce($key, $message) {
	@if(not map-get($_o-typography-warnings, $key)) {
		@warn #{$message};
		$_o-typography-warnings: map-merge($_o-typography-warnings, (
			#{$key}: true
		)) !global;
	}
	@return null;
}
