// brightness and hue offsets are based on the lightness and saturation of the color
// unless defined otherwise.
@function cs-brightness-offset($cs-brightness-offset) {
  @if $cs-brightness-offset == false {
    // find the difference between lightness
    @return lightness($cs-primary) - lightness(invert($cs-primary));
  }
  @else {
    @return $cs-brightness-offset;
  }
}

// Harmonized or Unaltered Color
@function clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount) {
  @if $cs-harmonize-mode != null {
    @return cs-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  } @else {
    @return $color;
  }
}

// Primary color
@function cs-primary($cs-primary:$cs-primary, $cs-scheme:$cs-scheme, $cs-hue-offset:$cs-hue-offset, $cs-brightness-offset:$cs-brightness-offset, $cs-harmonize-mode:$cs-harmonize-mode, $cs-harmonize-color:$cs-harmonize-color, $cs-harmonize-amount:$cs-harmonize-amount) {
  @return clean-or-harmonize($cs-primary, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
}

// Secondary color scheme
@function cs-secondary($cs-primary:$cs-primary, $cs-scheme:$cs-scheme, $cs-hue-offset:$cs-hue-offset, $cs-brightness-offset:$cs-brightness-offset, $cs-harmonize-mode:$cs-harmonize-mode, $cs-harmonize-color:$cs-harmonize-color, $cs-harmonize-amount:$cs-harmonize-amount) {
  $cs-brightness-offset: cs-brightness-offset($cs-brightness-offset);

  // mono
  @if $cs-scheme == mono {
    @if $cs-brightness-offset < 0 {
      $color: lighten($cs-primary, abs($cs-brightness-offset));
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: darken($cs-primary, abs($cs-brightness-offset));
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // complement
  @if $cs-scheme == complement {
    @if $cs-color-model == ryb {
      $color: ryb-complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // triad
  @if $cs-scheme == triad {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue(ryb-complement($cs-primary), $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue(complement($cs-primary), $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // tetrad
  @if $cs-scheme == tetrad {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue($cs-primary, $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue($cs-primary, $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // analogic
  @if $cs-scheme == analogic or $cs-scheme == accented-analogic {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue($cs-primary, $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue($cs-primary, $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }
}

// Tertiary color scheme
@function cs-tertiary($cs-primary:$cs-primary, $cs-scheme:$cs-scheme, $cs-hue-offset:$cs-hue-offset, $cs-brightness-offset:$cs-brightness-offset, $cs-harmonize-mode:$cs-harmonize-mode, $cs-harmonize-color:$cs-harmonize-color, $cs-harmonize-amount:$cs-harmonize-amount) {
  $cs-brightness-offset: cs-brightness-offset($cs-brightness-offset);

  // mono
  @if $cs-scheme == mono {
    $color: mix(cs-primary(), cs-secondary());
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // complement
  @if $cs-scheme == complement {
    $color: equalize($cs-primary);
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // triad
  @if $cs-scheme == triad {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue(ryb-complement($cs-primary), $cs-hue-offset * -1);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue(complement($cs-primary), $cs-hue-offset * -1);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // tetrad
  @if $cs-scheme == tetrad {
    @if $cs-color-model == ryb {
      $color: ryb-complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // analogic
  @if $cs-scheme == analogic or $cs-scheme == accented-analogic {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue($cs-primary, $cs-hue-offset * -1);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue($cs-primary, $cs-hue-offset * -1);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // accented-analogic
  @if $cs-scheme == accented-analogic {
    @if $cs-color-model == ryb {
      $color: ryb-complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }
}

// Quadrary color scheme
@function cs-quadrary($cs-primary:$cs-primary, $cs-scheme:$cs-scheme, $cs-hue-offset:$cs-hue-offset, $cs-brightness-offset:$cs-brightness-offset, $cs-harmonize-mode:$cs-harmonize-mode, $cs-harmonize-color:$cs-harmonize-color, $cs-harmonize-amount:$cs-harmonize-amount) {
  $cs-brightness-offset: cs-brightness-offset($cs-brightness-offset);

  // mono
  @if $cs-scheme == mono {
    $color: equalize($cs-primary);
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // complement
  @if $cs-scheme == complement {
    $color: equalize(ryb-complement($cs-primary));
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // triad
  @if $cs-scheme == triad {
    $color: equalize($cs-primary);
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // tetrad
  @if $cs-scheme == tetrad {
    @if $cs-color-model == ryb {
      $color: ryb-adjust-hue(ryb-complement($cs-primary), $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: adjust-hue(complement($cs-primary), $cs-hue-offset);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }

  // analogic
  @if $cs-scheme == analogic {
    $color: equalize($cs-primary);
    @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
  }

  // accented-analogic
  @if $cs-scheme == accented-analogic {
    @if $cs-color-model == ryb {
      $color: ryb-complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
    @else {
      $color: complement($cs-primary);
      @return clean-or-harmonize($color, $cs-harmonize-color, $cs-harmonize-mode, $cs-harmonize-amount);
    }
  }
}
