# Following Vim's dark/light naming convention.
COLOR_DARKBLACK=0
COLOR_DARKRED=1
COLOR_DARKGREEN=2
COLOR_DARKYELLOW=3
COLOR_DARKBLUE=4
COLOR_DARKMAGENTA=5
COLOR_DARKCYAN=6
COLOR_DARKWHITE=7
COLOR_LIGHTBLACK=8
COLOR_LIGHTRED=9
COLOR_LIGHTGREEN=10
COLOR_LIGHTYELLOW=11
COLOR_LIGHTBLUE=12
COLOR_LIGHTMAGENTA=13
COLOR_LIGHTCYAN=14
COLOR_LIGHTWHITE=15
# Default to light.
COLOR_BLACK="$COLORS_LIGHTBLACK"
COLOR_RED="$COLORS_LIGHTRED"
COLOR_GREEN="$COLORS_LIGHTGREEN"
COLOR_YELLOW="$COLORS_LIGHTYELLOW"
COLOR_BLUE="$COLORS_LIGHTBLUE"
COLOR_MAGENTA="$COLORS_LIGHTMAGENTA"
COLOR_CYAN="$COLORS_LIGHTCYAN"
COLOR_WHITE="$COLORS_LIGHTWHITE"

__color_enabled="$(command -v tput)"
__color_count="$([ "$__color_enabled" ] && tput colors || echo 0)"

__color_test_put()
{
  [ "$__color_enabled" ] || return 0
  for __color
  do
    if [ $__color_count -lt 16 ] && [ $__color -ge 8 ]
    then
      __color=$((__color - 8))
      tput bold
    fi
    tput setaf "$__color"
    printf '%s' '██'
    tput sgr0
  done
}

__color_test()
{
  __color_test_put 0
  __color_test_put $(seq 1 6)
  __color_test_put 7
  printf '\n'
  __color_test_put 8
  __color_test_put $(seq 9 14)
  __color_test_put 15
  printf '\n'
}

__color_test1()
{
  __color_test_put 0
  printf '\n'
  __color_test_put 8
  printf '\n'
  __color_test_put 7
  __color_test_put $(seq 1 6)
  printf '\n'
  __color_test_put 15
  __color_test_put $(seq 9 14)
  printf '\n'
}

__color_test2()
{
  __color_test_put 0
  printf '\n'
  __color_test_put 8
  __color_test_put $(seq 1 6)
  printf '\n'
  __color_test_put 7
  printf '\n'
  __color_test_put 15
  __color_test_put $(seq 9 14)
  printf '\n'
}

__color_format()
{
  for __color
  do
    # Same as `ceil(__color/0xff*1000)`.
    printf '%s\n' "$(((__color * 1000 + 0xfe) / 0xff))"
  done
}

# `terminfo` does not define capabilities for setting the default foreground
# and background colors, so if the terminal supports at least 16 colors we use
# OSC 10/11 directly and hope for the best. This causes `tmux` to explicitly
# render the background color, which causes issues with transparency. This also
# causes Vim's `:terminal` to interpret the escape character as an escape key
# press which puts readline in vi command mode. Therefore we only do this if
# we're a login shell.
__color_set_fg()
{
  [ -z "$TMUX" ] || return 0
  [ -z "$VIM"  ] || return 0
  # [ "$__color_count" -ge 16 ] || return 0
  # case "$0" in
  #   -*) break ;;
  #   *) return 0 ;;
  # esac
  printf '\33]10;rgb:%02x/%02x/%02x\33\\' "$@"
}
__color_set_bg()
{
  [ -z "$TMUX" ] || return 0
  [ -z "$VIM"  ] || return 0
  # [ "$__color_count" -ge 16 ] || return 0
  # case "$0" in
  #   -*) break ;;
  #   *) return 0 ;;
  # esac
  printf '\33]11;rgb:%02x/%02x/%02x\33\\' "$@"
}

