#!/usr/bin/python3
# -*- coding: utf-8 -*-

import pyqtgraph as pg
from PyQt6.QtCore import QPointF

licence = {}
licence['en'] = """\
This file is part of the package PYACIDOBASIC,

pyacidobasic version %s:

a program to simulate acido-basic equilibria

    Copyright (C) 2010-2024 Georges Khaznadar <georgesk@debian.org>
    Copyright (C) 2013 Jd Bourlier <jd.bourlier@gmail.com>
    Copyright (C) 2024 philippe DALET <philippe.dalet@gmail.com>

This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see
<http://www.gnu.org/licenses/>.
"""

class DoublePlotWidget(pg.PlotWidget):
    def __init__(self, parent,
                 title="DoublePlotWidget",
                 axisLabels=('axis 1', 'axis2'),
                 colors=("black", '#ff0000'),
                 background="w",
                 legend=True,):
        """
        Le constructeur.
        @param title titre du widget qui apparaît centré en haut
        @param axisLabels labels pour les deux axes verticaux
        @param colors une paire de couleurs pour les labels
        @param background couleur pour le fond du graphique
        @param legend un booléen, vrai si onveut afficher des légendes
        pour les courbes
        """
        pg.PlotWidget.__init__(self, parent)
        self.setWindowTitle(title)
        self.setBackground(background)
        self.legende = legend
        if legend:
            self.legendes = self.addLegends()
        # an overlay is created for plots with right Y axis
        self.overlay = pg.ViewBox()
        self.overlayCurves = []
        self.plotItem.showAxis('right')

        self.plotItem.showGrid(x=True, y=True)
        self.plotItem.getAxis('right').setGrid(0)

        self.plotItem.scene().addItem(self.overlay)
        self.plotItem.getAxis('right').linkToView(self.overlay)
        self.overlay.setXLink(self.plotItem)
        self.plotItem.getAxis('right').setLabel(axisLabels[1], color=colors[1])
        self.plotItem.getAxis('left').setLabel(axisLabels[0], color=colors[0])
        # signal quand on change les dimensions
        self.plotItem.vb.sigResized.connect(self.updateViews)
        # uniformisation des deux couches
        self.graphicItems = [self.plotItem.graphicsItem(), self.overlay]
        # pas d'échelle auto
        self.plotItem.vb.disableAutoRange()
        self.overlay.disableAutoRange()
        # réticule
        self.reticule = (
            pg.InfiniteLine(   # verticale
                angle=90,
                movable=False,
                pen=(0, 0, 0, 120),
            ),
            pg.InfiniteLine(   # horizontale
                angle=0,
                movable=False,
                pen=(0, 0, 0, 120),
            ),
            )
        for r in self.reticule:
            self.plotItem.vb.addItem(r, ignoreBounds=True)
            r.hide()
        pg.SignalProxy(self.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
        self.scene().sigMouseMoved.connect(self.mouseMoved)
        self.label = pg.TextItem(text="Hello", color='k')
        self.plotItem.vb.addItem(self.label)
        self.label.hide()
        self.label.setPos(20, 0)  # Pourquoi c'est en bas à droite ??????
        return

    def mouseMoved(self, evt):
        pos = evt  # # selon l'exemple standard de pyqtgraph
        vb = self.plotItem.vb
        hotRect = vb.boundingRect().translated(vb.pos())
        if hotRect.contains(pos):
            mousePoint = vb.mapSceneToView(pos)
            if pos.x() < self.sceneBoundingRect().width()/2:  # pointeur ...
                dx = 20                                         # à gauche
            else:
                dx = -150                                       # à droite
            if pos.y() < self.sceneBoundingRect().height()/2:  # en haut
                dy = 4
            else:                                             # en bas
                dy = -20
            labelPoint = vb.mapSceneToView(pos+QPointF(dx, dy))
            xy = (mousePoint.x(), mousePoint.y())
            # à ce stade il faut plutôt 2 chiffres significatifs
            self.label.setText("%0.1e, %0.1e" % xy)
            self.label.setPos(labelPoint)
            self.label.show()
            for r, val in zip(self.reticule, xy):
                r.setValue(val)
                r.show()
        else:
            self.label.hide()
            for r in self.reticule:
                r.hide()
        return

    def clearAll(self):
        self.clear()
        self.overlay.clear()
        for ln in self.legendes:
            ln.items = []
            while ln.layout.count() > 0:
                ln.layout.itemAt(0).close()
                ln.layout.removeAt(0)

    def addLegends(self):
        """
        ajout de deux légendes, la légende ordinaire et une de plus
        @ return une liste des deux legendItems
        """
        result = [self.addLegend()]
        ln = pg.LegendItem((100, 60), offset=(550, 60))
        ln.setParentItem(self.plotItem.graphicsItem())
        result.append(ln)
        return result

    def updateViews(self):
        self.overlay.setGeometry(self.plotItem.vb.sceneBoundingRect())
        self.overlay.linkedViewChanged(self.plotItem.vb, self.overlay.XAxis)
        return

    def show(self):
        pg.PlotWidget.show(self)
        self.updateViews()
        return

    def plot(self, *args, **kw):
        """
        Crée une courbes
        @return un plotCurveItem
        """
        index = kw.get("index", 0)
        name = kw.get("name", "")
        kw["clickable"] = True
        curveItem = pg.PlotCurveItem(*args, **kw)
        self.graphicItems[index].addItem(curveItem)
        if index:
            self.legendes[index].addItem(curveItem, name)
        return curveItem

    def setGrid(self,
                titre=None,
                yLeftMax=None, yLeftTitre=None,
                yRightMax=None, yRightTitre=None,
                xMax=None, xTitre=None):
        """
        Refait une grille et renomme les axes; les mots-clés optionnels
        permetent de refaire les intervalles et les titres des axes gauche
        et droit.
        """
        if not titre:
            titre = "Unknown"
        self.setTitle(titre)
        if xTitre:
            self.setLabel("bottom", xTitre)
        if xMax:
            self.setXRange(0, xMax)
        if yLeftTitre:
            self.setLabel("left", yLeftTitre)
        if yLeftMax:
            self.setYRange(0, yLeftMax)
        if yRightTitre:
            self.setLabel("right", yRightTitre)
        if yRightMax:
            self.overlay.setYRange(0, yRightMax)
        return

if __name__ == '__main__':
    # # Start Qt event loop unless running in interactive mode or using pyside.
    import sys
    from pyqtgraph.Qt import QtCore, QtGui
    import numpy as np

    pg.mkQApp()
    dpw = DoublePlotWidget()
    dpw.show()
    dpw.plot(x=np.arange(6), y=[1, 2, 4, 8, 16, 32])
    dpw.plot(x=np.arange(6), y=[10, 20, 40, 80, 40, 20], index=1, pen="r")

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec()
