'''
sifraplot.py
This module provides easy access to selected colours from the Brewer
palettes, and functions for customising and improving plot aesthetics
'''

import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['legend.numpoints'] = 2
mpl.rcParams['xtick.direction'] = 'out'
mpl.rcParams['ytick.direction'] = 'out'
mpl.rcParams['font.family'] = 'Open Sans', 'sans-serif'
mpl.rcParams['text.usetex'] = True

import numpy as np
import brewer2mpl
import re

# ----------------------------------------------------------------------------

COLR_DARK2 = brewer2mpl.get_map('Dark2', 'Qualitative', 8).mpl_colors
COLR_SET1 = brewer2mpl.get_map('Set1', 'Qualitative', 9).mpl_colors
COLR_SET2 = brewer2mpl.get_map('Set2', 'Qualitative', 8).mpl_colors
COLR_SET3 = brewer2mpl.get_map('Set3', 'Qualitative', 12).mpl_colors
COLR_RDYLGN = brewer2mpl.get_map('RdYlGn', 'Diverging', 11).mpl_colors
COLR_PAIR = brewer2mpl.get_map('Paired', 'Qualitative', 12).mpl_colors
COLR_SPECTRAL = brewer2mpl.get_map('Spectral', 'Diverging', 11).mpl_colors
COLR_DS = [COLR_PAIR[9], COLR_PAIR[3], COLR_PAIR[1],
           COLR_PAIR[7], COLR_PAIR[5]]
COLR_MIX = COLR_SET1 + COLR_DARK2

# ----------------------------------------------------------------------------


def split_long_label(string, delims, max_chars_per_line=20):
    '''
    Splits long labels into smaller chunks for better print/display outcome
    '''
    delims = [' ', '_']
    pattern = r'\s*(%s)\s*' % ('|'.join((re.escape(d) for d in delims)))
    splt_str = [i for i in re.split(pattern, string) if i and i is not None]

    str_list = []
    lines = []
    for i, val in enumerate(splt_str):
        str_list.append(val)
        if len(''.join(str_list)) >= max_chars_per_line and \
           (i < len(splt_str) - 1):
            str_list.append('\n')
            lines.extend(str_list)
            str_list = []

    if str_list != []:
        lines.extend(str_list)
    lines = ''.join(lines)
    return lines

# ----------------------------------------------------------------------------


def calc_tick_pos(stepsize, ax_vals_list, ax_labels_list,
                  maxnumticks=11, plot_type='line'):
    '''
    Calculates appropriate tick positions based on
    given input parameters
    '''
    stepsize = stepsize
    numticks = int(round((max(ax_vals_list) - min(ax_vals_list)) / stepsize))

    while numticks > maxnumticks:
        stepsize = stepsize * 2.0
        numticks = int(round((max(ax_vals_list) - min(ax_vals_list)) /
                             stepsize))

    skip = int(len(ax_vals_list) / numticks)
    ndx_all = range(1, len(ax_vals_list) + 1, 1)

    if plot_type == 'box':
        tick_pos = ndx_all[0::skip]
        if max(tick_pos) != max(ndx_all):
            numticks += 1
            tick_pos = np.append(tick_pos, max(ndx_all))

        tick_val = np.zeros(len(tick_pos))
        i = 0
        for j in tick_pos:
            tick_val[i] = ax_labels_list[j - 1]
            i += 1

    elif plot_type == 'line':
        tick_pos = ax_vals_list[0::skip]
        if max(tick_pos) != max(ax_vals_list):
            numticks += 1
            tick_pos = np.append(tick_pos, max(ax_vals_list))
        tick_val = tick_pos

    else: