# Types.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 Model.HydraulicStructures.Basic.HydraulicStructures import (
    BasicHS
)

from Model.HydraulicStructures.Basic.Value import (
    BHSValue
)


class NotDefined(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(NotDefined, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "ND"
        self._data = []


class DischargeWeir(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(DischargeWeir, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "S1"
        self._data = [
            BHSValue(-1, "width", float, 1.0, status=status),
            BHSValue(-1, "elevation", float, 1.0, status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
        ]


class TrapezoidalWeir(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(TrapezoidalWeir, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "S2"
        self._data = [
            BHSValue(-1, "width", float, 1.0, status=status),
            BHSValue(-1, "elevation", float, 1.0, status=status),
            BHSValue(-1, "loading_elevation", float, 9999.999, status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
            BHSValue(-1, "half-angle_tangent", float, 0.0, status=status),
        ]


class TriangularWeir(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(TriangularWeir, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "S3"
        self._data = [
            BHSValue(-1, "elevation", float, 1.0, status=status),
            BHSValue(-1, "loading_elevation", float, 9999.999, status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.31, status=status),
            BHSValue(-1, "half-angle_tangent", float, 1.0, status=status),
        ]


class RectangularOrifice(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(RectangularOrifice, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "OR"
        self._data = [
            BHSValue(-1, "width", float, 0.0, status=status),
            BHSValue(-1, "elevation", float, 0.0, status=status),
            BHSValue(-1, "loading_elevation", float, 9999.999,
                     status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
            BHSValue(-1, "maximal_loading_elevation", float, 9999.999,
                     status=status),
        ]


class CircularOrifice(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(CircularOrifice, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "OC"
        self._data = [
            BHSValue(-1, "diameter", float, 0.0, status=status),
            BHSValue(-1, "elevation", float, 0.0, status=status),
            BHSValue(-1, "siltation_height", float, 0.0, status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
        ]


class VaultedOrifice(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(VaultedOrifice, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "OV"
        self._data = [
            BHSValue(-1, "elevation", float, 1.0, status=status),
            BHSValue(-1, "width", float, 1.0, status=status),
            BHSValue(-1, "top_of_the_vault", float, 0.0, status=status),
            BHSValue(-1, "bottom_of_the_vault", float, 0.0, status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
        ]


class RectangularGate(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(RectangularGate, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "V1"
        self._data = [
            BHSValue(-1, "width", float, 1.0, status=status),
            BHSValue(-1, "elevation", float, 0.0, status=status),
            BHSValue(-1, "discharge coefficient", float, 0.4, status=status),
            BHSValue(-1, "opening", float, 1.0, status=status),
            BHSValue(-1, "maximal_opening", float, 1.0, status=status),
        ]


class SimplifiedRectangularGate(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(SimplifiedRectangularGate, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "V2"
        self._data = [
            BHSValue(-1, "width", float, 1.0, status=status),
            BHSValue(-1, "elevation", float, 0.0, status=status),
            BHSValue(-1, "discharge coefficient", float, 0.4, status=status),
            BHSValue(-1, "opening", float, 1.0, status=status),
            BHSValue(-1, "maximal_opening", float, 1.0, status=status),
        ]


class Borda(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(Borda, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "BO"
        self._data = [
            BHSValue(-1, "step_space", float, 0.1, status=status),
            BHSValue(-1, "weir", float, 0.15, status=status),
            BHSValue(-1, "coefficient", float, 0.4, status=status),
        ]


class CheckValve(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(CheckValve, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "CV"
        self._data = [
            BHSValue(-1, "width", float, 0.0, status=status),
            BHSValue(-1, "elevation", float, 0.0, status=status),
            BHSValue(-1, "loading_elevation", float, 9999.999,
                     status=status),
            BHSValue(-1, "discharge_coefficient", float, 0.4, status=status),
            BHSValue(-1, "maximal_loading_elevation", float, 9999.999,
                     status=status),
        ]


class UserDefined(BasicHS):
    def __init__(self, id: int = -1, name: str = "",
                 status=None, owner_scenario=-1):
        super(UserDefined, self).__init__(
            id=id, name=name,
            status=status,
            owner_scenario=owner_scenario
        )

        self._type = "UD"
        self._data = [
            BHSValue(-1, "parameter_1", float, 0.0, status=status),
            BHSValue(-1, "parameter_2", float, 0.0, status=status),
            BHSValue(-1, "parameter_3", float, 0.0, status=status),
            BHSValue(-1, "parameter_4", float, 0.0, status=status),
            BHSValue(-1, "parameter_5", float, 0.0, status=status),
        ]


BHS_types = {
    "ND": NotDefined,
    "S1": DischargeWeir,
    "S2": TrapezoidalWeir,
    "S3": TriangularWeir,
    "OR": RectangularOrifice,
    "OC": CircularOrifice,
    # "OV": VaultedOrifice,
    "V1": RectangularGate,
    "V2": SimplifiedRectangularGate,
    "BO": Borda,
    "CV": CheckValve,
    "UD": UserDefined
}
