CREATE TABLE func_begin_change(
    id INTEGER NOT NULL,
    parent_id INTEGER,
    author VARCHAR(255),
    author_contact VARCHAR(255),
    author_contact_method VARCHAR(255),
    author_shortname VARCHAR(255),
    lang VARCHAR(8) NOT NULL DEFAULT 'en',
    mtime INTEGER,
    mtimetz INTEGER
);


CREATE TRIGGER
    func_begin_change_bi_1
BEFORE INSERT ON
    func_begin_change
FOR EACH ROW
BEGIN

    SELECT debug(
        NEW.id,
        NEW.parent_id,
        NEW.author,
        NEW.author_contact,
        NEW.author_contact_method,
        NEW.author_shortname,
        NEW.lang,
        NEW.mtime,
        NEW.mtimetz
    );

    INSERT INTO changes(
        id,
        parent_id,
        author,
        author_contact,
        author_contact_method,
        author_shortname,
        mtime,
        mtimetz,
        mtimetzhm,
        lang,
        yaml
    )
    SELECT
        NEW.id,
        NEW.parent_id,
        NEW.author,
        NEW.author_contact,
        NEW.author_contact_method,
        NEW.author_shortname,
        COALESCE(NEW.mtime, strftime('%s','now')),
        COALESCE(NEW.mtimetz,
            strftime('%s','now','localtime') - strftime('%s','now')),
        -- All the following duplicate calculations
        -- because SQLite doesn't have variables:
        printf(
            -- FORMAT STRING
            "%+.2d%.2d",
            -- ARG 1
            CAST(COALESCE(NEW.mtimetz,
                strftime('%s','now','localtime') - strftime('%s','now')) / 3600
                AS INTEGER),
            -- ARG 2
            (
                abs(COALESCE(NEW.mtimetz,
                    strftime('%s','now','localtime') - strftime('%s','now'))) -
                CAST(abs( COALESCE(NEW.mtimetz,
                    strftime('%s','now','localtime') - strftime('%s','now')))
                    / 3600 AS INTEGER) * 3600
            ) / 60
        ),
        NEW.lang,

        /*
            We do not include identity_id here because for new
            identities the id/uuid is not yet known. The identity_id
            may already be set however, and is in fact required for
            things like hub_entities.
        */

        -- yaml:
        '---' || x'0A'
        || '-' || x'0A'
        ||
            CASE WHEN
                NEW.author IS NULL
            THEN
                '  author: ~' || x'0A'
            WHEN
                NEW.author = '-'
            THEN
                '  author: ''-''' || x'0A'
            WHEN
                instr(NEW.author, x'0A') OR
                instr(NEW.author, '\\')
            THEN
                '  author: "'
                || REPLACE(
                      REPLACE(
                        REPLACE(NEW.author, '\\', '\\\\'),
                        x'0A', '\n'), '"', '\"')
                || '"' || x'0A'
            WHEN
                instr(NEW.author, ' ') OR
                NEW.author = '' -- not at all sufficient
            THEN
                '  author: ''' || NEW.author || '''' || x'0A'
            ELSE
                '  author: ' || NEW.author || x'0A'
            END
        ||
            CASE WHEN
                NEW.author_contact IS NULL
            THEN
                '  author_contact: ~' || x'0A'
            WHEN
                NEW.author_contact = '-'
            THEN
                '  author_contact: ''-''' || x'0A'
            WHEN
                instr(NEW.author_contact, x'0A') OR
                instr(NEW.author_contact, '\\')
            THEN
                '  author_contact: "'
                || REPLACE(
                      REPLACE(
                        REPLACE(NEW.author_contact, '\\', '\\\\'),
                        x'0A', '\n'), '"', '\"')
                || '"' || x'0A'
            WHEN
                instr(NEW.author_contact, ' ') OR
                NEW.author_contact = '' -- not at all sufficient
            THEN
                '  author_contact: ''' || NEW.author_contact || '''' || x'0A'
            ELSE
                '  author_contact: ' || NEW.author_contact || x'0A'
            END
        ||
            CASE WHEN
                NEW.author_contact_method IS NULL
            THEN
                '  author_contact_method: ~' || x'0A'
            WHEN
                NEW.author_contact_method = '-'
            THEN
                '  author_contact_method: ''-''' || x'0A'
            WHEN
                instr(NEW.author_contact_method, x'0A') OR
                instr(NEW.author_contact_method, '\\')
            THEN
                '  author_contact_method: "'
                || REPLACE(
                      REPLACE(
                        REPLACE(NEW.author_contact_method, '\\', '\\\\'),
                        x'0A', '\n'), '"', '\"')
                || '"' || x'0A'
            WHEN
                instr(NEW.author_contact_method, ' ') OR
                NEW.author_contact_method = '' -- not at all sufficient
            THEN
                '  author_contact_method: ''' || NEW.author_contact_method || '''' || x'0A'
            ELSE
                '  author_contact_method: ' || NEW.author_contact_method || x'0A'
            END
        ||
            CASE WHEN
                NEW.author_shortname IS NULL
            THEN
                '  author_shortname: ~' || x'0A'
            WHEN
                NEW.author_shortname = '-'
            THEN
                '  author_shortname: ''-''' || x'0A'
            WHEN
                instr(NEW.author_shortname, x'0A') OR
                instr(NEW.author_shortname, '\\')
            THEN
                '  author_shortname: "'
                || REPLACE(
                      REPLACE(
                        REPLACE(NEW.author_shortname, '\\', '\\\\'),
                        x'0A', '\n'), '"', '\"')
                || '"' || x'0A'
            WHEN
                instr(NEW.author_shortname, ' ') OR
                NEW.author_shortname = '' -- not at all sufficient
            THEN
                '  author_shortname: ''' || NEW.author_shortname || '''' || x'0A'
            ELSE
                '  author_shortname: ' || NEW.author_shortname || x'0A'
            END
        || '  lang: ' || NEW.lang || x'0A'
        || '  mtime: ' || COALESCE(NEW.mtime, strftime('%s','now')) || x'0A'
        || '  mtimetz: '
        || COALESCE(NEW.mtimetz,
            strftime('%s','now','localtime') - strftime('%s','now'))
        || x'0A'
        || '  parent_uuid: ' || COALESCE(p.uuid,'~') || x'0A'
    FROM
        (SELECT 1)
    LEFT JOIN
        changes p
    ON
        p.id = NEW.parent_id
    ;

    SELECT RAISE(IGNORE);
END;
