const std = @import("std");
const rl = @import("raylib");
const rg = @import("raygui");
const pr = @import("primitives.zig");

var prng = std.rand.DefaultPrng.init(124346556);


const rand = prng.random();

fn randMinMaxFloat(min:f32,max:f32) f32 {
    var r1 = rand.float(f32);
    r1 = 2*(r1 - 0.5);//-0.5..0.5
    return (@abs(min)+@abs(max))/2 * r1;
}

test "random" {
    var seed:u64 = undefined;
    var r1 :f32 = undefined;
    try std.posix.getrandom(std.mem.asBytes(&seed));

    prng = std.rand.DefaultPrng.init(seed);
    while(true) {
        r1 = randMinMaxFloat(-10,10);
        //std.debug.print("randMinMaxFloat:{}\n",.{r1});
        if (r1 > 8 or r1 < -8 ) {
            std.debug.print("Greater:{}\n",.{r1});
        }
    }
}
    const screenWidth = 800;
    const screenHeight = 450;

const Particle = struct {
    const Self = @This();
    position : pr.Vec = .{.a = .{.x=0,.y=0,.z=0}},
    velocity : pr.Vec = .{.a = .{.x=0,.y=0,.z=0}},
    acceleration : pr.Vec = .{.a = .{.x=0,.y=0,.z=0}},
    lifespan : u8 = 0,
    pub fn new(self:Self) void {
        _ = self;
    }
    pub fn update(self:*Self) void {
        self.velocity.add(self.acceleration);
        self.position.add(self.velocity);

        if (self.lifespan > 0) {
            self.lifespan -= 1;
        } else {
            const xrnr = randMinMaxFloat(-1,1);
            const yrnr = randMinMaxFloat(-0.5,0.5);

            self.lifespan = rand.intRangeAtMost(u8,1,100);
            self.acceleration.a.x = xrnr;
            self.acceleration.a.y = yrnr;
            self.position.a.x = @floatFromInt(rl.getMouseX()-screenWidth/2);
            self.position.a.y = @floatFromInt(rl.getMouseY()-screenHeight/2);
            self.velocity.a.x = 0;
            self.velocity.a.y = -20;
            self.position.a.color.r = rand.intRangeAtMost(u8,0,255);
            self.position.a.color.g = rand.intRangeAtMost(u8,0,255);
            self.position.a.color.b = rand.intRangeAtMost(u8,0,255);
        }
    }
    pub fn applyGravity(self : *Self,val : f32) void {
        self.velocity.a.y += val;
    }
};

pub fn main() anyerror!void {
    // Initialization
    //--------------------------------------------------------------------------------------

    const rect2 = rl.Rectangle{ .x = @as(f32, @floatFromInt(10)), .y = @as(f32, @floatFromInt(10)), .width = @as(f32, @floatFromInt(300)), .height = @as(f32, @floatFromInt(100)) };
    var msg_res : i32=-1;
    var state : i32=-1;
    
    var seed:u64 = undefined;
    try std.posix.getrandom(std.mem.asBytes(&seed));

    prng = std.rand.DefaultPrng.init(seed);
    var xrnr : f32 = 0;
    var yrnr : f32 = 0;

    var posx : i32 = 0;
    var posy : i32 = 0;

    var p1 : [1000]Particle = undefined;
    for (&p1) |*p| {
        xrnr = rand.float(f32);
        yrnr = rand.float(f32);
        p.* = Particle{.velocity = .{.a = .{.x = 1,.y = -3}},.acceleration = .{.a = .{.x=xrnr,.y=yrnr}}};
    }

    const img : rl.Texture = rl.loadTexture("img.png");

    rl.initWindow(screenWidth, screenHeight, "raylib-zig [core] example - basic window");
    defer rl.closeWindow(); // Close window and OpenGL context

    rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second

    while (!rl.windowShouldClose()) { // Detect window close button or ESC key
        rl.beginDrawing();
        defer rl.endDrawing();

        rl.clearBackground(rl.Color{.r=181,
                                    .g =177,
                                    .b =154,
                                    .a = 255,
        });

        if(state != 0){ 
            msg_res = rg.guiMessageBox(rect2, "Title", "question?", "Nice;Cool");
            if(msg_res > -1){
                state = msg_res;
            }
            rl.clearBackground(rl.Color.white);
            switch(state){
                1 => {
                        rl.drawText("1", 190, 200, 20, rl.Color.red);
                },
                2 => {
                        rl.drawText("2", 190, 200, 20, rl.Color.red);
                },
                    else =>{},
            }
        }
        for (&p1) |*p| {
            p.update();
            p.applyGravity(2);
            if(p.position.a.x >= -(screenWidth/2)){
                posx = @intFromFloat(screenWidth / 2 + p.position.a.x);
            } else {
                posx  = 0;
            }
            if(p.position.a.y >= -(screenHeight/2)){
                posy = @intFromFloat(screenHeight / 2 + p.position.a.y);
            } else {
                posy = 0;
            }
            rl.drawCircle(posx,posy,5,rl.Color{.r=p.position.a.color.r,.g=p.position.a.color.g,.b=p.position.a.color.b,.a=255});
        }


    }
}

test "simple test" {
    var list = std.ArrayList(i32).init(std.testing.allocator);
    defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
    try list.append(42);
    try std.testing.expectEqual(@as(i32, 42), list.pop());
}
