v2 :: (x: float) -> Vector2 {
    return .{x, x};
}

v2 :: (x: s64) -> Vector2 {
    return .{xx x, xx x};
}

v3 :: (x: float, y: float, z: float) -> Vector3 {
    return .{x, y, z};
}

v3 :: (x: float) -> Vector3 {
    return .{x, x, x};
}

v3 :: (v: Vector2, a: float) -> Vector3 {
    return .{v.x, v.y, a};
}

v4 :: (x: float, y: float, z: float, w: float) -> Vector4 {
    return .{x, y, z, w};
}

v4 :: (v: Vector2) -> Vector4 {
    return .{v.x, v.y, 0.0, 0.0};
}

v4 :: (v: Vector3, f: float) -> Vector4 {
    return .{v.x, v.y, v.z, f};
}

v4 :: (x: float) -> Vector4 {
    return .{x, x, x, x};
}

orthographic_gl :: (left: float, right: float, bottom: float, top: float, near: float, far: float) -> Matrix4 {
    m : Matrix4;

    m._11 = 2.0 / (right - left);
    m._14 = -(right + left) / (right - left);

    m._22 = 2.0 / (top - bottom);
    m._24 = -(top + bottom) / (top - bottom);

    m._33 = -2.0 / (far - near);
    m._34 = -(far + near) / (far - near);

    m._44 = 1.0;

    return m;
}

vec2i :: struct {
    x : s32;
    y : s32;
}

operator == :: (a: vec2i, b: vec2i) -> bool {
    return a.x == b.x && a.y == b.y;
}

operator + :: (a: vec2i, b: vec2i) -> vec2i {
    return .{a.x + b.x, a.y + b.y};
}

operator - :: (a: vec2i, b: vec2i) -> vec2i {
    return .{a.x - b.x, a.y - b.y};
}

box :: struct {
    bottom_left : vec2i;
    top_right   : vec2i;
}

whbox :: struct {
    bottom_left : vec2i;
    size        : vec2i;
}

box_to_whbox :: (b: box) -> whbox {
    return whbox.{b.bottom_left, .{b.top_right.x - b.bottom_left.x, b.top_right.y - b.bottom_left.y}};
}

whbox_to_box :: (b: whbox) -> box {
    return box.{b.bottom_left, .{b.bottom_left.x + b.size.x, b.bottom_left.y + b.size.y}};
}

operator == :: (a: box, b: box) -> bool {
    return (a.bottom_left == b.bottom_left) && (a.top_right == b.top_right);
}

intersect :: (a: box, b: box) -> box {
    intersection := box.{.{max(a.bottom_left.x, b.bottom_left.x), max(a.bottom_left.y, b.bottom_left.y)},
                         .{min(a.top_right.x, b.top_right.x), min(a.top_right.y, b.top_right.y)}};
    if intersection.bottom_left.x < intersection.top_right.x && intersection.bottom_left.y < intersection.top_right.y {
        return intersection;
    } else {
        return .{};
    }
}
