-- 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_uferstruktur_func(kartierabsch_id INTEGER)
RETURNS INTEGER AS
$$
DECLARE
    -- necessary meta information
    gew_typ_id           INTEGER;
    stat_laenge          NUMERIC;
    str_absch_laenge     NUMERIC;
    tmp_ufervegetation_typical INTEGER;
    uferveg_links_typical BOOLEAN ;
    uferveg_rechts_typical BOOLEAN;
    uferverb_links_id NUMERIC;
    uferverb_rechts_id NUMERIC;
    uferveg_links_id NUMERIC;
    uferveg_rechts_id NUMERIC;
    z_uferverb_rechts_id NUMERIC;
    z_uferverb_links_id NUMERIC;
    sum_uferstrukturen_links  NUMERIC := 0;
    sum_uferstrukturen_rechts NUMERIC := 0;
    uferstrukturen_absolut_links  NUMERIC := 0;
    uferstrukturen_absolut_rechts NUMERIC := 0;
    num_entries   INTEGER;

    -- ratings
    rating_total             NUMERIC := 0;
    num_rating               INTEGER := 0;
    rating_strukturen_rechts NUMERIC := 0;
    rating_strukturen_links  NUMERIC := 0;
    rating_ufervegetation_links   NUMERIC := 0;
    rating_ufervegetation_rechts  NUMERIC := 0;
    rating_uferverbau_links   NUMERIC := 0;
    rating_uferverbau_rechts  NUMERIC := 0;
    malus_uferbelastung_links NUMERIC := 0;
    malus_uferbelastung_rechts NUMERIC := 0;

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

