"""
"""

from statsmodels.distributions.empirical_distribution import ECDF
import numpy as np
import matplotlib
matplotlib.use('Agg') # Agg, pgf, ps
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter
from cycler import cycler
import palettable

COLOR_MAP = palettable.colorbrewer.qualitative.Dark2_8.mpl_colors

PARAMS = {
    'figure.figsize': [10, 6],
    # 'figure.dpi': 300,
    'font.family': 'serif',
    'font.monospace': 'Courier Mono', # Ubuntu Mono
    'axes.labelsize': 28,
    'axes.titlesize': 28,
    'font.size': 28,
    'legend.fontsize': 28,
    'xtick.labelsize': 28,
    'ytick.labelsize': 28,
    'figure.titlesize': 28,
    'text.usetex': False,
    'lines.linewidth': 3,
    'axes.prop_cycle': cycler(color=COLOR_MAP)
    }

plt.rcParams.update(PARAMS)


def set_all_font_size(plt, size):
    to_update = {
        'axes.labelsize': size,
        'axes.titlesize': size,
        'font.size': size,
        'legend.fontsize': size,
        'xtick.labelsize': size,
        'ytick.labelsize': size,
        'figure.titlesize': size,
    }
    plt.rcParams.update(to_update)

# Functions
def _prepare_plot_para(
        i, labels, styles, widths, colors, markers, marker_sizes, **args):
    params = dict()
    params['label'] = labels[i]
    if styles is not None:
        params['linestyle'] = styles[i]
    if  widths is not None:
        params['linewidth'] = widths[i]
    if  colors is not None:
        params['color'] = colors[i]
    if  markers is not None:
        params['marker'] = markers[i]
    if  marker_sizes is not None:
        params['markersize'] = marker_sizes[i]
    for k, v in args.items():
        params[k] = v[i]
    return params

def plot_curves(list_x,
                list_y,
                labels,
                figure_path=None,
                x_label='x',
                y_label='y',
                xlim=None,
                ylim=None,
                xticks=None,
                yticks=None,
                styles=None,
                widths=None,
                colors=None,
                markers=None,
                marker_sizes=None,
                figsize=None,
                fontsize=None,
                is_grid='True',
                y_log=False,
                x_log=False,
                x_tick_label_format=None,
                y_tick_label_format=None,
                is_show=True,
                legend_loc=None, 
                show_legend=True, 
                **args
               ):
    """Plot a set of curves according to style settings
    Inputs

    """
    if figsize is not None:
        plt.figure(figsize=figsize)
    else:
        plt.figure()
    if fontsize is not None:
        set_all_font_size(plt, fontsize)

    axe = plt.subplot(1, 1, 1)

    if x_log:
        plt.xscale('log')
    if y_log:
        plt.yscale('log')

    for i, current_x in enumerate(list_x, start=0):
        x = current_x
        y = list_y[i]
        params = _prepare_plot_para(
            i, labels, styles, widths, colors, markers, marker_sizes, **args)
        axe.plot(x, y, **params)

    plt.xlabel(x_label)
    plt.ylabel(y_label)

    if is_grid:
        plt.grid()
    if legend_loc is None:
        legend_loc = 'best'
    if show_legend:
        plt.legend(loc=legend_loc, numpoints=1, frameon=False)
    if xlim is not None:
        axe.set_xlim(xlim)
    if ylim is not None:
        axe.set_ylim(ylim)
    if xticks is not None:
        plt.xticks(xticks[0], xticks[1])
    if yticks is not None:
        plt.yticks(yticks[0], yticks[1])
    if x_tick_label_format is not None:
        axe.xaxis.set_major_formatter(FormatStrFormatter(x_tick_label_format))
    if y_tick_label_format is not None:
        axe.yaxis.set_major_formatter(FormatStrFormatter(y_tick_label_format))
    if figure_path is not None:
        plt.savefig(figure_path, bbox_inches='tight')
        print('Saved figure to '+str(figure_path)+' .')
    if is_show:
        plt.show()

def boxplot(all_data,
            x_names=None,
            x_names_rotation=None, 
            x_names_positions=None,
            showfliers=True,
            figsize=None,
            figure_path=None,
            is_show=False,
            **args):
    if figsize is not None:
        plt.figure(figsize=figsize)
    else:
        plt.figure()
    axe = plt.subplot(1, 1, 1)
    axe.boxplot(all_data, showfliers=showfliers, **args)
    
    if x_names is not None:
        if x_names_positions is not None:
            assert len(x_names) == len(x_names_positions)
            axe.set_xticks(x_names_positions)
        axe.set_xticklabels(x_names, rotation=x_names_rotation)
    
    if figure_path is not None:
        plt.savefig(figure_path, bbox_inches='tight')
        print('Saved figure to '+str(figure_path)+' .')
    if is_show:
        plt.show()

def violinplot(all_data,
               x_names=None,
               x_names_rotation=None, 
               showmeans=False,
               showmedians=True,
               figsize=None,
               figure_path=None,
               is_show=False):
    if figsize is not None:
        plt.figure(figsize=figsize)
    else:
        plt.figure()
    axe = plt.subplot(1, 1, 1)
    axe.violinplot(all_data, showmeans=showmeans, showmedians=showmedians)
    
    if x_names is not None:
        axe.set_xticklabels(x_names, rotation=x_names_rotation)
    
    if figure_path is not None:
        plt.savefig(figure_path, bbox_inches='tight')
        print('Saved figure to '+str(figure_path)+' .')
    if is_show:
        plt.show()
    

def prepare_ECDF(sample, num=50):
    ecdf = ECDF(sample)
    x = np.linspace(min(sample), max(sample), num=num)
    y = ecdf(x)
    return x, y

def ECDF_to_EPDF(x, y):
    new_y = np.gradient(y, x[1]-x[0])
    return x, new_y
if __name__ == "__main__":
    pass
