local screen_size = { 1920, 1080 };
local scale = 300;

local length_seconds = 10;
local updates = 100;
local spf = length_seconds / updates;

config:set_size(screen_size[1], screen_size[2])
config:set_background_color(Color(20, 20, 30))
config:set_fps(60)
config:set_num_layers(1)

local cubeCorners = {
    { -1.0, -1.0, -1.0 }, -- Point 0
    { 1.0,  -1.0, -1.0 }, -- Point 1
    { -1.0, -1.0, 1.0 },  -- Point 2
    { 1.0,  -1.0, 1.0 },  -- Point 3
    { -1.0, 1.0,  -1.0 }, -- Point 4
    { 1.0,  1.0,  -1.0 }, -- Point 5
    { -1.0, 1.0,  1.0 },  -- Point 6
    { 1.0,  1.0,  1.0 }   -- Point 7
};

local cubeLines = {
    { 0, 1 },
    { 0, 2 },
    { 1, 3 },
    { 2, 3 },
    { 0, 4 },
    { 1, 5 },
    { 2, 6 },
    { 3, 7 },
    { 4, 5 },
    { 4, 6 },
    { 5, 7 },
    { 6, 7 },
};

function rotatePoint(arr, rot)
    local x = arr[1];
    local y = arr[2];
    local z = arr[3];

    -- Rotate around x axis:
    local y1 = (y * math.cos(rot[1])) - (z * math.sin(rot[1]));
    local z1 = (z * math.cos(rot[1])) + (y * math.sin(rot[1]));

    -- Rotate around y axis:
    local x2 = (z1 * math.sin(rot[2])) + (x * math.cos(rot[2]));
    local z2 = (z1 * math.cos(rot[2])) - (x * math.sin(rot[2]));

    -- Rotate around z axis:
    local x3 = (x2 * math.cos(rot[3])) - (y1 * math.sin(rot[3]));
    local y3 = (x2 * math.sin(rot[3])) + (y1 * math.cos(rot[3]));

    return { x3, y3, z2 };
end

function renderLine(pos, line)
    local p1 = cubeCorners[line[1] + 1];
    local p2 = cubeCorners[line[2] + 1];
    local p1r = rotatePoint(p1, { pos[1], pos[2], pos[3] });
    local p2r = rotatePoint(p2, { pos[1], pos[2], pos[3] });

    local p1s = Point((scale * p1r[1]) + (screen_size[1] / 2), (scale * p1r[2]) + (screen_size[2] / 2))
    local p2s = Point((scale * p2r[1]) + (screen_size[1] / 2), (scale * p2r[2]) + (screen_size[2] / 2))

    return Line(p1s, p2s, Color(255, 255, 255), 2.0)
end

layer(0)

local speeds = { 0.2, 0.4, 0.6 }

local pos = { math.pi / 2, math.pi / 3, math.pi / 4 }

for i = 0, updates, 1 do
    local nextpos = { pos[1] + speeds[1], pos[2] + speeds[2], pos[3] + speeds[3] };

    for j, line in ipairs(cubeLines) do
        animate(Animation(
            renderLine(pos, line),
            renderLine(nextpos, line),
            spf, Linear()
        ))
    end

    pos = nextpos;

    render(spf)
end

-- function Block(x, y, i)
--     animate(Animation(
--         Rect(pos, size, Color(clr_start, clr_start, clr_start)),
--         Rect(pos, size, Color(clr_end, clr_end, clr_end)),
--         1.0,
--         Linear()
--     ))
-- end
