-- Copyright 2010, Intevation GmbH, Germany, <info@intevation.de>
--
-- This file is part of FGSK.
--
-- FGSK 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 2 of the License, or (at your
-- option) any later version.
--
-- FGSK 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 FGSK. If not, see <http://www.gnu.org/licenses/>.
--
-- FGSK has been developed on behalf of the
-- Landesamt fuer Umwelt und Geologie Mecklenburg Vorpommern (LUNG-MV)
-- by Intevation GmbH. 
-- biota Institut fuer oekologische Forschung und Planung GmbH has provided
-- the functional background.
--
-- Authors:
-- Tim Englich <tim.englich@intevation.de>
-- Ingo Weinzierl <ingo.weinzierl@intevation.de>

BEGIN;
-- BEGIN TRANSACTION

CREATE OR REPLACE FUNCTION 
             calculate_points_laufentwicklung_func(kartierabsch_id INTEGER)
RETURNS INTEGER AS
$$
DECLARE
    -- necessary meta information
    laufkr_id     INTEGER;
    gew_typ_id    INTEGER;
    kruemm_id     INTEGER;
    laengsb_sum   NUMERIC;
    lb_absolute   NUMERIC;
    ls_absolute   NUMERIC;
    laufst_sum    NUMERIC;
    abschn_laeng  NUMERIC;
    abschn_lauf   NUMERIC;
    stat_laenge   NUMERIC;
    laengsb_abs   NUMERIC;
    num_entries   INTEGER;

    -- ratings
    rating_total             INTEGER := 0;
    num_rating               INTEGER := 0;
    rating_laufkruemmung     INTEGER;
    rating_kruemmungserosion INTEGER;
    rating_laengsbaenke      INTEGER;
    rating_laufstrukturen    INTEGER;

    -- this factor is necessary to transform kilometer into meter
    factor INTEGER := 1;
BEGIN

    SELECT COUNT(*) INTO num_entries
                    FROM laufentwicklung
                    WHERE kartierabschnitt_id  = kartierabsch_id;
    IF (num_entries = 0 )THEN
        RAISE DEBUG 'Kein Eintrag fuer laufentwicklung vorhanden. --> Abbruch';
        RETURN kartierabsch_id;
    END IF;

    RAISE DEBUG '------- AUSWERTUNG LAUFENTWICKLUNG -------';
    RAISE DEBUG 'Kartierabschnitt ID %', kartierabsch_id;

    --
    -- collect necessary meta information
    --
    SELECT gewaessertyp_id INTO gew_typ_id FROM kartierabschnitt
           WHERE id = kartierabsch_id;
    RAISE DEBUG 'Gewassertyp ID = %', gew_typ_id;

    SELECT laufkruemmung_id INTO laufkr_id FROM laufentwicklung
           WHERE kartierabschnitt_id = kartierabsch_id;
    RAISE DEBUG 'Laufkruemmung ID = %', laufkr_id;

    SELECT sum(anzahl) INTO laengsb_sum
           FROM laufentwicklung_hat_laengsbaenke
           WHERE kartierabschnitt_id = kartierabsch_id
                 AND laengsbaenke_id < 4;
    RAISE DEBUG 'Summe Laengsbaenke = %', laengsb_sum;

    SELECT abs(stationierung_bis - stationierung_von) INTO stat_laenge
           FROM kartierabschnitt
           WHERE id = kartierabsch_id;
    RAISE DEBUG 'Absolute Laenger der Stationierung = %', stat_laenge;

    SELECT DISTINCT abschnittslaenge INTO abschn_laeng
           FROM laengsbaenke_auswertung
           WHERE id_gewaessertyp = gew_typ_id;
    RAISE DEBUG 'Abschnittslaenge Laengsbaenke = %', abschn_laeng;

    IF laengsb_sum = 0.5 THEN
        lb_absolute := laengsb_sum;
    ELSE
        SELECT fgsk_round(laengsb_sum/(stat_laenge*factor/abschn_laeng))
               INTO lb_absolute;
    END IF;
    RAISE DEBUG 'Absolute Anzahl Laengsbaenke pro XXXm = %', lb_absolute;

    SELECT sum(anzahl) INTO laufst_sum
           FROM laufentwicklung_hat_laufstrukturen
           WHERE kartierabschnitt_id = kartierabsch_id
                 AND laufstrukturen_id < 7;
    RAISE DEBUG 'Summe Laufstrukturen = %', laufst_sum;

    SELECT DISTINCT abschnittslaenge INTO abschn_lauf
           FROM laufstrukturen_auswertung
           WHERE id_gewaessertyp = gew_typ_id;
    RAISE DEBUG 'Abschnittslaenge Laufstrukturen= %', abschn_lauf;

    IF laufst_sum = 0.5 THEN
        ls_absolute := laufst_sum;
    ELSE
        SELECT fgsk_round(laufst_sum/(stat_laenge*factor/abschn_lauf))
               INTO ls_absolute;
    END IF;
    RAISE DEBUG 'Absolute Anzahl Laufstrukturen pro XXXm = %', ls_absolute;



    SELECT kruemmungserosion_id INTO kruemm_id
           FROM laufentwicklung
           WHERE kartierabschnitt_id = kartierabsch_id;
    RAISE DEBUG 'Kruemmungserosion ID = %', kruemm_id;


    --
    -- collect ratings
    --
    SELECT bewertung INTO rating_laufkruemmung FROM laufkruemmung_auswertung
           WHERE id_gewaessertyp = gew_typ_id
                 AND id_laufkruemmung = laufkr_id;
    RAISE DEBUG '-> Laufkruemmung: %', rating_laufkruemmung;

    SELECT bewertung INTO rating_laengsbaenke FROM laengsbaenke_auswertung
           WHERE id_gewaessertyp = gew_typ_id
                 AND anz_laengsbaenke_von <= lb_absolute
                 and anz_laengsbaenke_bis >= lb_absolute;
    RAISE DEBUG '-> Laengsbaenke: %', rating_laengsbaenke;

    SELECT bewertung INTO rating_laufstrukturen
           FROM laufstrukturen_auswertung
           WHERE id_gewaessertyp = gew_typ_id
                 AND anz_laufstrukturen_von <= ls_absolute
                 and anz_laufstrukturen_bis >= ls_absolute;
    RAISE DEBUG '-> Laufstrukturen: %', rating_laufstrukturen;

    SELECT bewertung INTO rating_kruemmungserosion
           FROM kruemmungserosion_auswertung
           WHERE id_gewaessertyp = gew_typ_id
                 AND id_kruemmungserosion = kruemm_id;
    RAISE DEBUG '-> Kruemmungserosion: %', rating_kruemmungserosion;

    --
    -- calculate the total rating and return it
    --
    IF rating_laufkruemmung > 0 THEN
        rating_total := rating_total + rating_laufkruemmung;
        num_rating := num_rating + 1;
    END IF;

    IF rating_kruemmungserosion > 0 THEN
        rating_total := rating_total + rating_kruemmungserosion;
        num_rating := num_rating + 1;
    END IF;

    IF rating_laengsbaenke > 0 THEN
        rating_total := rating_total + rating_laengsbaenke;
        num_rating := num_rating + 1;
    END IF;

    IF rating_laufstrukturen > 0 THEN
        rating_total := rating_total + rating_laufstrukturen;
        num_rating := num_rating + 1;
    END IF;

    RAISE DEBUG '=> Laufentwicklung gesamt: %', rating_total;
    RAISE DEBUG '=> Anzahl der Kriterien: %', num_rating;

    UPDATE laufentwicklung SET summe_punktzahl = rating_total , 
                               anzahl_kriterien = num_rating
           WHERE kartierabschnitt_id = kartierabsch_id;

    -- Call Gesamtbewertungs-function
    PERFORM update_points_kartierabschnitt_func(kartierabsch_id);

    RETURN kartierabsch_id;

