-- AREAL --

DROP FUNCTION vrevisions_stable.insert_areal(bigint, bigint, bigint, geometry, integer, integer, hstore, double precision, geometry, hstore);

CREATE OR REPLACE FUNCTION vrevisions_stable.insert_areal(
    in_branch_id bigint,
    in_id bigint,
    in_commit_id bigint,
    in_the_geom geometry,
    in_zmin integer,
    in_zmax integer,
    in_domain_attrs hstore,
    in_area double precision,
    in_service_attrs hstore DEFAULT ''::hstore)
    RETURNS void AS
$$
DECLARE
    old_branches hstore;
    old_mask_id bigint;
    new_mask_id bigint;
BEGIN
    SELECT branch_mask_id, branches INTO old_mask_id, old_branches
        FROM vrevisions_stable.objects_a
        JOIN vrevisions_stable.branch_mask
        USING (branch_mask_id)
        WHERE id=in_id AND commit_id=in_commit_id AND zmin=in_zmin AND zmax=in_zmax
            AND CASE
                WHEN in_service_attrs IS NULL
                THEN service_attrs IS NULL
                ELSE service_attrs=in_service_attrs
                END
        LIMIT 1;
    IF FOUND THEN
        new_mask_id := vrevisions_stable.get_branch_mask_id(old_branches || hstore(in_branch_id::text,'1'));
        UPDATE vrevisions_stable.objects_a
            SET branch_mask_id=new_mask_id
            WHERE id=in_id AND branch_mask_id=old_mask_id;
    ELSE
        new_mask_id := vrevisions_stable.get_branch_mask_id(hstore(in_branch_id::text,'1'));
        INSERT INTO vrevisions_stable.objects_a (branch_mask_id, id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, area)
            VALUES (new_mask_id, in_id, in_commit_id, in_the_geom, in_zmin, in_zmax, in_domain_attrs, in_service_attrs, in_area);
    END IF;
END;
$$ LANGUAGE plpgsql;


DROP FUNCTION vrevisions_stable.update_areal(bigint, bigint, bigint, geometry, integer, integer, hstore, double precision, geometry);

CREATE OR REPLACE FUNCTION vrevisions_stable.update_areal(
    in_branch_id bigint,
    in_id bigint,
    in_commit_id bigint,
    in_the_geom geometry,
    in_zmin integer,
    in_zmax integer,
    in_domain_attrs hstore,
    in_area double precision)
    RETURNS void AS
$$
DECLARE
    r RECORD;
BEGIN
    SELECT * INTO r
        FROM vrevisions_stable.objects_a
        JOIN vrevisions_stable.branch_mask
        USING (branch_mask_id)
        WHERE id=in_id AND branches ? in_branch_id::text
        LIMIT 1;
    IF FOUND THEN
        PERFORM vrevisions_stable.delete_areal_impl(in_branch_id, in_id, r.branch_mask_id, r.branches);
        PERFORM vrevisions_stable.insert_areal(
            in_branch_id, in_id, in_commit_id, in_the_geom, in_zmin, in_zmax, in_domain_attrs, in_area, r.service_attrs);
    ELSE
        PERFORM vrevisions_stable.insert_areal(
            in_branch_id, in_id, in_commit_id, in_the_geom, in_zmin, in_zmax, in_domain_attrs, in_area);
    END IF;
END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION vrevisions_stable.update_areal_service_attrs(
    in_branch_id bigint,
    in_id bigint,
    in_zmin integer,
    in_zmax integer,
    in_service_attrs hstore)
    RETURNS void AS
$$
DECLARE
    r RECORD;
BEGIN
    SELECT * INTO r
        FROM vrevisions_stable.objects_a
        JOIN vrevisions_stable.branch_mask
        USING (branch_mask_id)
        WHERE id=in_id AND branches ? in_branch_id::text
        LIMIT 1;
    IF FOUND THEN
        PERFORM vrevisions_stable.delete_areal_impl(in_branch_id, in_id, r.branch_mask_id, r.branches);
        PERFORM vrevisions_stable.insert_areal(
            in_branch_id, in_id, r.commit_id, r.the_geom, in_zmin, in_zmax, r.domain_attrs, r.area, in_service_attrs);
    END IF;
END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION vrevisions_stable.prepare_schema(
    schemaname text,
    branch_id bigint)
    RETURNS void AS
