# PlotXY.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 -*-

from tools import timer, trace
from View.Tools.PamhyrPlot import PamhyrPlot
from matplotlib import collections
import numpy as np

from PyQt5.QtCore import (
    QCoreApplication, Qt, QItemSelectionModel,
    QItemSelection, QItemSelectionRange,
)
from PyQt5.QtWidgets import QApplication, QTableView

try:
    import rasterio
    import rasterio.control
    import rasterio.crs
    import rasterio.sample
    import rasterio.vrt
    import rasterio._features

    from rasterio.io import MemoryFile
    _rasterio_loaded = True
except Exception as e:
    print(f"Module 'rasterio' is not available: {e}")
    _rasterio_loaded = False

_translate = QCoreApplication.translate


class PlotXY(PamhyrPlot):
    def __init__(self, canvas=None, trad=None, data=None, geotiff=None,
                 toolbar=None, table=None, parent=None):
        super(PlotXY, self).__init__(
            canvas=canvas,
            trad=trad,
            data=data,
            toolbar=toolbar,
            table=table,
            parent=parent
        )

        self._data = data
        self._geotiff = geotiff

        self.label_x = self._trad["x"]
        self.label_y = self._trad["y"]
        self.parent = parent

        self._plot_img = {}

        self._isometric_axis = True

        self._auto_relim_update = True
        self._autoscale_update = False

    @timer
    def draw(self):
        self.init_axes()

        if self._data is None:
            self.idle()
            return

        if len(self._data) < 1:
            self.idle()
            return

        self.line_lr = []
        for data in self._data:
            if data.reach.number_profiles != 0:
                self.draw_xy(data.reach)
                self.draw_lr(data.reach)

        if self._geotiff is not None:
            self.draw_geotiff(self._geotiff.files)

        self.idle()

        return

    def draw_xy(self, reach):
        line_xy = []
        for xy in zip(reach.get_x(), reach.get_y()):
            line_xy.append(np.column_stack(xy))

        line_xy_collection = collections.LineCollection(
            line_xy,
            colors=self.color_plot_river_bottom
        )
        self.canvas.axes.add_collection(line_xy_collection)

    def draw_lr(self, reach):
        lx = []
        ly = []
        rx = []
        ry = []

        for x, y in zip(reach.get_x(),
                        reach.get_y()):
            lx.append(x[0])
            ly.append(y[0])

            rx.append(x[-1])
            ry.append(y[-1])

        line = self.canvas.axes.plot(
            lx, ly,
            color=self.color_plot_river_bottom,
            linestyle="dotted",
            lw=1.,
        )
        self.line_lr.append(line)

        line = self.canvas.axes.plot(
            rx, ry,
            color=self.color_plot_river_bottom,
            linestyle="dotted",
            lw=1.,
        )
        self.line_lr.append(line)

    def draw_geotiff(self, lst):
        if not _rasterio_loaded:
            return

        for img in self._plot_img:
            self._plot_img[img].remove()

        self._plot_img = {}

        for geotiff in lst:
            if geotiff.is_deleted():
                continue

            memfile = geotiff.memfile
            if memfile is None:
                continue

            with memfile.open() as gt:
                img = gt.read()
                coords = geotiff.coordinates

                left = coords["left"]
                right = coords["right"]
                bottom = coords["bottom"]
                top = coords["top"]

                self._plot_img[geotiff] = self.canvas.axes.imshow(
                    img.transpose((1, 2, 0)),
                    extent=(left, right, bottom, top)
                )

            if not geotiff.is_enabled():
                self._plot_img[geotiff].set(alpha=0.5)

        self.idle()

    @timer
    def update(self):
        self.draw()
        self.update_idle()
