// =============================================================================
// =ALEKSI - CSS-RULE
// =============================================================================
////
//// @group aleksi-general

@import "aleksi/lists/prepend";

// =css-value( $value[, $important, $func, $args... ])
// -----------------------------------------------------------------------------
/// Optionally appends the !important flag to a css-value. Can also run the
/// value through a function before if needed.
///
/// @param {any} $value - The value of the css rule to modify
/// @param {bool} $important - Whether to append the `!important` flag
/// @param {string} $func - The name of a function to run $value through
/// @param {arglist} $args... - Additional arguments for $func
///
/// @example scss - SCSS stylesheet
///   .foo {
///     color: css-value(aqua);
///     font-size: css-value(2em, true);
///     content: css-value('hello world', false, 'to-upper-case');
///   }
///
/// @example css - CSS output
///   .foo {
///     color: aqua;
///     font-size: 2em !important;
///     content: 'HELLO WORLD';
///   }
///
/// @access public
/// @since 0.1.0

@function css-value( $value, $important: false, $func: '__none__', $args...  )
{
  // allow omitting the $important argument
  @if type-of($important) == 'string'
  {
    $args: if($func != '__none__', $args, prepend($args, $fn), $args);
    $func: $important;
    $important: false;
  }

  // optionally apply a given funtion to modify the value
  @if $func != '__none__'
  {
      @if type-of($func) == 'string' {
        $func: get-function($func);
      }

      $call-args: prepend($args, $value);
      $value: call($func, $call-args...);
  }

  // don't append the '!important' flag to `null` because that will make SASS
  // output it in the final CSS, when `null` alone will be left out.
  @return if( $important and ($value != null), $value !important, $value );
}

// =css-rule( $property, $value[, $important, $func, $args... ])
// -----------------------------------------------------------------------------
/// Outputs a css rule dynamically. Optionally modifies the value with a
/// function and/or appending the '!important' flag. Delegates to the
/// 'css-value()' function.
///
/// @param {string} $name - The property of the css rule to output
/// @param {any} $value - The value of the css rule to output
/// @param {bool} $important - Whether to append the `!important` flag
/// @param {string} $func - The name of a function to run $value through
/// @param {arglist} $args... - Additional arguments for $func
///
/// @see {function} css-value
///
/// @example scss - SCSS stylesheet
///   .foo {
///     @include css-rule('color', aqua);
///     @include css-rule(font-size, 2em, true);
///     @include css-rule(content, 'hello world', false, 'to-upper-case');
///   }
///
/// @example css - CSS output
///   .foo {
///     color: aqua;
///     font-size: 2em !important;
///     content: 'HELLO WORLD';
///   }
///
/// @access public
/// @since 0.1.0

@mixin css-rule( $property, $value, $important: false, $func: null, $args... )
{
  #{$property}: css-value( $value, $important, $func, $args... );
}

// =css( $property, $value[, $important, $func, $args... ])
// -----------------------------------------------------------------------------
/// @alias css-rule
///
/// @access public
/// @since 0.1.0

@mixin css( $property, $value, $important: false, $func: null, $args... )
{
  @include css-rule($property, $value, $important, $func, $args...);
}