$$
BEGIN
    PERFORM vrevisions.drop_views(schemaname);
    EXECUTE format('
        SET search_path=%I,public;

        DROP TABLE IF EXISTS objects_r CASCADE;
        DROP TABLE IF EXISTS objects CASCADE;

        CREATE VIEW objects_g AS
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs
                FROM vrevisions_stable.objects_g
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects AS
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs
                FROM vrevisions_stable.objects_g
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s''
            UNION ALL
            SELECT id, commit_id, NULL, 0, 0, domain_attrs, service_attrs
                FROM vrevisions_stable.objects_c
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_c AS
            SELECT id, commit_id, NULL::geometry AS the_geom, domain_attrs, service_attrs
                FROM vrevisions_stable.objects_c
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_p AS
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, part
                FROM vrevisions_stable.objects_p
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_l AS
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, length, part
                FROM vrevisions_stable.objects_l
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_a AS
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, area, part
                FROM vrevisions_stable.objects_a
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_r AS
            SELECT id, commit_id, domain_attrs, master_id, slave_id
                FROM vrevisions_stable.objects_r
                JOIN vrevisions_stable.branch_mask USING (branch_mask_id)
                WHERE branches ? ''%2$s'';

        CREATE VIEW objects_a_view AS
            WITH bm AS (
                SELECT branch_mask_id
                FROM vrevisions_stable.branch_mask
                WHERE branches ? ''%2$s'')
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, area, part
                FROM vrevisions_stable.objects_a
                WHERE branch_mask_id IN (SELECT branch_mask_id FROM bm);

        CREATE VIEW objects_l_view AS
            WITH bm AS (
                SELECT branch_mask_id
                FROM vrevisions_stable.branch_mask
                WHERE branches ? ''%2$s'')
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, length, part
                FROM vrevisions_stable.objects_l
                WHERE branch_mask_id IN (SELECT branch_mask_id FROM bm);

        CREATE VIEW objects_p_view AS
            WITH bm AS (
                SELECT branch_mask_id
                FROM vrevisions_stable.branch_mask
                WHERE branches ? ''%2$s'')
            SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, part
                FROM vrevisions_stable.objects_p
                WHERE branch_mask_id IN (SELECT branch_mask_id FROM bm);

        CREATE VIEW complex_objects_indirect_highlight_view AS
            WITH bm AS (
                SELECT branch_mask_id
                FROM vrevisions_stable.branch_mask
                WHERE branches ? ''%2$s'')
            SELECT r.master_id,
                l.id,
                l.the_geom,
                l.zmin,
                l.zmax,
                r.domain_attrs,
                r.slave_id,
                l.part
            FROM vrevisions_stable.objects_r r,
                 vrevisions_stable.objects_r r_next,
                 vrevisions_stable.objects_l l
            WHERE r.slave_id = r_next.master_id AND r_next.slave_id = l.id
                AND r.branch_mask_id IN (SELECT branch_mask_id FROM bm)
                AND r_next.branch_mask_id IN (SELECT branch_mask_id FROM bm)
                AND l.branch_mask_id IN (SELECT branch_mask_id FROM bm);

        CREATE VIEW complex_objects_l_highlight_view AS
            WITH bm AS (
                SELECT branch_mask_id
                FROM vrevisions_stable.branch_mask
                WHERE branches ? ''%2$s'')
            SELECT r.master_id,
                l.id,
                l.the_geom,
                l.zmin,
                l.zmax,
                l.part
                FROM vrevisions_stable.objects_r r
                JOIN vrevisions_stable.objects_l l ON r.slave_id = l.id
                WHERE r.branch_mask_id IN (SELECT branch_mask_id FROM bm)
                    AND l.branch_mask_id IN (SELECT branch_mask_id FROM bm);

        DROP FUNCTION IF EXISTS objects_a_insert_trigger();
        DROP FUNCTION IF EXISTS objects_a7_update_trigger();
        DROP FUNCTION IF EXISTS objects_a8_update_trigger();
        DROP FUNCTION IF EXISTS objects_a10_update_trigger();
        DROP FUNCTION IF EXISTS objects_a12_update_trigger();
        DROP FUNCTION IF EXISTS objects_a12_update_trigger();
        DROP FUNCTION IF EXISTS objects_a14_update_trigger();
        DROP FUNCTION IF EXISTS objects_a16_update_trigger();

        DROP FUNCTION IF EXISTS objects_l_insert_trigger();
        DROP FUNCTION IF EXISTS objects_l9_update_trigger();
        DROP FUNCTION IF EXISTS objects_l10_update_trigger();
        DROP FUNCTION IF EXISTS objects_l12_update_trigger();
        DROP FUNCTION IF EXISTS objects_l12_14_update_trigger();
        DROP FUNCTION IF EXISTS objects_l15_update_trigger();

        DROP FUNCTION IF EXISTS objects_p_insert_trigger();
        DROP FUNCTION IF EXISTS objects_p_update_trigger();
        DROP FUNCTION IF EXISTS objects_p16_update_trigger();',
        schemaname, branch_id::text);
END;
$$ LANGUAGE plpgsql;


DROP VIEW vrevisions_trunk.objects_a_view;
CREATE VIEW vrevisions_trunk.objects_a_view AS
    SELECT id, commit_id, the_geom, zmin, zmax, domain_attrs, service_attrs, area, part
        FROM vrevisions_trunk.objects_a;


WITH schemas AS (
    SELECT schemaname FROM pg_views
    WHERE schemaname like 'vrevisions_stable_%' AND viewname='objects_a' ORDER BY 1)
SELECT schemaname, vrevisions_stable.prepare_schema(schemaname, (SUBSTR(schemaname, 19))::bigint)
 FROM schemas;
