///
/// This file regroups the odoo mixins. They are available in every asset bundle.
///

// ------------------------------------------------------------------
// Caret
// ------------------------------------------------------------------
@mixin utils-caret-boilerplate {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    vertical-align: middle;
    -moz-transform: scale(0.9999); // Smooth the caret on firefox
}

// ------------------------------------------------------------------
// Position absolute
// ------------------------------------------------------------------
@mixin o-position-absolute($top: auto, $right: auto, $bottom: auto, $left: auto) {
    position: absolute;
    top: $top;
    left: $left;
    bottom: $bottom;
    right: $right;
}

// ------------------------------------------------------------------
// Position sticky
// ------------------------------------------------------------------
@mixin o-position-sticky($top: auto, $right: auto, $bottom: auto, $left: auto) {
    position: -webkit-sticky;
    position: sticky;
    top: $top;
    left: $left;
    bottom: $bottom;
    right: $right;
}

// ------------------------------------------------------------------
// Text overflow
// ------------------------------------------------------------------
@mixin o-text-overflow($display: inline-block, $max-width: 100%) {
    display: $display;
    max-width: $max-width;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: top; // To update display context changed by overflow:hidden
}

// ------------------------------------------------------------------
// Hovering effects
// ------------------------------------------------------------------
@mixin o-hover-opacity($default-opacity: 0.5, $hover-opacity: 1) {
    opacity: $default-opacity;

    &:hover, &:focus, &.focus {
        opacity: $hover-opacity;
    }
}

//------------------------------------------------------------------------------
// Colors
//------------------------------------------------------------------------------