END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION update_points_laufentwicklung_func()
RETURNS TRIGGER AS
$$
DECLARE
BEGIN

    RAISE DEBUG '%: TABLE NAME = %', TG_OP, TG_TABLE_NAME;
    IF (TG_TABLE_NAME = 'laufentwicklung') THEN
        IF NEW.laufkruemmung_id IS NULL OR NEW.kruemmungserosion_id IS NULL THEN
            RAISE DEBUG 'Keine Aktualisierung fuer Laufentwicklung noetig.';
           RETURN NEW;
        END IF;
    END IF;

    IF (TG_OP = 'UPDATE') THEN
        IF (TG_TABLE_NAME = 'laufentwicklung') THEN
            IF (NEW.laufkruemmung_id = OLD.laufkruemmung_id) AND
               (NEW.kruemmungserosion_id = OLD.kruemmungserosion_id) THEN

                RAISE DEBUG 'Keine Aktualisierung fuer Laufentwicklung noetig.';
                RETURN NEW;
            END IF;
        END IF;
    END IF;

    PERFORM calculate_points_laufentwicklung_func(NEW.kartierabschnitt_id);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;


--
-- remove existing triggers before creating new ones
--
DROP TRIGGER IF EXISTS update_laufentwicklung_points
ON laufentwicklung;

DROP TRIGGER IF EXISTS update_laufentwicklung_points
ON laufentwicklung_hat_laengsbaenke;

DROP TRIGGER IF EXISTS update_laufentwicklung_points
ON laufentwicklung_hat_laufstrukturen;


--
-- necessary trigger for each table that has a relation to LAUFENTWICKLUNG
--
CREATE TRIGGER update_laufentwicklung_points
AFTER UPDATE OR INSERT
    ON laufentwicklung
    FOR EACH ROW EXECUTE PROCEDURE
        update_points_laufentwicklung_func();

CREATE TRIGGER update_laufentwicklung_points
AFTER UPDATE OR INSERT
    ON laufentwicklung_hat_laengsbaenke
    FOR EACH ROW EXECUTE PROCEDURE
        update_points_laufentwicklung_func();

CREATE TRIGGER update_laufentwicklung_points
AFTER UPDATE OR INSERT
    ON laufentwicklung_hat_laufstrukturen
    FOR EACH ROW EXECUTE PROCEDURE
        update_points_laufentwicklung_func();

-- END TRANSACTION
END;
