$uswds-base: 16px;                    // USWDS base
$formation-base: 10px;                // Formation base

$f2u-coeff: $formation-base / $uswds-base; // Formation  to USDWS conversion coeffient
$u2f-coeff: $uswds-base / $formation-base; // USDWS to Formation conversion coeffient


$unit-types: (
    "px": 1px,
    "cm": 1cm,
    "mm": 1mm,
    "%": 1%,
    "ch": 1ch,
    "in": 1in,
    "em": 1em,
    "rem": 1rem,
    "pt": 1pt,
    "pc": 1pc,
    "ex": 1ex,
    "vw": 1vw,
    "vh": 1vh,
    "vmin": 1vmin,
    "vmax": 1vmax,
    "deg": 1deg,
    "turn": 1turn,
    "rad": 1rad,
    "grad": 1grad,
    "s": 1s,
    "ms": 1ms,
    "Hz": 1Hz,
    "kHz": 1kHz,
    "dppx": 1dppx,
    "dpcm": 1dpcm,
    "dpi": 1dpi,
  );


@function split-value-unit($string) {
  // takes a string,  returns a map of
  // number: number || null
  // unit: a unit || or null
  // joint: the number+ its unit
  @if(type-of($string) == number){
      @return(
        number: if(map-has-key($unit-types, unit($string)),
            $string / map-get($unit-types, unit($string))
            ,$string),
        unit: unit($string),
        joint: $string
      )
  }
  @if(type-of($string) == color){
      @return(
        number: $string,
        unit: color,
        joint: $string
      )
  }
  @if(type-of($string) != string){
      @return(
        number: null,
        unit: null,
        joint: $string
      )
  }
  $length: str-length($string);
  $numeric-value: "";
  $unit: "";
  $digits: ( "0":0, "1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9);
  $sign : 1;
  $decimal: 1;
  $magnitude: 10;
  $past: false;
  @for $i from 1 through $length {
    $char: str-slice($string, $i, $i);
    @if($char == "-") {
      $sign :  -1;
    }
    @else if($char == "." and $past == false) {
      $decimal : 10;
      $magnitude : 1;
    }
    @else if( map-get($digits,$char) and $past == false){
      @if ($numeric-value == ""){
            $numeric-value : 0;
      }
      $numeric-value: ($numeric-value * $magnitude) +(map-get($digits,$char)/$decimal);
        @if ($decimal > 1){
            $decimal : $decimal * 10;
        }
    }
    @else {
        $unit: $unit + $char;
        $past: true;
    }
  }
  $numeric-result: if( $numeric-value == "" , null, $sign * $numeric-value);
  @return (
    number: $numeric-result,
    unit: unquote($unit),
    joint: if($numeric-result != null, #{$numeric-result} + unquote($unit), $string)
  );
}

@function str-split($string, $separator: " ") {
  $split-list: ();
  $index: str-index($string, $separator);

  @while $index != null {
    $item: str-slice($string, 1, $index - 1);
    $split-list: append($split-list, $item);
    $string: str-slice($string, $index + 1);
    $index: str-index($string, $separator);
  }

  @return append($split-list, $string);
}

@function scale-rem($value, $coeff: $f2u-coeff,  $separator: space) {
  // converts any singular SCSS value with rem units
  // to its scaled equivalent
  // otherwise returns the orginal value
  @if (type-of($value) == number and unit($value) == rem) {
    @return ($value * $coeff) ;
  }
  @if (type-of($value) == string ) {
    $inner-sep: if($separator == comma , ",", " ");
    $value-set: str-split($value, $inner-sep);
    $scaled-values: ();

    @each $val in $value-set{
        $val-parts : split-value-unit($val);
        @if (map-get($val-parts, unit) == rem) {
            $rem-number: str-slice($val, 0, -4);
            $scaled-rem: map-get($val-parts, number) * $coeff ;
            $scaled-values: append($scaled-values, $scaled-rem + rem);
        } @else {
            $scaled-values: append($scaled-values,
            map-get($val-parts, joint), $separator);
        }
    }
    @return  $scaled-values;
  }
  @else {
    @return $value;
  }
}

@function scale-rule($rule, $separator: space,  $coeff: $f2u-coeff   ) {
  // converts any plural SCSS value with rem units
  $scaled: ();
  @each $value in $rule {
    $scaled-value: scale-rem($value, $coeff, $separator);
    $scaled: append($scaled, $scaled-value, $separator);
  }
  @return $scaled;
}