// ----------------
// Breakpoint mixin
// Based upon https://github.com/innocentiv/media-breakpoint
// ----------------

@mixin _mb-reset-context(){
  $_mb-context: (
    min: null,
    max: null,
    resolution: null,
    orientation: all,
    device: all
  ) !global;
}
@include _mb-reset-context();

@mixin _mb-set-context($map){
  $_mb-context: map-merge($_mb-context, $map) !global;
}

@function mb-context($key){
  @return map-get($_mb-context , $key);
}

@function _mb-in($list, $item){
  @return index($list, $item) != null;
}

@function _mb-remove($list, $items){
  $result: ();
  @each $el in $list {
    @if not _mb-in($items, $el) {
      $result: append($result, $el)
    }
  }
  @return $result;
}

@function _mb-is-length($num) {
  @return type-of($num) == number and _mb-in(px em rem, unit($num));
}

@function _mb-get-length($num, $browser-context: 16px, $pixel-before: false) {
  $num: if(unit($num) == em, $num,
    if(unit($num) == rem, $num / 1rem * 1em,
      if(unit($num) == px, $num / $browser-context * 1em, null)));
  @return if($pixel-before, $num - 1em / ($browser-context / 1px), $num);
}

@function _mb-is-bp($bp){
  @return map_has_key($breakpoints, $bp) and _mb-is-length(map_get($breakpoints, $bp));
}

@function _mb-get-bp($range, $type){
  $bp: nth($range, if($type == min, 1, -1));
  @if _mb-is-length($bp) {
    @return _mb-get-length($bp);
  }
  @if not _mb-is-bp($bp) {
    @error "'#{$bp}' is not a valid breakpoint";
  }
  @if $type == min {
    @return _mb-get-length(map_get($breakpoints, $bp));
  }
  @if $type == max {
    $index: index(map_keys($breakpoints), $bp);
    @if $index < length($breakpoints) {
      @return _mb-get-length(nth(map_values($breakpoints), $index + 1), $pixel-before: true);
    }
    @return null;
  }
}

@mixin breakpoint($query){
  $range: _mb-remove($query, up down only height);
  $min: null;
  $max: null;
  $attr: if(_mb-in($query, height), height, width);

  @if not _mb-in($query, down) {
    $min: _mb-get-bp($range, min);
  }
  @if _mb-in($query, down) or _mb-in($query, only) or length($range) > 1 {
    $max: _mb-get-bp($range, max);
  }

  $mq: if($min, "(min-#{$attr}: #{$min})", "")
  if($min and $max, "and", "")
  if($max, "(max-#{$attr}: #{$max})", "");

  @include _mb-set-context((min: $min, max: $max));
  @media #{$mq} {
    @content;
  }
  @include _mb-reset-context();
}

@mixin media($queries) {
  $unit: null;
  $query: nth($queries, 1);

  @if type-of($query) == number and _mb-in(x dppx dpi, unit($query)){
    $unit: unit($query);
    $query: $query / ($query * 0 + 1);
  }

  $mq: null;
  @if _mb-in(landscape portrait, $query) {
    $mq: "(orientation: #{$query})";
    @include _mb-set-context((orientation: $query));
  } @else if _mb-in(print screen speech, $query){
    $mq: "only " + $query;
    @include _mb-set-context((device: $query));
  } @else if $unit == x or $unit == dppx {
    $mq: "(-webkit-min-device-pixel-ratio: #{$query}), (min-resolution: #{$query*96dpi})";
    @include _mb-set-context((resolution: #{$query+$unit}));
  } @else if $unit == dpi{
    $mq: "(-webkit-min-device-pixel-ratio: #{$query/96}), (min-resolution: #{$query*1dpi})";
    @include _mb-set-context((resolution: #{$query+$unit}));
  } @else {
    @error "'#{$query}' is not a valid query";
  }

  @media #{$mq}
  {
    @if length($queries) > 1 {
      @include media(_mb-remove($queries, $query)){
        @content;
      }
    } @else {
      @content;
    }
  }
  @include _mb-reset-context();
}
