# MeshingDialog.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 View.Tools.PamhyrWindow import PamhyrDialog

from PyQt5.QtGui import (
    QKeySequence,
)

from PyQt5.QtCore import (
    Qt, QVariant, QAbstractTableModel, QItemSelectionModel,
)

from PyQt5.QtWidgets import (
    QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
    QDoubleSpinBox, QRadioButton,
)


class MeshingDialog(PamhyrDialog):
    _pamhyr_ui = "MeshingOptions"
    _pamhyr_name = "Meshing"

    def __init__(self, reach, trad=None, parent=None):
        super(MeshingDialog, self).__init__(
            title=trad[self._pamhyr_name],
            trad=trad,
            options=[],
            parent=parent
        )

        self._reach = reach
        self._profiles = None

        self._init_default_values()

    def _init_default_values(self):
        gl, _ = self._reach.compute_guidelines()
        self._gl = list(gl)
        self._space_step = 50.0
        self._lplan = False
        self._lm = "3"
        self._linear = True
        self._begin_cs = -1
        self._end_cs = -1
        self._begin_dir = "un"
        self._end_dir = "np"

        lower_gl = list(map(str.lower, self._gl))
        for i, gl in enumerate(lower_gl):
            if gl == "rg":
                self._begin_dir = self._gl[i]
            elif gl == "rd":
                self._end_dir = self._gl[i]

        self._origin = self._reach.profile(0)

        self._init_default_values_profiles()
        # self._init_default_values_guidelines()

        self.set_double_spin_box(
            "doubleSpinBox_space_step",
            self._space_step
        )

        if self._linear:
            self.set_radio_button("radioButton_linear", True)
        else:
            self.set_radio_button("radioButton_spline", True)

        self.find(QRadioButton, "radioButton_spline").setEnabled(False)
        self.find(QRadioButton, "radioButton_linear").setEnabled(False)

    def _init_default_values_profiles(self):
        profiles = self.profiles

        self.combobox_add_items("comboBox_begin_rk", profiles)
        self.combobox_add_items("comboBox_end_rk", profiles)

        r = self.parent.tableView\
                .selectionModel()\
                .selectedRows()
        if len(r) <= 1:
            self.set_combobox_text("comboBox_begin_rk", profiles[0])
            self.set_combobox_text("comboBox_end_rk", profiles[-1])
        else:
            self.set_combobox_text("comboBox_begin_rk", profiles[r[0].row()])
            self.set_combobox_text("comboBox_end_rk", profiles[r[-1].row()])

    @property
    def profiles(self):
        if self._profiles is None:
            self._profiles = list(
                map(
                    lambda p: self._profile_name(p),
                    self._reach.profiles
                )
            )

        return self._profiles

    def _profile_name(self, profile):
        name = profile.name

        if name == "":
            name = f"{profile.rk}"
        else:
            name += f" ({profile.rk})"

        return name

    def _init_default_values_guidelines(self):
        gl, _ = self._reach.compute_guidelines()
        gl = list(gl)

        bgl = ['un'] + gl + ['np']
        egl = ['un'] + gl + ['np']

        self.combobox_add_items("comboBox_begin_gl", bgl)
        self.combobox_add_items("comboBox_end_gl", egl)

        self.set_combobox_text("comboBox_begin_gl", self._begin_dir)
        self.set_combobox_text("comboBox_end_gl", self._end_dir)

    @property
    def space_step(self):
        return self._space_step

    @property
    def lplan(self):
        return self._lplan

    @property
    def linear(self):
        return self._linear

    @property
    def begin_cs(self):
        return self._begin_cs

    @property
    def end_cs(self):
        return self._end_cs

    @property
    def begin_dir(self):
        return self._begin_dir

    @property
    def end_dir(self):
        return self._end_dir

    def accept(self):
        self._space_step = self.get_double_spin_box(
            "doubleSpinBox_space_step",
        )
        self._linear = self.get_radio_button("radioButton_linear")

        p1 = self.get_combobox_text("comboBox_begin_rk")
        p2 = self.get_combobox_text("comboBox_end_rk")

        self._begin_cs = self.profiles.index(p1)
        self._end_cs = self.profiles.index(p2)

        # self._begin_dir = self.get_combobox_text("comboBox_begin_gl")
        # self._end_dir = self.get_combobox_text("comboBox_end_gl")

        super().accept()

    def reject(self):
        self.close()
