const rl = @import("raylib");
const Rect = rl.Rectangle;

pub const AlignX = enum { left, center, right };
pub const AlignY = enum { top, center, bottom };

pub fn initCentered(rect: Rect, width: f32, height: f32) Rect {
    const unused_width = rect.width - width;
    const unused_height = rect.height - height;
    return Rect.init(rect.x + unused_width / 2, rect.y + unused_height / 2, width, height);
}

pub fn center(rect: Rect) rl.Vector2 {
    return rl.Vector2{
        .x = rect.x + rect.width / 2,
        .y = rect.y + rect.height / 2,
    };
}

pub fn bottomLeft(rect: Rect) rl.Vector2 {
    return rl.Vector2{
        .x = rect.x,
        .y = rect.y + rect.height,
    };
}

pub fn bottomRight(rect: Rect) rl.Vector2 {
    return rl.Vector2{
        .x = rect.x + rect.width,
        .y = rect.y + rect.height,
    };
}

pub fn topLeft(rect: Rect) rl.Vector2 {
    return rl.Vector2{
        .x = rect.x,
        .y = rect.y,
    };
}

pub fn topRight(rect: Rect) rl.Vector2 {
    return rl.Vector2{
        .x = rect.x + rect.width,
        .y = rect.y,
    };
}

pub fn aligned(rect: Rect, align_x: AlignX, align_y: AlignY) rl.Vector2 {
    const x = switch(align_x) {
        .left   => rect.x,
        .center => rect.x + rect.width/2,
        .right  => rect.x + rect.width,
    };

    const y = switch(align_y) {
        .top    => rect.y,
        .center => rect.y + rect.height/2,
        .bottom => rect.y + rect.height,
    };

    return rl.Vector2.init(x, y);
}

pub fn shrink(rect: Rect, x: f32, y: f32) rl.Rectangle {
    return Rect.init(rect.x + x, rect.y + y, rect.width - 2 * x, rect.height - 2 * y);
}

pub fn shrinkX(rect: rl.Rectangle, offset: f32) rl.Rectangle {
    return shrink(rect, offset, 0);
}

pub fn shrinkY(rect: rl.Rectangle, offset: f32) rl.Rectangle {
    return shrink(rect, 0, offset);
}

pub fn shrinkTop(rect: rl.Rectangle, offset: f32) rl.Rectangle {
    return Rect.init(rect.x, rect.y + offset, rect.width, rect.height - offset);
}

pub fn grow(rect: Rect, x: f32, y: f32) rl.Rectangle {
    return shrink(rect, -x, -y);
}

pub fn growY(rect: Rect, offset: f32) rl.Rectangle {
    return grow(rect, 0, offset);
}

pub fn position(rect: rl.Rectangle) rl.Vector2 {
    return rl.Vector2.init(rect.x, rect.y);
}

pub fn isInside(rect: rl.Rectangle, x: f32, y: f32) bool {
    return (rect.x <= x and x < rect.x + rect.width) and (rect.y < y and y < rect.y + rect.height);
}

pub fn isInsideVec2(rect: rl.Rectangle, vec2: rl.Vector2) bool {
    return isInside(rect, vec2.x, vec2.y);
}

pub fn top(rect: rl.Rectangle) f32 {
    return rect.y;
}

pub fn bottom(rect: rl.Rectangle) f32 {
    return rect.y + rect.height;
}

pub fn left(rect: rl.Rectangle) f32 {
    return rect.x;
}

pub fn right(rect: rl.Rectangle) f32 {
    return rect.x + rect.width;
}

pub fn verticalSplit(rect: rl.Rectangle, left_side_width: f32) [2]rl.Rectangle {
    var left_side = rect;
    left_side.width = left_side_width;

    var right_side = rect;
    right_side.x += left_side_width;
    right_side.width -= left_side_width;

    return .{
        left_side,
        right_side
    };
}

pub fn horizontalSplit(rect: rl.Rectangle, top_side_height: f32) [2]rl.Rectangle {
    var top_side = rect;
    top_side.height = top_side_height;

    var bottom_side = rect;
    bottom_side.y += top_side_height;
    bottom_side.height -= top_side_height;

    return .{
        top_side,
        bottom_side
    };
}