BEGIN

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

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

    --
    -- collect necessary meta information
    --
    SELECT gewaessertyp_id, abs(stationierung_bis - stationierung_von)
           INTO gew_typ_id, stat_laenge
           FROM kartierabschnitt
           WHERE id = kartierabsch_id;

    RAISE DEBUG 'Gewassertyp ID = %', gew_typ_id;
    RAISE DEBUG 'Absolute Laenge der Stationierung = %', stat_laenge;

    SELECT abschnittslaenge INTO str_absch_laenge
           FROM  uferstrukturen_auswertung
           WHERE id_gewaessertyp = gew_typ_id;
    RAISE DEBUG 'Abschnittslaenge Uferstrukturen = %', str_absch_laenge;

    SELECT uferverbau_links_id, z_uferverbau_links_id,
           uferverbau_rechts_id, z_uferverbau_rechts_id,
           ufervegetation_links_id, ufervegetation_links_typical,
           ufervegetation_rechts_id,ufervegetation_rechts_typical
          INTO uferverb_links_id , z_uferverb_links_id,
               uferverb_rechts_id, z_uferverb_rechts_id,
               uferveg_links_id, uferveg_links_typical,
               uferveg_rechts_id, uferveg_rechts_typical
          FROM uferstruktur 
          WHERE kartierabschnitt_id = kartierabsch_id;

    RAISE DEBUG 'uferverbau_links_id = %', uferverb_links_id;
    RAISE DEBUG 'Zustand uferverbau_links_id = %', z_uferverb_links_id;

    RAISE DEBUG 'uferverbau_rechts_id = %', uferverb_rechts_id;
    RAISE DEBUG 'Zustand uferverbau_rechts_id = %', z_uferverb_rechts_id;

    RAISE DEBUG 'ufervegetation_links_id = %', uferveg_links_id;
    RAISE DEBUG 'ufervegetation_links_typical = %', uferveg_links_typical;

    RAISE DEBUG 'ufervegetation_rechts_id = %', uferveg_rechts_id;
    RAISE DEBUG 'ufervegetation_rechts_typical = %', uferveg_rechts_typical;

    IF (str_absch_laenge > 0) THEN
        SELECT SUM(anzahl_links), SUM(anzahl_rechts)
               INTO sum_uferstrukturen_links, sum_uferstrukturen_rechts
               FROM uferstruktur_hat_uferstrukturen
               WHERE kartierabschnitt_id = kartierabsch_id AND
                     uferstrukturen_id < 8;
        RAISE DEBUG '-> Absolute Anzahl Uferstrukturen links: %', 
                     sum_uferstrukturen_links;
        RAISE DEBUG '-> Absolute Anzahl Uferstrukturen rechts: %', 
                     sum_uferstrukturen_rechts;
                     
        IF sum_uferstrukturen_links = 0.5 THEN
            uferstrukturen_absolut_links := sum_uferstrukturen_links;
        ELSE
            SELECT fgsk_round((sum_uferstrukturen_links / 
                              (stat_laenge*factor) * str_absch_laenge))
                   INTO uferstrukturen_absolut_links;
        END IF;
        
        RAISE DEBUG '-> Anzahl Uferstrukturen pro Abschnittslaenge links: %', 
                     uferstrukturen_absolut_links;

        IF sum_uferstrukturen_rechts = 0.5 THEN
            sum_uferstrukturen_rechts := sum_uferstrukturen_rechts;
        ELSE
            SELECT fgsk_round((sum_uferstrukturen_rechts / 
                              (stat_laenge*factor) * str_absch_laenge))
                   INTO uferstrukturen_absolut_rechts;
        END IF;
        
        RAISE DEBUG '-> Anzahl Uferstrukturen pro Abschnittslaenge rechts: %', 
                     uferstrukturen_absolut_rechts;
        
        SELECT bewertung INTO rating_strukturen_links
               FROM uferstrukturen_auswertung
               WHERE anz_uferstrukturen_von <= uferstrukturen_absolut_links AND
                     anz_uferstrukturen_bis >= uferstrukturen_absolut_links AND
                     id_gewaessertyp = gew_typ_id;

        SELECT bewertung INTO rating_strukturen_rechts
               FROM uferstrukturen_auswertung
               WHERE anz_uferstrukturen_von <= uferstrukturen_absolut_rechts AND
                     anz_uferstrukturen_bis >= uferstrukturen_absolut_rechts AND
                     id_gewaessertyp = gew_typ_id;

    END IF;

    RAISE DEBUG '-> Uferstrukturen links: %', rating_strukturen_links;
    RAISE DEBUG '-> Uferstrukturen rechts: %', rating_strukturen_rechts;

    tmp_ufervegetation_typical :=1;
    IF uferveg_links_typical = false THEN
        tmp_ufervegetation_typical := 2;
    END IF;

    SELECT bewertung INTO rating_ufervegetation_links 
           FROM ufervegetation_auswertung 
           WHERE id_ufervegetation = uferveg_links_id AND 
                 ufervegetation_typical = tmp_ufervegetation_typical AND 
                 id_gewaessertyp = gew_typ_id;
                 
    RAISE DEBUG '-> Uferbewuchs links: %', rating_ufervegetation_links;

    tmp_ufervegetation_typical :=1;
    IF uferveg_rechts_typical = false THEN
        tmp_ufervegetation_typical := 2;
    END IF;

    SELECT bewertung INTO rating_ufervegetation_rechts 
           FROM ufervegetation_auswertung 
           WHERE id_ufervegetation = uferveg_rechts_id AND 
                 ufervegetation_typical = tmp_ufervegetation_typical AND 
                 id_gewaessertyp = gew_typ_id;
                 
    RAISE DEBUG '-> Uferbewuchs rechts: %', rating_ufervegetation_rechts;

    SELECT bewertung INTO rating_uferverbau_links 
           FROM uferverbau_auswertung 
           WHERE id_uferverbau = uferverb_links_id AND 
                 id_z_uferverbau = z_uferverb_links_id AND 
                 id_gewaessertyp = gew_typ_id;
    RAISE DEBUG '-> Uferverbau links: %', rating_uferverbau_links;

    SELECT bewertung INTO rating_uferverbau_rechts 
           FROM uferverbau_auswertung 
           WHERE id_uferverbau = uferverb_rechts_id AND 
                 id_z_uferverbau = z_uferverb_rechts_id AND 
                 id_gewaessertyp = gew_typ_id;
    RAISE DEBUG '-> Uferverbau rechts: %', rating_uferverbau_rechts;

    SELECT SUM(bewertung) INTO malus_uferbelastung_links
       FROM uferbelastungen_auswertung, uferstruktur_hat_uferbelastungen
       WHERE kartierabschnitt_id = kartierabsch_id AND
             uferbelastungen_id = id_uferbelastungen AND
             id_gewaessertyp = gew_typ_id AND
             anzahl_links > 0;
    RAISE DEBUG '-> Malus besondere Uferbelastungen links: %',
                 malus_uferbelastung_links;

    IF (malus_uferbelastung_links IS NOT NULL AND
       malus_uferbelastung_links < -2.5) THEN
        malus_uferbelastung_links := -2.5;
        RAISE DEBUG '-> Korrigierter Malus besondere Uferbelastungen links: %',
                 malus_uferbelastung_links;
    END IF;

    SELECT SUM(bewertung) INTO malus_uferbelastung_rechts
       FROM uferbelastungen_auswertung, uferstruktur_hat_uferbelastungen
       WHERE kartierabschnitt_id = kartierabsch_id AND
             uferbelastungen_id = id_uferbelastungen AND
             id_gewaessertyp = gew_typ_id AND
             anzahl_rechts > 0;
    RAISE DEBUG '-> Malus besondere Uferbelastungen rechts: %',
                 malus_uferbelastung_rechts;

    IF (malus_uferbelastung_rechts IS NOT NULL AND 
        malus_uferbelastung_rechts < -2.5) THEN
        malus_uferbelastung_rechts := -2.5;
        RAISE DEBUG '-> Korrigierter Malus besondere Uferbelastungen rechts: %',
                 malus_uferbelastung_rechts;
    END IF;
    --
    -- calculation of the rating
    --
    
    IF (rating_strukturen_links IS NOT NULL AND
        rating_strukturen_links > 0) THEN
            rating_total := rating_total + rating_strukturen_links;
            num_rating := num_rating + 1;
    END IF;

    IF (rating_strukturen_rechts IS NOT NULL AND
        rating_strukturen_rechts > 0) THEN
            rating_total := rating_total + rating_strukturen_rechts;
            num_rating := num_rating + 1;
    END IF;

    IF (rating_ufervegetation_links IS NOT NULL AND
        rating_ufervegetation_links > 0) THEN
            rating_total := rating_total + rating_ufervegetation_links;
            num_rating := num_rating + 1;
    END IF;

    IF (rating_ufervegetation_rechts IS NOT NULL AND
        rating_ufervegetation_rechts > 0) THEN
            rating_total := rating_total + rating_ufervegetation_rechts;
            num_rating := num_rating + 1;
    END IF;

    IF (rating_uferverbau_links IS NOT NULL AND
        rating_uferverbau_links > 0) THEN
            rating_total := rating_total + rating_uferverbau_links;
            num_rating := num_rating + 1;
    END IF;

    IF (rating_uferverbau_rechts IS NOT NULL AND
        rating_uferverbau_rechts > 0) THEN
            rating_total := rating_total + rating_uferverbau_rechts;
            num_rating := num_rating + 1;
    END IF;

    IF (malus_uferbelastung_links IS NOT NULL AND
        malus_uferbelastung_links < 0) THEN
            rating_total := rating_total + malus_uferbelastung_links;
    END IF;

    IF (malus_uferbelastung_rechts IS NOT NULL AND 
        malus_uferbelastung_rechts < 0) THEN
            rating_total := rating_total + malus_uferbelastung_rechts;
    END IF;

    UPDATE uferstruktur SET summe_punktzahl = rating_total, 
                            anzahl_kriterien = num_rating
           WHERE kartierabschnitt_id = kartierabsch_id;
    RAISE DEBUG '=> Uferstruktur gesamt: %', rating_total;
    RAISE DEBUG '=> Anzahl der Kriterien: %', num_rating;

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

    RETURN kartierabsch_id;