@function luma($color) {
    @return ((red($color) * .299) + (green($color) * .587) + (blue($color) * .114)) / 255 * 100%;
}
//
// Given two colors, returns the one which has the most constrast with another
// given color. Careful: if you want to find the text color which will suit the
// most on a given background color, you should use the 'color-yiq' function.
//
@function o-get-most-contrast($color, $c1, $c2, $background: #FFFFFF, $threshold: false, $cross-mix: true) {
    $background: if($background == null, #FFFFFF, $background);

    $real-color: mix(rgba($color, 1.0), $background, percentage(alpha($color)));
    $luma: luma($real-color);

    $cross-color: if($cross-mix, $real-color, $background);

    $real-c1: mix(rgba($c1, 1.0), $cross-color, percentage(alpha($c1)));
    $luma-c1: luma($real-c1);

    $real-c2: mix(rgba($c2, 1.0), $cross-color, percentage(alpha($c2)));
    $luma-c2: luma($real-c2);

    $-dark: if($luma-c1 <= $luma-c2, $c1, $c2);
    $-light: if($luma-c1 > $luma-c2, $c1, $c2);

    @if $threshold == false {
        // Automatic threshold: give a really small preference to light results
        // as bootstrap does by default (mainly by compatibility at the moment
        // this code is written)
        $threshold: ($luma-c1 + $luma-c2) * 0.515; // 150 / 145.63 * 0.5 would be the BS value
    }

    @return if($luma > $threshold, $-dark, $-light);
}

// Extend placeholder which adds a chess-like background below the color and
// image of an element to preview the transparency of that color and image.
// This is done thanks to both ::before and ::after elements so they must both
// be available.
%o-preview-alpha-background {
    position: relative;
    z-index: 0;

    &::before {
        content: "";
        @include o-position-absolute(0, 0, 0, 0);
        z-index: -1;
        background-image: url('/web/static/img/transparent.png');
        background-size: 10px auto;
        border-radius: inherit;
    }
    &::after {
        content: "";
        @include o-position-absolute(0, 0, 0, 0);
        z-index: -1;
        background: inherit; // Inherit all background properties
        border-radius: inherit;
    }
}

// ------------------------------------------------------------------
// Padding
// ------------------------------------------------------------------
@mixin o-webclient-padding($top: 0px, $right: $o-horizontal-padding, $bottom: 0px, $left: $o-horizontal-padding) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

// ------------------------------------------------------------------
// Caret
// ------------------------------------------------------------------
@mixin o-caret-down($caret-width: $caret-width, $caret-color: var(--o-input-border-color, currentColor)) {
    @include utils-caret-boilerplate;
    border-bottom: 0;
    border-left: $caret-width solid transparent;
    border-right: $caret-width solid transparent;
    border-top: $caret-width solid $caret-color;
}
@mixin o-caret-up($caret-width: $caret-width, $caret-color: var(--o-input-border-color, currentColor)) {
    @include utils-caret-boilerplate;
    border-bottom: $caret-width solid $caret-color;
    border-left: $caret-width solid transparent;
    border-right: $caret-width solid transparent;
    border-top: 0;
}
@mixin o-caret-left($caret-width: $caret-width, $caret-color: var(--o-input-border-color, currentColor)) {
    @include utils-caret-boilerplate;
    border-bottom: $caret-width solid transparent;
    border-left: 0;
    border-right: $caret-width solid $caret-color;
    border-top: $caret-width solid transparent;
}
@mixin o-caret-right($caret-width: $caret-width, $caret-color: var(--o-input-border-color, currentColor)) {
    @include utils-caret-boilerplate;
    border-bottom: $caret-width solid transparent;
    border-left: $caret-width solid $caret-color;
    border-right: 0;
    border-top: $caret-width solid transparent;
}

//-------------------------------------------------------------------
// Cursor
//-------------------------------------------------------------------

@mixin o-grab-cursor() {
    // Use a custom cursor for the open hand icon as "grab" is not properly
    // working on Chrome Linux (at least)
    cursor: url(/web/static/src/img/openhand.cur), grab;
}

// ------------------------------------------------------------------
// Hovering effects
// ------------------------------------------------------------------
@mixin o-hover-text-color($default-color: $body-color, $hover-color: $link-color) {
    color: $default-color;

    &:hover, &:focus, &.focus {
        color: $hover-color;
    }
}

// ------------------------------------------------------------------
// Mixin to define variations for btn-links and muted btn-links
// ------------------------------------------------------------------
@mixin o-btn-link-variant($color, $color-active) {
    text-transform: none;
    @include o-hover-text-color($default-color: $color, $hover-color: $color-active);

    &, &:hover, &:focus, &:active, &.active {
        border-color: transparent;
        background-color: transparent;
    }

    &.text-muted, .text-muted {
        @include o-hover-opacity;
        @include o-hover-text-color($default-color: $text-muted, $hover-color: $color-active);
    }
}

// Odoo defines a limited Noto font-family for a small variety of unicode
// characters that are not necessary defined in the user system or even defined
// but not properly readable. This function allows to add this font family in a
// given font list.
//
// @param {list} $font - a list of font names ending with the generic one.
// @param {integer} [$index] - the position where to add the support font, if
//        not given, it will be placed before the generic one.
@function o-add-unicode-support-font($font, $index: false) {
    @if $index == false {
        $index: length($font);
    }

    $-with-support-font: ();
    @for $i from 1 through length($font) {
        @if $i == $index {
            $-with-support-font: append($-with-support-font, 'Odoo Unicode Support Noto', $separator: comma);
        }
        $-with-support-font: append($-with-support-font, nth($font, $i), $separator: comma);
    }

    @return $-with-support-font;
}

// Function to remove all null values of a map
@function o-map-omit($map) {
    $-map: ();
    @each $key, $value in $map {
        @if $value != null {
            $-map: map-merge($-map, (
                $key: $value,
            ));
        }
    }
    @return $-map;
}

// Function to swap two values in a list
@function o-swap($list, $i, $j) {
    $tmp: nth($list, $i);
    $list: set-nth($list, $i, nth($list, $j));
    @return set-nth($list, $j, $tmp);
}

// Function to get an element of a list with a default value in case the index
// is out-of-bounds; also return that value if the retrieved value is null.
@function o-safe-nth($list, $index, $default: null) {
    $value: if($index > 0 and $index <= length($list), nth($list, $index), null);
    @return if($value != null, $value, $default);
}

// Function to get an element of a map with a default value in case the key
// does not exist; also return that value if the retrieved value is null.
@function o-safe-get($map, $key, $default: null) {
    $value: map-get($map, $key);
    @return if($value != null, $value, $default);
}

// ------- Kanban grouped mixins -------
@mixin o-kanban-icon($base-opacity: 0.5) {
    display: block;
    text-align: center;
    color: $o-main-text-color;
    font-size: $font-size-sm;
    cursor: pointer;
    @include o-hover-opacity($base-opacity);
}
@mixin o-kanban-tag-color {
    @for $size from 1 through length($o-colors) {
        // Note: the first color is supposed to be invisible if there is a color
        // field but it is used as a default color when there is no color field
        &.o_tag_color_#{$size - 1} span {
            background-color: nth($o-colors, $size);
        }
    }
}
@mixin o-kanban-record-color {
    @for $size from 2 through length($o-colors) {
        // Note: the first color is not defined as it is the 'no color' for kanban
        .oe_kanban_color_#{$size - 1} {
            border-left-color: nth($o-colors, $size);
            &:after {
                background-color: nth($o-colors, $size);
                outline: 1px solid nth($o-colors, $size);
            }
        }
    }
}
@mixin o-kanban-slim-col {
    position: relative;
    flex: 0 0 auto;
    margin: 0;
    padding: 0 floor($o-kanban-group-padding * 0.7);
    cursor: pointer;
}
@mixin o-kanban-header-title {
    display: flex;
    align-items: center;
    height: $o-kanban-header-title-height;
    line-height: 2.2;
    color: $headings-color;
}
@mixin o-kanban-v-title {
    @include o-position-absolute($o-kanban-inside-vgutter * 2, $left: floor(-$o-kanban-inside-vgutter * 1.2));
    transform-origin: left bottom 0;
    transform: rotate(90deg);
    overflow: visible;
    white-space: nowrap;
    font-size: 15px;
}

