/* ============================================================================
   @CORE -> MIXINS -> MEDIA QUERIES
   ========================================================================= */


/**
 * Setup media query mixins for the following Media features
 * (http://www.w3.org/TR/2012/REC-css3-mediaqueries-20120619/#media1):
 *
 * - Width
 * - Height
 * - Resolution
 *
 * The width and height mixins are for applying styles based on the width or
 * height of the viewport, this can either be a minimum width or height or a
 * maximum width or height, or a minimum width or height range or a maximum
 * width or height range. The defaults are "width" and "minimum". They accept
 * any integer or any of Scally's breakpoints defined here: Core -> Settings
 * -> Breakpoints. E.g.
 *
   @include respond-to(400) {
     .foo {background: red;}
   }
 *
 * Would compile to:
 *
   @media min-width(25em) {
    .foo {background: red;}
   }
 *
 * And for a range:
 *
   @include respond-range(500, 780) {
    .foo {background: red;}
   }
 *
 * Would compile to:
 *
   @media (min-width: 31.25em) and (max-width: 48.75em) {
    .foo {background: red;}
   }
 *
 * To apply a maximum width or height the "max" flag needs to be applied e.g.
 *
   @include respond-to(desk-large, max) {
     .foo {background: red;}
   }
 *
 * And for a range:
 *
   @include respond-range(500, 700, max) {
     .foo {background: red;}
   }
 *
 * And to target the height the `$axis` parameter needs to be set to "height"
 * e.g.
 *
   @include respond-to(780, $axis: height) {
     .foo {background: red;}
   }
 *
 * And for a range:
 *
   @include respond-range(500, 700, $axis: height) {
     .foo {background: red;}
   }
 *
 * Applying both maximum and height will look something like this:
 *
   @include respond-to(palm, max, $axis: height) {
     .foo {background: red;}
   }
 *
 * For a range it doesn't make sense to pass in the "max" flag as ranges will
 * always use a maximum width or height for the second parameter as ranges
 * always need to be minimum-maximum however if the second parameter is
 * omitted and the first parameter is a Scally breakpoint then the second
 * parameter will use the next breakpoint in the sequence. So if you pass in
 * the "lap" breakpoint for the first parameter and nothing else for the
 * second parameter it will be "lap-large" as "lap-large" comes after "lap".
 * E.g.
 *
   @include respond-range(lap, $axis: height) {
     .foo {background: red;}
   }
 *
 * Would compile to:
 *
   @media (min-height: 40.0625em) and (max-height: 75em) {
     .foo {background: red;}
   }
 *
 * Where `max-height: 75em` is the "lap-large" breakpoint.
 *
 * N.B. the width and height mixins accept unitless integers or integers with
 * `px` e.g.
 *
   @include respond-to(400) {
     .foo {background: red;}
   }

   @include respond-to(400px) {
     .foo {background: red;}
   }
 *
 * The resolution mixin is for applying styles to hi-dpi (retina) devices. It
 * uses a default resolution defined here: Core -> Settings -> Retina
 * Resolution or it will accept either a unitless device pixel ratio (dpr) e.g.
 *
   @include respond-retina(2) {
     .foo {background-size: 100px auto;}
   }
 *
 * Which will compile to a dpi unit using the calculation: "dpr * 96dpi"
 * meaning the above mixin will compile too:
 *
   @media (min-resolution: 192dpi) {
     .foo {background-size: 100px auto;}
   }
 *
 * Or it will accept a dpi unit e.g.
 *
   @media (min-resolution: 192dpi) {
     .foo {background-size: 100px auto;}
   }
 */


/**
 * Simple minimum and maximum width and height values.
 */

@mixin respond-to($value, $limit: "min", $axis: "width") {
  @media (#{$limit}-#{$axis}: to-em(strip-unit($value), 16)) {
    @content;
  }
}


/**
 * Ranges.
 */

@mixin respond-range($min-value, $max-value: 0, $axis: "width") {

  // If `min-value` is a named breakpoint and `max-value` is omitted use the
  // next named breakpoint after the `min-value` breakpoint.
  @if type-of($min-value) == "string" and $max-value == 0 {

    $breakpoint-values: map-keys($breakpoints);
    $breakpoint-index:  index($breakpoint-values, $min-value);

    @if type-of($breakpoint-index) == "number" {

      $next-breakpoint-index: $breakpoint-index + 1;

      @if $min-value == "lap" {
        $next-breakpoint-index: $breakpoint-index + 2;
      }

      @if $next-breakpoint-index <= length($breakpoint-values) {
        $max-value: nth($breakpoint-values, $next-breakpoint-index);
      }
      @else {
        @warn "No max-#{$axis} value specified and no available breakpoints to use as a substitute";
      }
    }
    @else {
      @warn "Breakpoint name '#{$min-value}' not recognised.";
    }
  }

  @media (min-#{$axis}: to-em(strip-unit($min-value), 16)) and (max-#{$axis}: to-em(strip-unit($max-value), 16)) {
    @content;
  }
}


/**
 * Retina.
 */

@mixin respond-retina($resolution: $retina-resolution) {
  $resolution: if(unitless($resolution), $resolution * 96dpi, $resolution);

  @media (min-resolution: $resolution) {
    @content;
  }
}