__color_set()
{
  [ "$__color_enabled" ] || return 0
  __color=$((0))
  while read -r __color_r __color_g __color_b __color_comment
  do
    [ "$__color_r" ] || continue
    # Palette.
    tput initc "$((__color))" $(__color_format \
      "$__color_r" \
      "$__color_g" \
      "$__color_b"
    )
    # Background (color 0, to match the Linux console).
    if [ "$__color" -eq 0 ]
    then
      __color_set_bg \
        "$__color_r" \
        "$__color_g" \
        "$__color_b"
    fi
    # Foreground (color 7, to match the Linux console).
    if [ "$__color" -eq 7 ]
    then
      __color_set_fg \
        "$__color_r" \
        "$__color_g" \
        "$__color_b"
    fi
    __color=$((__color + 1))
  done
}

__color_set_uniform_hard_linear()
{
  # https://notes.rcrnstn.net/colors.md
  # hard-linear
  echo '
    0x00 0x00 0x00 Black
    0xa4 0x6a 0x6a Red
    0x4e 0x86 0x56 Green
    0x87 0x79 0x40 Yellow
    0x64 0x7a 0xa4 Blue
    0x9c 0x68 0x98 Magenta
    0x07 0x87 0x88 Cyan
    0x79 0x79 0x79 White
    0x3e 0x3e 0x3e Bright Black
    0xff 0xa6 0xa7 Bright Red
    0x7b 0xd1 0x88 Bright Green
    0xd3 0xbe 0x67 Bright Yellow
    0x9d 0xbf 0xff Bright Blue
    0xf3 0xa3 0xec Bright Magenta
    0x00 0xd3 0xd4 Bright Cyan
    0xbe 0xbe 0xbe Bright White
  ' | __color_set
}

__color_set_twisted1()
{
  echo '
    0x00 0x00 0x00 Black
    0x9a 0x6a 0x4b Red
    0x08 0x84 0x65 Green
    0x6d 0x7b 0x32 Yellow
    0x7d 0x6b 0xa4 Blue
    0xa4 0x5e 0x83 Magenta
    0x08 0x80 0x95 Cyan
    0x75 0x75 0x75 White
    0x3b 0x3b 0x3b BrightBlack
    0xee 0xa6 0x77 BrightRed
    0x09 0xce 0x9e BrightGreen
    0xab 0xbf 0x51 BrightYellow
    0xc3 0xa8 0xfd BrightBlue
    0xfe 0x94 0xcd BrightMagenta
    0x07 0xc7 0xe8 BrightCyan
    0xb6 0xb6 0xb6 BrightWhite
  ' | __color_set
}

__color_set_twisted2()
{
  echo '
    0x00 0x00 0x00 Black
    0xa4 0x5e 0x83 Red
    0x6d 0x7b 0x32 Green
    0x9a 0x6a 0x4b Yellow
    0x08 0x80 0x95 Blue
    0x7d 0x6b 0xa4 Magenta
    0x08 0x84 0x65 Cyan
    0x75 0x75 0x75 White
    0x3b 0x3b 0x3b BrightBlack
    0xfe 0x94 0xcd BrightRed
    0xab 0xbf 0x51 BrightGreen
    0xee 0xa6 0x77 BrightYellow
    0x07 0xc7 0xe8 BrightBlue
    0xc3 0xa8 0xfd BrightMagenta
    0x09 0xce 0x9e BrightCyan
    0xb6 0xb6 0xb6 BrightWhite
  ' | __color_set
}

__color_set_alacritty()
{
  # https://github.com/alacritty/alacritty/blob/master/extra/man/alacritty.5.scd#colors
  echo '
    0x0f 0x0f 0x0f Black
    0x71 0x2b 0x2b Red
    0x5f 0x6f 0x3a Green
    0xa1 0x7e 0x4d Yellow
    0x45 0x68 0x77 Blue
    0x70 0x4d 0x68 Magenta
    0x4d 0x77 0x70 Cyan
    0x8e 0x8e 0x8e White
    0x6b 0x6b 0x6b Bright Black
    0xc5 0x55 0x55 Bright Red
    0xaa 0xc4 0x74 Bright Green
    0xfe 0xca 0x88 Bright Yellow
    0x82 0xb8 0xc8 Bright Blue
    0xc2 0x8c 0xb8 Bright Magenta
    0x93 0xd3 0xc3 Bright Cyan
    0xf8 0xf8 0xf8 Bright White
  ' | __color_set
}

__color_set_uniform_hard_linear