# PamhyrPlot.py -- Pamhyr
# Copyright (C) 2023-2026  INRAE
#
# 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 <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import logging

import matplotlib.colors as mplcolors
from matplotlib import ticker

from tools import timestamp_to_old_pamhyr_date

from View.Tools.Plot.APlot import APlot
from View.Tools.Plot.PamhyrCanvas import MplCanvas
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar

logger = logging.getLogger()


class PamhyrPlot(APlot):
    color_axes = "black"
    color_axes_grid = "grey"
    color_axes_labels = "black"
    color_plot = "red"
    color_plot_highlight = "blue"
    color_plot_previous = "black"
    color_plot_current = "blue"
    color_plot_next = "purple"
    color_plot_river_bottom = "grey"
    color_plot_river_water = "blue"
    color_plot_river_water_zone = "skyblue"
    colors = list(mplcolors.TABLEAU_COLORS)
    linestyle = ['solid', 'dashed', 'dashdot', 'dotted']

    plot_default_kargs = {
        "lw": 1.,
        "markersize": 3,
        "marker": "+",
    }

    def __init__(self, data=None,
                 trad=None,     # Translate object
                 canvas=None,   # Use existing canvas
                 canvas_height=4, canvas_width=5,
                 canvas_dpi=100,
                 toolbar=None,
                 table=None,
                 parent=None):
        if canvas is None:
            canvas = MplCanvas(
                height=canvas_height, width=canvas_width,
                dpi=canvas_dpi
            )

        self._trad = trad
        self._canvas = canvas
        self._toolbar = toolbar
        self._table = table
        self._parent = parent

        self._init_event()
        self._init_default_value()

        super(PamhyrPlot, self).__init__(data=data)

    def _init_event(self):
        connector = {
            'pick_event': self.onpick,
            'button_press_event': self.onclick,
            'button_release_event': self.onrelease,
        }

        for event in connector:
            self.canvas.mpl_connect(
                event, connector[event]
            )

    def _init_default_value(self):
        self._label_x = "X"
        self._label_y = "Y"

        self._isometric_axis = True  #: Use isometric view

        self._auto_relim = True  #: Auto relim axes at plot creation
        self._autoscale = True  #: Auto scale at plot creation

        self._auto_relim_update = True  #: Auto relim axes at plot update
        self._autoscale_update = True  #: Auto scale at plot creation

        self._highlight_data = None  #: Data identifier to highlight
        self._highlight_data_update = False
        self._current_data = None  #: Current data identifier
        self._current_data_update = False
        self._rect_select = None

    @property
    def canvas(self):
        return self._canvas

    @property
    def toolbar(self):
        return self._toolbar

    @property
    def table(self):
        return self._table

    @property
    def label_x(self):
        """Plot X axes label"""
        return self._label_x

    @label_x.setter
    def label_x(self, name):
        self._label_x = name

    @property
    def label_y(self):
        """Plot Y axes label"""
        return self._label_x

    @label_y.setter
    def label_y(self, name):
        self._label_y = name

    @property
    def highlight(self):
        return self._highlight_data

    @highlight.setter
    def highlight(self, data):
        self._highlight_data = data
        self._highlight_data_update = True

    @property
    def current(self):
        return self._current_data

    @current.setter
    def current(self, data):
        self._current_data = data
        self._current_data_update = True

    def init_axes(self):
        self.canvas.axes.cla()
        self.canvas.axes.grid(
            color=self.color_axes_grid,
            linestyle='--',
            linewidth=0.5
        )

        self.init_axes_labels()
        self.init_axes_axis()

    def init_axes_labels(self):
        self.canvas.axes.set_xlabel(
            self._label_x,
            color=self.color_axes_labels,
            fontsize=10
        )

        self.canvas.axes.set_ylabel(
            self._label_y,
            color=self.color_axes_labels,
            fontsize=10
        )

    def init_axes_axis(self):
        if self._isometric_axis:
            self.canvas.axes.axis("equal")
        else:
            self.canvas.axes.axis("tight")

    def idle(self):
        if self._auto_relim:
            self.canvas.axes.relim()

        if self._autoscale:
            self.canvas.axes.autoscale_view(True, True, True)
            self.canvas.axes.autoscale()

        self.canvas.figure.canvas.draw_idle()

        self.toolbar_update()

    def update_idle(self):
        if self._auto_relim_update:
            self.canvas.axes.relim()

        if self._autoscale_update:
            self.canvas.axes.autoscale_view(True, True, True)
            self.canvas.axes.autoscale()

        self.canvas.figure.canvas.draw_idle()

        self.toolbar_update()

    def toolbar_update(self):
        if self._toolbar is not None:
            self._toolbar.update()

    def set_ticks_time_formater(self):
        self.canvas.axes.xaxis.set_major_formatter(
            lambda x, pos: timestamp_to_old_pamhyr_date(int(x))
        )

        self.canvas.axes.tick_params(
            labelsize=9,
            labelrotation=45
        )

    def enable_legend(self):
        self.canvas.axes.legend(
            fancybox=True,
            shadow=True,
            fontsize=8
        )

    def onpick(self, event):
        return

    def onclick(self, event):
        return

    def onrelease(self, event):
        return

    def rect_select_callback(self, eclick, erelease):
        'eclick and erelease are the press and release events'
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        logging.debug("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
        return
