@charset 'UTF-8';

////
/// Flavor SCSS Mixins Border
/// @group mixins-border
/// @author blackmirror1980
////

@import 'width';
@import 'style';
@import 'color';
@import 'radius';
@import 'image';

/// Border modes
///
/// @access private
/// @type list
$border-modes: array-concat((none), $css-default-modes);

/// Checks if something is border mode (none, initial, inherit)
///
/// @access public
/// @param {string} $bm - the border mode
/// @return {boolean} - true if is border mode
@function is-border-mode($bm) {
  @return is-defined($bm) and array-contains($border-modes, $bm);
}

/// Border mixin
///
/// @link https://www.w3schools.com/cssref/pr_border.asp W3Schools border docs
/// @example scss - Usage
///   .border-element {
///     @include border(1px null red);
///   }
///
/// @example css - Output
///   .border-element {
///     border: 1px solid red;
///   }
///
/// @example scss - Usage - with object parameter
///   .border-element {
///     @include border((
///       size: 2px,
///       color: black
///     );
///   }
///
/// @example css - Output - with object parameter
///   .border-element {
///     border: 2px solid black;
///   }
/// @requires {function} extend
/// @requires {function} get
/// @requires {function} is-defined
/// @requires {function} nth-value
/// @access public
/// @param {string | object | map} $options - the border options
/// @param {size} $options.size [0] - border-width
/// @param {string} $options.style [solid] - border-style
/// @param {color} $options.color [transparent] - border-color
/// @param {size} $options.radius [null] - border-radius
/// @param {string} $border-selector [border] - used for the border selector
/// @param {boolean} $shorthand [true] - if true, renders the shorthand form of border selector
/// @param {boolean} $important [false] - if true, will render the important rule
@mixin border($options, $border-selector: border, $shorthand: true, $important: false) {
  @if is-border-mode($options) {
    #{$border-selector}: $options;
  }
  @else {
    $settings: (size: 0, style: solid, color: transparent, radius: null);

    @if is-object($options) {
      $settings: extend($settings, $options);
    }
    @else {
      $size: nth-value($options, 1);

      @if is-defined($size) {
        $settings: extend($settings, (size: $size));
      }

      $style: nth-value($options, 2);

      @if is-defined($style) {
        $settings: extend($settings, (style: $style));
      }

      $color: nth-value($options, 3);

      @if is-defined($color) {
        $settings: extend($settings, (color: $color));
      }

      $radius: nth-value($options, 4);

      @if is-defined($radius) {
        $settings: extend($settings, (radius: $radius));
      }
    }

    $border: ();

    $border-width: get($settings, size);

    @if $shorthand == false {
      @include border-width($border-width, $border-selector, $important);
    }
    @else {
      @if is-size($border-width) {
        $border: append($border, $border-width);
      }
      @else {
        @warn '`border-width: #{$border-width}` is not a valid size';
      }
    }

    $border-style: get($settings, style);

    @if $shorthand == false {
      @include border-style($border-style, $border-selector, $important);
    }
    @else {
      @if is-border-style($border-style) {
        $border: append($border, $border-style);
      }
      @else {
        @warn '`border-style: #{$border-style}` is not a valid border-style value';
      }
    }

    $border-color: get($settings, color);

    @if $shorthand == false {
      @include border-color($border-color, $border-selector, $important);
    }
    @else {
      @if is-css-color($border-color) {
        $border: append($border, $border-color);
      }
      @else {
        @warn '`border-color: #{$border-color}` is not a valid css color';
      }
    }

    @if $shorthand == true {
      #{$border-selector}: $border important($important);
    }

    $border-radius: get($settings, radius);

    @if is-defined($border-radius) {
      @include border-radius($border-radius, false, $important);
    }
  }
}

/// Border top mixin
///
/// @example scss - Usage
///   .border-element {
///     @include border-top(1px null red);
///   }
///
/// @example css - Output
///   .border-element {
///     border-top: 1px solid red;
///   }
/// @see {mixin} border
/// @access public
/// @param {string | object | map} $options - the border options
/// @param {boolean} $important [false] - if true, will render the important rule
@mixin border-top($options, $important: false) {
  @include border($options, border-top, $important);
}

/// Border right mixin
///
/// @example scss - Usage
///   .border-element {
///     @include border-right(1px null red);
///   }
///
/// @example css - Output
///   .border-element {
///     border-right: 1px solid red;
///   }
/// @see {mixin} border
/// @access public
/// @param {string | object | map} $options - the border options
/// @param {boolean} $important [false] - if true, will render the important rule
@mixin border-right($options, $important: false) {
  @include border($options, border-right, $important);
}

/// Border bottom mixin
///
/// @example scss - Usage
///   .border-element {
///     @include border-bottom(1px null red);
///   }
///
/// @example css - Output
///   .border-element {
///     border-bottom: 1px solid red;
///   }
/// @see {mixin} border
/// @access public
/// @param {string | object | map} $options - the border options
/// @param {boolean} $important [false] - if true, will render the important rule
@mixin border-bottom($options, $important: false) {
  @include border($options, border-bottom, $important);
}

/// Border left mixin
///
/// @example scss - Usage
///   .border-element {
///     @include border-left(1px null red);
///   }
///
/// @example css - Output
///   .border-element {
///     border-left: 1px solid red;
///   }
/// @see {mixin} border
/// @access public
/// @param {string | object | map} $options - the border options
/// @param {boolean} $important [false] - if true, will render the important rule
@mixin border-left($options, $important: false) {
  @include border($options, border-left, $important);
}


