import pyqtgraph as pg
from pyqtgraph import Qt
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

from pyqtgraph.dockarea import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

from .DataExtractorLyse import DataExtractorManager
# import DataExtractorLyse
from .WidgetPlot import DataPlot
# import WidgetPlot

from PIL import ImageColor

color_palette_html = ['#1f77b4',
                      '#ff7f0e',
                      '#2ca02c',
                      '#d62728',
                      '#9467bd',
                      '#8c564b',
                      '#e377c2',
                      '#7f7f7f',
                      '#bcbd22',
                      '#17becf']

color_palette = [ImageColor.getcolor(color, "RGB") for color in color_palette_html]


class FakeColorPlot(DataPlot):
    def __init__(self, title, data_path=None, **kwargs):

        super().__init__(title, **kwargs)

        # set data extractor
        self.data_extractor_manager = DataExtractorManager(data_path)
        self.data_extractor_manager.add_data_extractor('data_img', 'array', data_path)
        self.data_extractor_manager.add_data_extractor('x', 'array', (data_path[0], 'x'))
        self.data_extractor_manager.add_data_extractor('y', 'array', (data_path[0], 'y'))
        self.data_extractor_manager.add_data_extractor('warning', 'single', (data_path[0], 'warning'))

        self.setMinimumHeight(550)
        self.setMinimumWidth(550)

        # Add imaging
        self.img = pg.ImageItem()
        self.aximg = self.plots.addPlot(title="")
        self.aximg.addItem(self.img)

        # Isocurve draplotsg
        self.iso = pg.IsocurveItem(level=1000, pen=color_palette[2])
        self.iso.setParentItem(self.img)
        self.iso.setZValue(5)

        # Contrast/color control
        self.hist = pg.HistogramLUTItem()
        self.hist.setImageItem(self.img)
        self.plots.addItem(self.hist)

        # Draggable line for setting isocurve level
        self.isoLine = pg.InfiniteLine(angle=0, movable=True, pen=color_palette[2])
        self.hist.vb.addItem(self.isoLine)
        self.hist.vb.setMouseEnabled(y=False)  # makes user interaction a little easier
        self.isoLine.setValue(1000)
        self.isoLine.setZValue(1000)  # bring iso line above contrast controls
        self.isoLine.sigDragged.connect(self.updateIsocurve)

        # Monkey-patch the image to use our custom hover function.
        # This is generally discouraged (you should subclass ImageItem instead),
        # but it works for a very simple use like this.
        self.img.hoverEvent = self.imageHoverEvent

        self.plots.nextRow()
        self.plots.nextColumn()
        self.img.translate(-0.5, -0.5)

        self.scalex = 1
        self.scaley = 1

        self.cx = 0
        self.cy = 0

        self.data_image = None

    def update(self, h5_path):

        data = self.data_extractor_manager.get_data(h5_path)
        data_img = data['data_img']
        x = data['x']
        y = data['y']
        if x is None:
            x = np.linspace(0, data_img.shape[0], data_img.shape[0])
        if y is None:
            y = np.linspace(0, data_img.shape[1], data_img.shape[1])
        warning = data['warning']

        # update plots
        self.img.setImage(data_img.T)
        self.iso.setData(data_img.T)

        self.data_img = data_img

        # set position and scale of image
        newscalex = x[1] - x[0]
        newscaley = y[1] - y[0]

        transx = (x[0] - (self.cx - 0.5 * self.scalex)) / newscalex - 0.5
        transy = (y[0] - (self.cy - 0.5 * self.scaley)) / newscaley - 0.5

        self.img.scale(newscalex / self.scalex, newscaley / self.scaley)
        self.img.translate(transx, transy)

        self.scalex = newscalex
        self.scaley = newscaley

        self.cx = x[0]
        self.cy = y[0]

        # update table and warning
        self.update_warning(warning)

    def updateIsocurve(self):
        self.iso.setLevel(self.isoLine.value())

    def imageHoverEvent(self, event):
        """Show the position, pixel, and value under the mouse cursor.
        """
        if event.isExit():
            self.aximg.setTitle("")
            return
        pos = event.pos()
        i, j = pos.y(), pos.x()
        i = int(np.clip(i, 0, self.data_img.shape[0] - 1))
        j = int(np.clip(j, 0, self.data_img.shape[1] - 1))
        val = self.data_img[i, j]
        ppos = self.img.mapToParent(pos)
        x, y = ppos.x(), ppos.y()
        self.aximg.setTitle("pos: (%0.1f, %0.1f) value: %g" % (x, y, val))