import hashlib
import os
import threading

from GChartWrapper import VerticalBarGroup
from GChartWrapper import Line
from GChartWrapper import constants

from config import cfg_dict


COLORS = ["1569C7", "81D8D0", "307D7E", "5CB3FF", "0040FF", "81DAF5"]
constants.MARKERS += 'E'  # append E marker to available markers


def save_image(chart, img_path):
    t = threading.Thread(target=chart.save, kwargs={'fname': img_path})
    t.daemon = True
    t.start()


def render_vertical_bar(title, legend, dataset, width=700, height=400,
                        scale_x=None, scale_y=None, label_x=None,
                        label_y=None, lines=()):
    """
    Renders vertical bar group chart

    :param legend - list of legend values.
        Example: ['bar1', 'bar2', 'bar3']
    :param dataset - list of values for each type (value, deviation)
        Example:
            [
                [(10,1), (11, 2), (10,1)], # bar1 values
                [(30,(29,33)),(35,(33,36)), (30,(29,33))], # bar2 values
                [(20,(19,21)),(20,(13, 24)), (20,(19,21))] # bar 3 values
            ]
    :param width - width of chart
    :param height - height of chart
    :param scale_x - x ace scale
    :param scale_y - y ace scale

    :returns url to chart

    dataset example:
    {
        'relese_1': {
            'randr': (1, 0.1),
            'randwr': (2, 0.2)
        }
        'release_2': {
            'randr': (3, 0.3),
            'randwr': (4, 0.4)
        }
    }
    """

    bar = VerticalBarGroup([], encoding='text')
    bar.title(title)

    values = []
    deviations = []

    for d in dataset:
        val, dev = zip(*d)

        display_dev = []
        for i in range(len(val)):
            display_dev.append((val[i]-dev[i], val[i]+dev[i]))
        values.append(val)
        # deviations.extend(zip(*dev))
        deviations.extend(zip(*display_dev))

    # bar.dataset(values + deviations, series=len(values))
    bar.dataset(values + deviations + [l[0] for l in lines],
                series=len(values))
    bar.axes.type('xyy')
    bar.axes.label(2, None, label_x)
    if scale_x:
        bar.axes.label(0, *scale_x)

    max_value = (max([max(l) for l in values + deviations + [lines[1][0]]]))
    bar.axes.range(1, 0, max_value)
    bar.axes.style(1, 'N*s*')
    bar.axes.style(2, '000000', '13')

    bar.scale(*[0, max_value] * len(values + deviations))

    bar.bar('r', '.1', '1')
    for i in range(1):
        bar.marker('E', '000000', '%s:%s' % ((len(values) + i*2), i),
                   '', '1:10')
    bar.color(*COLORS)
    bar.size(width, height)

    axes_type = "xyy"

    scale = [0, max_value] * len(values + deviations)
    if lines:
        line_n = 0
        for data, label, axe, leg in lines:
            bar.marker('D', COLORS[len(values) + line_n],
                       (len(values + deviations)) + line_n, 0, 3)
            max_val_l = max(data)
            if axe:
                bar.axes.type(axes_type + axe)
                bar.axes.range(len(axes_type), 0, max_val_l)
                bar.axes.style(len(axes_type), 'N*s*')
                bar.axes.label(len(axes_type) + 1, None, label)
                bar.axes.style(len(axes_type) + 1, '000000', '13')
                axes_type += axe
                line_n += 1
            legend.append(leg)
            scale += [0, max_val_l]

    bar.legend(*legend)
    bar.scale(*scale)
    img_name = hashlib.md5(str(bar)).hexdigest() + ".png"
    img_path = os.path.join(cfg_dict['charts_img_path'], img_name)
    if not os.path.exists(img_path):
        save_image(bar, img_path)
        return str(bar)
    return img_path


def render_lines(title, legend, dataset, scale_x, width=700, height=400):
    line = Line([], encoding="text")
    line.title(title)
    line.dataset(dataset)

    line.axes('xy')
    max_value = (max([max(l) for l in dataset]))
    line.axes.range(1, 0, max_value)
    line.scale(0, max_value)
    line.axes.label(0, *scale_x)
    line.legend(*legend)
    line.color(*COLORS[:len(legend)])
    line.size(width, height)

    img_name = hashlib.md5(str(line)).hexdigest() + ".png"
    img_path = os.path.join(cfg_dict['charts_img_path'], img_name)
    if not os.path.exists(img_path):
        save_image(line, img_path)
        return str(line)
    return img_path
