"""
        
        This file contains modified code from Tosi book - Matplotlib for Python Developers
        
"""

from matplotlib import rcParams
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

from qgis.PyQt.QtWidgets import *

from gst.mpl.utils import valid_intervals
from gst.plots.geology import *


# repeated from gst.core, Windows version does not see it
def string2dict(
        strng,
        valsep=",",
        kvsep="="
):
    """
    Creates a dictionary from a string.

    :param strng: string to convert into dictionary
    :param valsep: separator between key-value pairs
    :param kvsep: separator between key and value
    :return: a dictionary

    Examples:
      >>> d1 = string2dict("m=s, c=blue")
      >>> d1 == {'c': 'blue', 'm': 's'}
      True
    """

    vals = strng.split(valsep)
    kv_vals = map(lambda kvstr: kvstr.strip().split(kvsep), vals)

    return dict(kv_vals)


# repeated from gst.plots.geology, Windows version does not see it
def plot(data, force=''):
    """
    DEPRECATED. Use 'stereonet'.
    Plot geological data with matplotlib and mplstereonet
    """

    if not isinstance(data, list):
        data = [data]

    if force not in ('', 'upper', 'lower'):
        raise Exception("Force parameter is not valid")

    fig, ax = ms.subplots()

    for rec in data:

        if isinstance(rec, tuple):
            if isinstance(rec[-1], str):
                params = rec[-1]
                objs = rec[:-1]
            else:
                params = None
                objs = rec
        else:
            objs = [rec]
            params = None

        if params:
            kwargs = string2dict(params)
        else:
            kwargs = dict()

        for obj in objs:
            if isDirect(obj):
                plunge, bearing, symbol, color = params_gvect(obj, kwargs, force_emisphere=force)
                ax.line(
                    plunge,
                    bearing,
                    marker=symbol,
                    markerfacecolor=color,
                    markeredgecolor=color)
            elif isAxis(obj):
                plunge, bearing, symbol, color = params_gaxis(obj, kwargs, force_emisphere=force)
                ax.line(
                    plunge,
                    bearing,
                    marker=symbol,
                    markerfacecolor=color,
                    markeredgecolor=color)
            elif isPlane(obj):
                strike, dip, linestyle, color = params_gplane(obj, kwargs, force_emisphere=force)
                ax.plane(
                    strike,
                    dip,
                    linestyle=linestyle,
                    color=color)

    ax.grid()

    return fig, ax


class MplCanvas(FigureCanvas):
    """
    Class to represent the FigureCanvas widget.
    """

    def __init__(self, plot_type, data_plot, set_rc_params=True):

        if set_rc_params:
            self.set_rcParams()

        if plot_type == "Stereonet":
            self.fig, self.ax = plot(data_plot)
        else:
            self.fig = Figure()
            FigureCanvas.__init__(self, self.fig)

        super().__init__(self.fig)

    def set_rcParams(self):

        rcParams["font.size"] = 9.0
        rcParams["xtick.direction"] = 'out'
        rcParams["ytick.direction"] = 'out'

        rcParams["figure.subplot.left"] = 0.1
        rcParams["figure.subplot.right"] = 0.96
        rcParams["figure.subplot.bottom"] = 0.06
        rcParams["figure.subplot.top"] = 0.96
        rcParams["figure.subplot.wspace"] = 0.1
        rcParams["figure.subplot.hspace"] = 0.1

        rcParams["figure.facecolor"] = 'white'

# from: http://stackoverflow.com/questions/12695678/how-to-modify-the-navigation-toolbar-easily-in-a-matplotlib-figure-window

class NavigatioToolbarModif(NavigationToolbar):

    toolitems = [t for t in NavigationToolbar.toolitems if
                 t[0] in ('Home', 'Pan', 'Zoom')]


class MplWidget(QWidget):

    def __init__(self, window_title, type, data, set_rc_params=True):

        super().__init__()

        self.setWindowTitle(window_title)

        # set the canvas and the navigation toolbar
        self.canvas = MplCanvas(type, data, set_rc_params=set_rc_params)

        # create a vertical box layout
        self.vbl = QVBoxLayout()

        self.vbl.addWidget(self.canvas)

        self.canvas.adjustSize()

        # set the layout to the vertical box
        self.setLayout(self.vbl)


def plot_line(axes, x_list, y_list, linecolor, name="", linewidth=1):

    line, = axes.plot(x_list, y_list, '-', color=linecolor, linewidth=linewidth)

    if name is not None and name != "":
        axes.annotate(name, xy=(x_list[0], y_list[0]), xycoords='data',
                      xytext=(-40, 25), textcoords='offset points',
                      size=8,
                      arrowprops=dict(arrowstyle="fancy",
                                      fc="0.6", ec="none",
                                      patchB=line,
                                      connectionstyle="angle3,angleA=0,angleB=-90"))


def plot_filled_line(axes, x_list, y_list, plot_y_min, facecolor, alpha=0.1):

    y_values_array = np.array(y_list)
    x_values_array = np.array(x_list)
    for val_int in valid_intervals(y_values_array):
        axes.fill_between(x_values_array[val_int['start']: val_int['end'] + 1],
                          plot_y_min,
                          y_values_array[val_int['start']: val_int['end'] + 1],
                          facecolor=facecolor,
                          alpha=alpha)
