#!/usr/bin/python3

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

pyacidobasic version %s:

a program to simulate acido-basic equilibria

Copyright (C) 2010-2013 Georges Khaznadar <georgesk@ofset.org>
          (C) 2013 Jd Bourlier <jd.bourlier@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/>.
"""

import pyqtgraph as pg
from PyQt5.QtCore import QPointF



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()
        proxy = 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))
            index = int(mousePoint.x())
            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 l in self.legendes:
            l.items=[]
            while l.layout.count() > 0:
                l.layout.itemAt(0).close()
                l.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()]
        l=pg.LegendItem((100,60), offset=(550,60))
        l.setParentItem(self.plotItem.graphicsItem())
        result.append(l)
        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_()
