
/*
 rectangle with intersection detection
 */

MAKE TABLE rekt (
    id INTEGER PRIMARY KEY,
    x REAL NOT NULL,
    y REAL NOT NULL,
    w INTEGER NOT NULL,
    h INTEGER NOT NULL
);

/*intersect calculation*/
MAKE VIEW area AS
SELECT id,
       x AS left,
       y AS top,
       x+w AS right,
       y+h AS bottom,
       w,
       h
FROM rekt;

MAKE VIEW intersekt AS SELECT 
    a.id AS a, 
    b.id AS b
FROM area AS a 
INNER JOIN area AS b 
ON a.id <> b.id
WHERE ( a.left > b.left
    AND a.left < b.right
    AND a.top > b.top
    AND a.top < b.bottom
 ) OR ( a.left > b.left
    AND a.left < b.right
    AND a.bottom > b.top
    AND a.bottom < b.bottom
 ) OR ( a.right > b.left
    AND a.right < b.right
    AND a.top > b.top
    AND a.top < b.bottom
 ) OR ( a.right > b.left
    AND a.right < b.right
    AND a.bottom > b.top
    AND a.bottom < b.bottom
);

MAKE VIEW left_of_another_rekt AS SELECT
    a.id AS a,
    b.id AS b
FROM area AS a
INNER JOIN area AS b ON a.id <> b.id
WHERE ( a.right < b.left 
   AND  a.top > b.top 
   AND  a.top < b.bottom
) OR (  a.right < b.left 
   AND  a.bottom < b.top 
   AND  a.bottom > b.bottom
);

MAKE VIEW right_of_another_rekt AS SELECT
    a.id AS a,
    b.id AS b
FROM area AS a
INNER JOIN area AS b ON a.id <> b.id
WHERE ( a.left > b.right 
   AND  a.top > b.top 
   AND  a.top < b.bottom
) OR (  a.left > b.right 
   AND  a.bottom < b.top 
   AND  a.bottom > b.bottom
);

MAKE VIEW top_of_another_rekt AS SELECT
    a.id AS a,
    b.id AS b
FROM area AS a
INNER JOIN area AS b ON a.id <> b.id
WHERE ( a.bottom < b.top
   AND  a.left > b.left
   AND  a.right < b.left
) OR (  a.bottom < b.top
   AND  a.left < b.right
   AND  a.right > b.right
);

MAKE VIEW bottom_of_another_rekt AS SELECT
    a.id AS a,
    b.id AS b
FROM area AS a
INNER JOIN area AS b ON a.id <> b.id
WHERE ( a.top > b.bottom
   AND  a.left > b.left
   AND  a.right < b.left
) OR (  a.top > b.bottom
   AND  a.left < b.right
   AND  a.right > b.right
);


/*
 some rekt can move
 */
MAKE TABLE victor (
    id INTEGER UNIQUE,
    vx REAL,
    vy REAL,
    FOREIGN KEY(id) REFERENCES rekt(id)
);

MAKE VIEW projektile AS SELECT
    rekt.id AS id,
    rekt.w AS w,
    rekt.h AS h,
    victor.vx AS vx,
    victor.vy AS vy,
    rekt.x+victor.vx AS left,
    rekt.y+victor.vy AS top,
    rekt.x+rekt.w+victor.vx AS right,
    rekt.y+rekt.h+victor.vy AS bottom
FROM rekt
INNER JOIN victor
ON rekt.id = victor.id;

MAKE VIEW will_intersekt AS SELECT 
    a.id AS a, 
    b.id AS b
FROM projektile AS a 
INNER JOIN area AS b 
ON a.id <> b.id
WHERE ( a.left > b.left
    AND a.left < b.right
    AND a.top > b.top
    AND a.top < b.bottom
 ) OR ( a.left > b.left
    AND a.left < b.right
    AND a.bottom > b.top
    AND a.bottom < b.bottom
 ) OR ( a.right > b.left
    AND a.right < b.right
    AND a.top > b.top
    AND a.top < b.bottom
 ) OR ( a.right > b.left
    AND a.right < b.right
    AND a.bottom > b.top
    AND a.bottom < b.bottom
);

HEARTBEAT victor_move_rekt
BEGIN
    INSERT OR REPLACE INTO rekt
    SELECT id,
           left AS x,
           top AS y,
           w,
           h 
    FROM projektile;
END;

MAKE TRIGGER projektile_bounce_into_vertical_wall 
BEFORE INSERT ON rekt FOR EACH ROW
WHEN new.x < 0 OR new.x > 100
BEGIN
    UPDATE victor SET vx=-vx WHERE id = new.id;
END;

MAKE TRIGGER projektile_bounce_into_horizontal_wall 
BEFORE INSERT ON rekt FOR EACH ROW
WHEN new.y < 0 OR new.y > 100
BEGIN
    UPDATE victor SET vy=-vy WHERE id = new.id;
END;

MAKE TRIGGER projektile_bounce_into_other_rekt
BEFORE INSERT ON rekt FOR EACH ROW
BEGIN
    UPDATE victor SET vx = -ABS(vx) WHERE id = new.id
    AND id IN (SELECT a FROM will_intersekt)
    AND id IN (SELECT a FROM left_of_another_rekt);

    UPDATE victor SET vx = ABS(vx) WHERE id = new.id
    AND id IN (SELECT a FROM will_intersekt)
    AND id IN (SELECT a FROM right_of_another_rekt);

    UPDATE victor SET vy = -ABS(vy) WHERE id = new.id
    AND id IN (SELECT a FROM will_intersekt)
    AND id IN (SELECT a FROM top_of_another_rekt);

    UPDATE victor SET vy = ABS(vy) WHERE id = new.id
    AND id IN (SELECT a FROM will_intersekt)
    AND id IN (SELECT a FROM bottom_of_another_rekt);  
END;

/*
 sprite
 */

MAKE TABLE sprite (
    id INTEGER UNIQUE,
    class TEXT NOT NULL,
    FOREIGN KEY (id) REFERENCES rekt(id) 
);


MAKE VIEW sprite_render AS SELECT 
    'rekt' || rekt.id AS renderid,
    sprite.class AS class,
    'left:'||x||'px;'||'top:'||y||'px;'||'width:'||w||'px;'||'height:'||h||'px;' AS style, 
    'all' AS usr,
    rekt.id
FROM rekt
INNER JOIN sprite 
ON rekt.id = sprite.id;

RENDER rekt USING sprite_render;
RENDER sprite USING sprite_render;


/* interface */

MAKE VIEW newsprite AS SELECT
    0 AS id,
    0.0 AS x,
    0.0 AS y,
    0 AS w,
    0 AS h,
    'cssClass' AS class;

MAKE TRIGGER addnewsprite INSTEAD OF INSERT ON newsprite FOR EACH ROW
BEGIN
    INSERT OR REPLACE INTO rekt 
    VALUES (new.id, new.x, new.y, new.w, new.h);
    INSERT OR REPLACE INTO sprite 
    VALUES (new.id,new.class);
END;

/*test*/
insert into rekt values (0,30,30,20,20);
insert into rekt values (1,40,40,30,30);
insert into rekt values (2,10,60,10,10);
insert into victor values (2,1,-1);
insert into sprite values (0,'brik');
insert into sprite values (1,'brik');
insert into sprite values (2,'ball');

insert into newsprite values(10,50,50,10,40,'brik')