// ------- Kanban records mixins -------
@mixin o-kanban-record-title($font-size) {
    color: $headings-color;
    font-size: $font-size;
    font-weight: 500;
    margin-bottom: 0;
    margin-top: 0;
}
@mixin o-kanban-dropdown($padding-base: $o-kanban-inside-vgutter) {
    margin: -1px -1px 1px;
    padding: $padding-base/2 $padding-base;
    border: 1px solid transparent;
    border-bottom: none;
    vertical-align: top;
    @include o-hover-text-color($body-color, $headings-color);

    &:focus, &:active, &:focus:active {
        outline: none;
        box-shadow: none;
    }
}
@mixin o-kanban-dropdown-open {
    position: relative;
    background: white;
    border-color: $border-color;
    z-index: $zindex-dropdown + 1;
}
@mixin o-kanban-dropdown-menu {
    @include o-position-absolute($right: -1px);
    margin-top: -2px;
    border-color: $border-color;
    border-top-right-radius: 0;
}
@mixin o-kanban-colorpicker {
    max-width: 150px;
    padding: 3px ($o-dropdown-hpadding - $o-kanban-inner-hmargin) 3px $o-dropdown-hpadding;

    > li {
        display: inline-block;
        margin: $o-kanban-inner-hmargin $o-kanban-inner-hmargin 0 0;
        border: 1px solid white;
        box-shadow: 0 0 0 1px gray('300');

        > a {
            display: block;

            &::after {
                content: "";
                display: block;
                width: 20px;
                height: 15px;
            }
        }

        // No Color
        &:first-child > a {
            position: relative;
            &::before {
                content: "";
                @include o-position-absolute(-2px, $left: 10px);
                display: block;
                width: 1px;
                height: 20px;
                transform: rotate(45deg);
                background-color: red;
            }
            &::after {
                background-color: white;
            }
        }
    }
}

// Emulate dropdown links
@mixin o-kanban-dashboard-dropdown-link($link-padding-gap: $o-dropdown-hpadding) {
    padding: 0;

    > a {
        margin: auto auto auto (-$link-padding-gap);
        padding: 3px $link-padding-gap;
        color: $dropdown-link-color;
        display: block;

        &:hover {
            background-color: $dropdown-link-hover-bg;
            color: $dropdown-link-hover-color;
        }
    }

    &:last-child {
        margin-bottom: 5px;
    }
}

// No content helper
@mixin o-nocontent-empty {
    pointer-events: auto;
    max-width: 650px;
    margin: auto;
    padding: 15px;
    z-index: 1000;
    text-align: center;
    color: $o-tooltip-text-color;
    font-size: 115%;

    > p:first-of-type {
        margin-top: 0;
        color: $o-tooltip-title-text-color;
        font-weight: bold;
        font-size: 125%;
    }

    a {
        cursor: pointer;
    }
}

%o-nocontent-init-image {
    content: "";
    display: block;
    margin: auto;
    background-size: cover;
}

%o-nocontent-empty-document {
    @extend %o-nocontent-init-image;
    @include size(120px, 80px);
    margin-top: 30px;
    margin-bottom: 30px;
    background: transparent url(/web/static/img/empty_folder.svg) no-repeat center;
}

// ----------------------------------------------------------------------------
// CSS Variables
// ----------------------------------------------------------------------------

// Print a document property the right way (depending on the type of the
// printed variable).
@mixin print-variable($key, $value) {
    @if $value != null {
        $-type: type-of($value);
        @if $-type == 'string' {
            --#{$key}: '#{$value}';
        } @else if $-type == 'list' {
            --#{$key}: #{inspect($value)};
        } @else {
            --#{$key}: #{$value};
        }
    }
}
