"""Helper to choose RGB sets of colors for figures
==================================================

Provides

.. autofunction:: make_colorchart

"""

from __future__ import division
from __future__ import print_function

# from builtins import str
from builtins import range
from colorsys import hsv_to_rgb

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# import subprocess
# import os
# import shlex


def make_colorchart(nb_colors=4, darkest_gray=0.03, lightest_gray=0.85):
    """Produce a pdf with color charts.

    The color charts help choosing RGB sets of colors which are
    distinguishable both in black and white and in color.

    Notes
    -----

    For many journals, it is very expensive to have figures with
    colors in the printed version. But nowadays, the printed version
    of a paper is not very important because most people get numerical
    papers on the web. So a good solution for many figures is to use
    colors that can be differentiated in black and white. This
    function produces pdf files with color charts helping researchers
    to choose colors adapted to this requirement.

    First author: Tobit CAUDWELL 2015 (tobit [AT] locta.fr).

    Parameters
    ----------

    nb_colors : int
        nb of desired final colors.

    darkest_gray : float
        darkest gray level (between 0 and 1)

    lightest_gray : float
        lightest gray level (between 0 and 1)

    """

    colors = []
    nbHue = 30  # nb of  hue values
    nbSV = 200  # nb of light/dark nuances

    # Creation of a table with colors sorted according to their hue
    for h in range(nbHue + 1):
        for sv in range(nbSV + 1):
            # variations along s
            RGBcolor = hsv_to_rgb(h / nbHue, sv / nbSV, 1)
            # multiply RGBcolor by 255
            RGBcolor = tuple(i * 255 for i in RGBcolor)

            luminance = (
                0.2126 * RGBcolor[0] + 0.7152 * RGBcolor[1] + 0.0722 * RGBcolor[2]
            )
            colors.append([h, RGBcolor, luminance])

            # variations along v
            RGBcolor = hsv_to_rgb(h / nbHue, 1, sv / nbSV)
            # multiply RGBcolor by 255
            RGBcolor = tuple(i * 255 for i in RGBcolor)

            luminance = (
                0.2126 * RGBcolor[0] + 0.7152 * RGBcolor[1] + 0.0722 * RGBcolor[2]
            )
            colors.append([h, RGBcolor, luminance])

    # round of luminance values
    lumRnd = 2.0
    nbGray = int(round(256.0 / lumRnd))
    # list of list where color are sorted
    color_table = [[0 for i in range(nbHue)] for j in range(nbGray)]
    for l in colors:
        h = l[0]
        luminance = l[2]
        # Position in color_table
        idx_lum = int(round(luminance / lumRnd)) - 1
        # First dim = luminance, 2nd dim = HUE
        color_table[idx_lum][h - 1] = l

    darkest_gray = darkest_gray * 255
    lightest_gray = lightest_gray * 255
    gray_wanted = [
        lightest_gray + i * (darkest_gray - lightest_gray) / (nb_colors - 1)
        for i in range(nb_colors)
    ]  # equivalent to linspace
    # index of desired list in color_table
    idx = [int(round(x / lumRnd)) for x in gray_wanted]

    # Selection of final colors
    final_colors = []
    for i in idx:
        colors = [x[1] for x in color_table[i]]
        final_colors.append(colors)

    #     # create the text of the latex file
    #     lines = [(
    #         r"""\documentclass{standalone}
    # \usepackage{tikz,calc}
    # \begin{document} \small
    # \begin{tikzpicture}""")]

    #     x = 0
    #     for line in reversed(final_colors):
    #         y = 0
    #         for col in line:
    #             coltxt = str([round(i/255, 2) for i in col])
    #             lines.append(
    #                 r'\definecolor{currentcolor}{rgb}{' +
    #                 coltxt[1:-1] + '}\n'
    #                 r'\node[fill=currentcolor, '
    #                 'minimum width=3cm, minimum height=1cm] at (' +
    #                 str(x) + "," + str(y) + r') {' + coltxt + '};')
    #             y -= 1
    #         x += 3.5

    #     x = 0
    #     for g in reversed(gray_wanted):
    #         coltxt = str([round(g/255, 2) for i in range(3)])
    #         lines.append(
    #             r'\definecolor{currentcolor}{rgb}{' +
    #             coltxt[1:-1] + '}\n'
    #             r'\node[fill=currentcolor, minimum width=3cm, '
    #             'minimum height=1cm] at (' +
    #             str(x) + r',2) {' + coltxt + '};')
    #         x += 3.5

    #         lines.append(r'\end{tikzpicture}' + '\n' + r'\end{document}')

    #     # write the .tex file
    #     file_name = "colorchart_using_" + str(nb_colors) + "_levels"
    #     with open(file_name + ".tex", "w") as f:
    #         f.write('\n'.join(lines))

    #     # PdfLaTeX compilation for PDF output
    #     proc = subprocess.Popen(shlex.split('pdflatex ' + file_name + ".tex"))
    #     proc.communicate()

    #     # delete .tex .log and .aux
    #     os.unlink(file_name + ".tex")
    #     os.unlink(file_name + ".log")
    #     os.unlink(file_name + ".aux")

    #     print('Document ' + file_name + '.pdf written.')

    width = 10
    height = 5
    step_x = 1.2 * width
    step_y = 1.2 * height

    fig = plt.figure(figsize=(5, 9))
    ax = fig.add_axes([0, 0, 1, 1])

    for i0, line in enumerate(reversed(final_colors)):
        for i1, color in enumerate(line):
            x = 2 + i0 * step_x
            y = 2 + i1 * step_y
            color = [round(c / 255, 2) for c in color]
            ax.add_patch(Rectangle((x, y), width, height, color=color))
            ax.text(x + 1, y + step_y / 4.0, str(color), fontsize=7)

    y += 1.5 * step_y

    for i0, g in enumerate(gray_wanted):
        color = [round(g / 255, 2)] * 3
        x = 2 + i0 * step_x
        ax.add_patch(Rectangle((x, y), width, height, color=color))
        ax.text(x + 1, y + step_y / 4.0, str(color), fontsize=7)

    ax.set_xlim([0, x + step_x])
    ax.set_ylim([0, y + step_y])
    ax.set_axis_off()

    return final_colors


if __name__ == "__main__":
    final_colors = make_colorchart(
        nb_colors=4, darkest_gray=0.5, lightest_gray=0.85
    )
    plt.show()