END
$$ LANGUAGE plpgsql;

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

    RAISE DEBUG '%: TABLE NAME = %', TG_OP, TG_TABLE_NAME;
    
    IF (TG_TABLE_NAME = 'uferstruktur') THEN
        IF NEW.ufervegetation_links_id IS NULL
           OR NEW.ufervegetation_rechts_id IS NULL
           OR NEW.ufervegetation_links_typical IS NULL
           OR NEW.ufervegetation_rechts_typical IS NULL
           OR NEW.uferverbau_links_id IS NULL
           OR NEW.uferverbau_rechts_id IS NULL
           OR NEW.z_uferverbau_links_id IS NULL
           OR NEW.z_uferverbau_rechts_id IS NULL THEN

           RAISE DEBUG 'Keine Aktualisierung fuer Uferstruktur noetig.';
           RETURN NEW;
       END IF;
    END IF;
    
    IF (TG_OP = 'UPDATE') THEN
        IF (TG_TABLE_NAME = 'uferstruktur') THEN
            IF (NEW.ufervegetation_links_id = OLD.ufervegetation_links_id)
              AND (NEW.ufervegetation_rechts_id = OLD.ufervegetation_rechts_id)
              AND (NEW.ufervegetation_links_typical = OLD.ufervegetation_links_typical)
              AND (NEW.ufervegetation_rechts_typical = OLD.ufervegetation_rechts_typical)
              AND (NEW.uferverbau_links_id = OLD.uferverbau_links_id)
              AND (NEW.uferverbau_rechts_id = OLD.uferverbau_rechts_id)
              AND (NEW.z_uferverbau_links_id = OLD.z_uferverbau_links_id)
              AND (NEW.z_uferverbau_rechts_id = OLD.z_uferverbau_rechts_id) THEN

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

    PERFORM calculate_points_uferstruktur_func(NEW.kartierabschnitt_id);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;


--
-- remove existing triggers before creating new ones
--
DROP TRIGGER IF EXISTS update_uferstruktur_points
ON uferstruktur;

DROP TRIGGER IF EXISTS update_uferstruktur_points
ON uferstruktur_hat_uferstrukturen;

DROP TRIGGER IF EXISTS update_uferstruktur_points
ON uferstruktur_hat_uferbelastungen;

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

CREATE TRIGGER update_uferstruktur_points
AFTER UPDATE OR INSERT
    ON uferstruktur_hat_uferstrukturen
    FOR EACH ROW EXECUTE PROCEDURE
        update_points_uferstruktur_func();

CREATE TRIGGER update_uferstruktur_points
AFTER UPDATE OR INSERT
    ON uferstruktur_hat_uferbelastungen
    FOR EACH ROW EXECUTE PROCEDURE
        update_points_uferstruktur_func();


-- END TRANSACTION
END;
