///
/// Calculate width
///
/// @access private
///
/// @param {String}        $key            - key of breakpoint
/// @param {Number}        $span           - span value of element
/// @param {Number|String} $context [null] - context value of element
/// @param {Number}        $deduct  [null] - subtract value out of final width
///
/// @return {Map} - map of target and context result
///
/// @group Internal Functions
///
@function flint-calc-width($key, $span, $context: null, $deduct: null) {
	$result: ();

	// Check to see if value has been cached
	@if map-has-key($flint-cached-values, "#{$key, $span, $context, $deduct}::width") and $context != "auto" {
		@return map-get($flint-cached-values, "#{$key, $span, $context, $deduct}::width");
	}

	@if $span == "container" {

		$result: flint-get-value("breakpoints", $key, "breakpoint");

	} @else if $context == "auto" {

		//
		// Check if instance maps are enabled
		//
		@if not flint-get-value("settings", "instance-maps") {
			@if not $flint-development-mode {
				@error "Instance maps are disabled. Automatic context is not available. Enable `instance-maps` in the config to continue.";
			} @else {
				@warn "Instance maps are disabled. Automatic context is not available. Enable `instance-maps` in the config to continue.";
			}
		}

		@if flint-has-family-instance($key) {
			$result: map-merge($result, ("target": ((flint-get-instance-value($key, "internal", "width") / flint-get-instance-value($key, "span") * $span) - if($deduct, $deduct, 0))));
			$result: map-merge($result, ("context": flint-get-instance-value($key, "internal", "width")));
		} @else {
			@if not $flint-development-mode {
				@error "You set context to `#{$context}`, but a parent instance could not be found for `#{nth(&, 1) + '::' + $key}`";
			} @else {
				@return false;
			}
		}

	} @else {

		$result: map-merge($result, ("target": ((flint-get-value("breakpoints", $key, "breakpoint") / flint-get-value("breakpoints", $key, "columns") * $span) - if($deduct, $deduct, 0))));

		@if $context {
			$result: map-merge($result, ("context": flint-get-value("breakpoints", $key, "breakpoint") / flint-get-value("breakpoints", $key, "columns") * $context));
		} @else {
			$result: map-merge($result, ("context": flint-get-value("breakpoints", $key, "breakpoint")));
		}

	}

	// Save result to cache
	@if $context != "auto" {
		$flint-cached-values: map-merge($flint-cached-values, ("#{$key, $span, $context, $deduct}::width": $result)) !global;
	}

	// Return result
	@return $result;
}
