# -*- coding: utf-8 -*-
#
# Copyright © 2009 Pierre Raybaut
# Licensed under the terms of the MIT License
# see the mpl licenses directory for a copy of the license

"""Module that provides a GUI-based editor for matplotlib's figure options"""

import os.path as osp

import matplotlib.backends.qt4_editor.formlayout as formlayout
from PyQt4.QtGui import QIcon

def get_icon(name):
    import matplotlib
    basedir = osp.join(matplotlib.rcParams['datapath'], 'images')
    return QIcon(osp.join(basedir, name))

LINESTYLES = {
              '-': 'solid "-"',
              '--': 'dashed "--"',
              '-.': 'dash_dot "-."',
              ':': 'dotted ":"',
              #'steps': 'Steps',
              'none': 'None',
              }

MARKERS = {
           'none': 'None',
           'o': 'circle "o"',
           '^': 'triangle_up "^"',
           'v': 'triangle_down "v"',
           '<': 'triangle_left "<"',
           '>': 'triangle_right ">"',
           's': 'square "s"',
           '+': 'plus "+"',
           'x': 'cross "x"',
           '*': 'star "*"',
           'D': 'diamond "D"',
           'd': 'thin_diamond "d"',
           '1': 'tripod_down "1"',
           '2': 'tripod_up "2"',
           '3': 'tripod_left "3"',
           '4': 'tripod_right "4"',
           'h': 'hexagon "h"',
           'H': 'rotated_hexagon "H"',
           'p': 'pentagon "p"',
           '|': 'vertical_line "|"',
           '_': 'horizontal_line "_"',
           '.': 'dot "."',
           ',': 'pixel ","',
           }

COLORS = {'b': '#0000ff', 'g': '#008000', 'r': '#ff0000', 'c': '#ff00ff',
          'm': '#ff00ff', 'y': '#ffff00', 'k': '#000000', 'w': '#ffffff'}

def col2hex(color):
    """Convert matplotlib color to hex"""
    return COLORS.get(color, color)

def figure_edit(axes, parent=None):
    """Edit matplotlib figure options"""
    sep = (None, None) # separator

    has_curve = len(axes.get_lines()) > 0
    has_legend = (axes.legend_ is not None)

    # Get / General
    xmin, xmax = axes.get_xlim()
    ymin, ymax = axes.get_ylim()
    general = [('Title', axes.get_title()),
               ('Legend', has_legend),
               sep,
               (None, "<b>X-Axis</b>"),
               ('Min', xmin), ('Max', xmax),
               ('Label', axes.get_xlabel()),
               ('Scale', [axes.get_xscale(), 'linear', 'log']),
               sep,
               (None, "<b>Y-Axis</b>"),
               ('Min', ymin), ('Max', ymax),
               ('Label', axes.get_ylabel()),
               ('Scale', [axes.get_yscale(), 'linear', 'log'])
               ]

    if has_curve:
        # Get / Curves
        linedict = {}
        for line in axes.get_lines():
            label = line.get_label()
            # if label == '_nolegend_':
            #    continue
            linedict[label] = line
        curves = []
        linestyles = sorted(LINESTYLES.items())
        markers = sorted(MARKERS.items(), key=lambda (k,v): (v,k))
        curvelabels = sorted(linedict.keys())
        for label in curvelabels:
            line = linedict[label]
            curvedata = [
                         ('Label', label),
                         ('Visible', line.get_visible()),
                         sep,
                         (None, '<b>Line</b>'),
                         ('Style', [line.get_linestyle()] + linestyles),
                         ('Width', line.get_linewidth()),
                         ('Color', col2hex(line.get_color())),
                         sep,
                         (None, '<b>Marker</b>'),
                         ('Style', [line.get_marker()] + markers),
                         ('Size', line.get_markersize()),
                         ('Facecolor', col2hex(line.get_markerfacecolor())),
                         ('Edgecolor', col2hex(line.get_markeredgecolor())),
                         ]
            curves.append([curvedata, label, ""])

    datalist = [(general, "Axes", "")]
    if has_curve:
        datalist.append((curves, "Curves", ""))
        
    def apply_callback(data):
        """This function will be called to apply changes"""
        if has_curve:
            general, curves = data
        else:
            general, = data
            
        # Set / General
        title, has_legend, xmin, xmax, xlabel, xscale, \
            ymin, ymax, ylabel, yscale = general
        axes.set_xscale(xscale)
        axes.set_yscale(yscale)
        axes.set_title(title)
        axes.set_xlim(xmin, xmax)
        axes.set_xlabel(xlabel)
        axes.set_ylim(ymin, ymax)
        axes.set_ylabel(ylabel)
        
        if has_curve:
            # Set / Curves
            has_label = False
            for index, curve in enumerate(curves):
                line = linedict[curvelabels[index]]
                label, visible, linestyle, linewidth, color, \
                    marker, markersize, markerfacecolor, markeredgecolor = curve
                if not label.startswith('_') : 
                    has_label = True
                line.set_label(label)
                line.set_visible(visible)
                line.set_linestyle(linestyle)
                line.set_linewidth(linewidth)
                line.set_color(color)
                if marker == 'none': marker='None'
                line.set_marker(marker)
                line.set_markersize(markersize)
                line.set_markerfacecolor(markerfacecolor)
                line.set_markeredgecolor(markeredgecolor)
            if has_legend and has_label : 
				axes.legend(loc=0)
            else: 
				axes.legend_=None
            
        # Redraw
        figure = axes.get_figure()
        figure.canvas.draw()
        
    data = formlayout.fedit(datalist, title="Figure options", parent=parent,
                            icon=get_icon('qt4_editor_options.svg'), apply=apply_callback)
    if data is not None:
        apply_callback(data)
    
