// File: /workspace/github_cpp_makefile_star2_O2/4shadoww[P]xwinter/xwinter.cpp
// Function: main
int main(int argc, char** argv){
    // Settings
    unsigned int count = 200;
    float speed_x = 30.f;
    float speed_y = 30.f;
    std::string particle_color = "white";
    float random_x = 20.f;
    float random_y = 20.f;
    int x_spawn = 1;
    unsigned int size = 2;
    unsigned int random_size = 2;
    unsigned int fps = 144;

    // Chech is help asked to be printed
    if(argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)){
        print_usage(argv[0]);
        return 0;
    }
    // Chech is version asked to be printed
    if(argc > 1 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)){
        print_version();
        return 0;
    }

    // Check is argument count correct
    if(argc % 2 == 0 || argc == 2){
        std::cerr << "error: invalid argument count" << std::endl;
        return 1;
    }
    // Parse arguments
    for(int i = 1; i < argc - 1; i++){
        // Particle count
        if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--count") == 0){
            i++;
            count = std::stoul(argv[i]);
            continue;
        // Speed x
        }else if(strcmp(argv[i], "-sx") == 0 || strcmp(argv[i], "--speed-x") == 0){
            i++;
            speed_x = std::atof(argv[i]);
            continue;
        // Speed y
        }else if(strcmp(argv[i], "-sy") == 0 || strcmp(argv[i], "--speed-y") == 0){
            i++;
            speed_y = std::atof(argv[i]);
            continue;
        // Color
        }else if(strcmp(argv[i], "-cl") == 0 || strcmp(argv[i], "--color") == 0){
            i++;
            particle_color = argv[i];
            continue;
        // Random x
        }else if(strcmp(argv[i], "-rx") == 0 || strcmp(argv[i], "--random-x") == 0){
            i++;
            random_x = std::atof(argv[i]);
            continue;
        // Random y
        }else if(strcmp(argv[i], "-ry") == 0 || strcmp(argv[i], "--random-y") == 0){
            i++;
            random_y = std::atof(argv[i]);
            continue;
        // Spawn y
        }else if(strcmp(argv[i], "-xs") == 0 || strcmp(argv[i], "--x-spawn") == 0){
            i++;
            x_spawn = std::atoi(argv[i]);
            continue;
        // Size
        }else if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--size") == 0){
            i++;
            size = std::stoul(argv[i]);
            continue;
        // Random size
        }else if(strcmp(argv[i], "-rs") == 0 || strcmp(argv[i], "--random-size") == 0){
            i++;
            random_size = std::stoul(argv[i]);
            continue;
        // Framerate
        }else if(strcmp(argv[i], "-fps") == 0 || strcmp(argv[i], "--frame-rate") == 0){
            i++;
            fps = std::stoul(argv[i]);
            continue;
        }else{
            std::cerr << "error: unknown argument \"" << argv[i] << "\"" << std::endl;
            return 1;
        }
    }

    // Tick
    float tick = 1000 / fps;

    // Print license
    print_copyright();

    // Init xorg
    Display* display = XOpenDisplay (NULL);
    Window defaultroot = DefaultRootWindow(display);
    XVisualInfo vinfo;
    XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo);
    Screen* screen = XDefaultScreenOfDisplay(display);
    int screen_num = DefaultScreen(display);
    GC gc;
    XColor xcolor;

    // Get screen width and heigth
    int width = XWidthOfScreen(screen);
    int height = XHeightOfScreen(screen);
    // Set window attributes
    XSetWindowAttributes attr;
    attr.override_redirect = 1;
    attr.colormap = XCreateColormap(display, defaultroot, vinfo.visual, AllocNone);
    attr.border_pixel = 0;
    attr.background_pixel = 0;
    // Create window
    Window window = XCreateWindow(display, defaultroot, 0, 0, width, height, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect, &attr);

    // Event listener
    XSelectInput(display, defaultroot, ExposureMask | StructureNotifyMask);

    // Move window to background
    XLowerWindow(display, window);

    XMapWindow(display, window);
    XMapWindow(display, defaultroot);
    // Graphics context
    gc = XCreateGC(display, window, 0, 0);

    // Create the color
    if(particle_color == "red"){
        xcolor.red = 65535; xcolor.green = 0; xcolor.blue = 0;
    }else if(particle_color == "blue"){
        xcolor.red = 0; xcolor.green = 0; xcolor.blue = 65535;
    }else if(particle_color == "green"){
        xcolor.red = 0; xcolor.green = 65535; xcolor.blue = 0;
    }else{
        xcolor.red = 65535; xcolor.green = 65535; xcolor.blue = 65535;
    }
    xcolor.flags = DoRed | DoGreen | DoBlue;
    XAllocColor(display, DefaultColormap(display, screen_num), &xcolor);

    // Set snow color
    XSetForeground(display, gc, xcolor.pixel);
    // Flush
    XFlush(display);

    // Create sky
    sky skyen(width, height);
    skyen.set_count(count);
    skyen.set_speed(speed_x, speed_x + random_x, speed_y, speed_y + random_y);
    skyen.set_x_spawn_intensity(x_spawn);
    skyen.set_size(size, size + random_size);
    skyen.create_sky();

    while(true){
        // Events
        XEvent e;
        XCheckMaskEvent(display, ExposureMask | StructureNotifyMask, &e);
        // Resize window
        if (e.type == ConfigureNotify){
            XConfigureEvent xce = e.xconfigure;

            if(width != xce.width || height != xce.height){
                width = xce.width;
                height = xce.height;

                skyen.set_screen_size(width, height);
                XResizeWindow(display, window, width, height);
            }
        }
        // Draw
        XFillRectangles(display, window, gc, skyen.snowflakes, count);
        XFlush(display);
        XClearWindow(display, window);
        // Update sky
        skyen.update(tick);
        usleep(1000000 / fps);
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2988, %rsp           # imm = 0x2988
movq %rsi, %rbp
movl %edi, %r13d
leaq 0x19d9(%rip), %rsi      # 0x448e
leaq 0x88(%rsp), %rdi
leaq 0x238(%rsp), %rdx
callq 0x336a
cmpl $0x2, %r13d
movq %rbp, 0x38(%rsp)
jl 0x2b3b
movq 0x8(%rbp), %rbx
movb (%rbx), %bpl
cmpb $0x2d, %bpl
jne 0x2af2
cmpb $0x68, 0x1(%rbx)
jne 0x2af2
cmpb $0x0, 0x2(%rbx)
je 0x2f6f
leaq 0x199b(%rip), %rsi      # 0x4494
movq %rbx, %rdi
callq 0x2250
testl %eax, %eax
je 0x2f6f
cmpb $0x2d, %bpl
movq 0x38(%rsp), %rbp
jne 0x2b24
cmpb $0x76, 0x1(%rbx)
jne 0x2b24
cmpb $0x0, 0x2(%rbx)
je 0x2faa
leaq 0x1970(%rip), %rsi      # 0x449b
movq %rbx, %rdi
callq 0x2250
testl %eax, %eax
je 0x2faa
testb $0x1, %r13b
jne 0x2b61
movq 0x44a8(%rip), %rdi      # 0x6ff0
leaq 0x1956(%rip), %rsi      # 0x44a5
callq 0x21a0
movq %rax, %rdi
callq 0x20d0
jmp 0x2f6a
pushq $0x1
popq %r15
decl %r13d
movl $0xc8, %eax
movq %rax, 0x70(%rsp)
movss 0x14b2(%rip), %xmm1     # 0x402c
movss 0x14ae(%rip), %xmm0     # 0x4030
movl $0x90, %eax
movq %rax, 0x68(%rsp)
pushq $0x2
popq %rax
leaq 0x238(%rsp), %rbx
movss %xmm0, 0x48(%rsp)
movss %xmm0, 0x4c(%rsp)
movss %xmm1, 0x50(%rsp)
movss %xmm1, 0x54(%rsp)
movq %rax, 0x80(%rsp)
movq %rax, 0x78(%rsp)
movl %r15d, 0x44(%rsp)
cmpl %r13d, %r15d
jge 0x2fd2
movq %rbx, %r14
movslq %r15d, %r12
movq (%rbp,%r12,8), %rbp
movb (%rbp), %bl
cmpb $0x2d, %bl
jne 0x2bed
cmpb $0x63, 0x1(%rbp)
jne 0x2bed
cmpb $0x0, 0x2(%rbp)
je 0x2dcd
movq %rbp, %rdi
leaq 0x18cc(%rip), %rsi      # 0x44c3
callq 0x2250
testl %eax, %eax
je 0x2dcd
movq %rbp, %rdi
leaq 0x18bd(%rip), %rsi      # 0x44cb
callq 0x2250
testl %eax, %eax
je 0x2e0c
movq %rbp, %rdi
leaq 0x18aa(%rip), %rsi      # 0x44cf
callq 0x2250
testl %eax, %eax
je 0x2e0c
movq %rbp, %rdi
leaq 0x189d(%rip), %rsi      # 0x44d9
callq 0x2250
testl %eax, %eax
je 0x2e2d
movq %rbp, %rdi
leaq 0x188a(%rip), %rsi      # 0x44dd
callq 0x2250
testl %eax, %eax
je 0x2e2d
movq %rbp, %rdi
leaq 0x187d(%rip), %rsi      # 0x44e7
callq 0x2250
testl %eax, %eax
je 0x2e4b
movq %rbp, %rdi
leaq 0x186a(%rip), %rsi      # 0x44eb
callq 0x2250
testl %eax, %eax
je 0x2e4b
movq %rbp, %rdi
leaq 0x185b(%rip), %rsi      # 0x44f3
callq 0x2250
testl %eax, %eax
je 0x2e67
movq %rbp, %rdi
leaq 0x1848(%rip), %rsi      # 0x44f7
callq 0x2250
testl %eax, %eax
je 0x2e67
movq %rbp, %rdi
leaq 0x183c(%rip), %rsi      # 0x4502
callq 0x2250
testl %eax, %eax
je 0x2e85
movq %rbp, %rdi
leaq 0x1829(%rip), %rsi      # 0x4506
callq 0x2250
testl %eax, %eax
je 0x2e85
movq %rbp, %rdi
leaq 0x181d(%rip), %rsi      # 0x4511
callq 0x2250
testl %eax, %eax
je 0x2ea3
movq %rbp, %rdi
leaq 0x180a(%rip), %rsi      # 0x4515
callq 0x2250
testl %eax, %eax
je 0x2ea3
cmpb $0x2d, %bl
jne 0x2d2d
cmpb $0x73, 0x1(%rbp)
jne 0x2d2d
cmpb $0x0, 0x2(%rbp)
je 0x2ec4
movq %rbp, %rdi
leaq 0x17e8(%rip), %rsi      # 0x451f
callq 0x2250
testl %eax, %eax
je 0x2ec4
movq %rbp, %rdi
leaq 0x17d8(%rip), %rsi      # 0x4526
callq 0x2250
testl %eax, %eax
je 0x2efb
movq %rbp, %rdi
leaq 0x17c5(%rip), %rsi      # 0x452a
callq 0x2250
testl %eax, %eax
je 0x2efb
movq %rbp, %rdi
leaq 0x17bc(%rip), %rsi      # 0x4538
callq 0x2250
testl %eax, %eax
je 0x2d9c
movq %rbp, %rdi
leaq 0x17ae(%rip), %rsi      # 0x453d
callq 0x2250
testl %eax, %eax
jne 0x2f2f
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rsi
movq %r14, %rbx
movq %r14, %rdi
leaq 0x108(%rsp), %rdx
callq 0x336a
movq %rbx, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x34f7
movq %rax, 0x68(%rsp)
jmp 0x2dfc
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rsi
movq %r14, %rbx
movq %r14, %rdi
leaq 0x108(%rsp), %rdx
callq 0x336a
movq %rbx, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x34f7
movq %rax, 0x70(%rsp)
incl %r15d
movq %rbx, %rdi
callq 0x2368
jmp 0x2ebc
incl %r15d
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rdi
callq 0x21d0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x54(%rsp)
jmp 0x2eb9
incl %r15d
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rdi
callq 0x21d0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x50(%rsp)
jmp 0x2eb9
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rsi
leaq 0x88(%rsp), %rdi
callq 0x2340
incl %r15d
jmp 0x2eb9
incl %r15d
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rdi
callq 0x21d0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x4c(%rsp)
jmp 0x2eb9
incl %r15d
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rdi
callq 0x21d0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x48(%rsp)
jmp 0x2eb9
incl %r15d
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rdi
callq 0x22c0
movl %eax, 0x44(%rsp)
movq %r14, %rbx
incl %r15d
jmp 0x2bc1
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rsi
movq %r14, %rbx
movq %r14, %rdi
leaq 0x108(%rsp), %rdx
callq 0x336a
movq %rbx, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x34f7
movq %rax, 0x80(%rsp)
jmp 0x2dfc
movq 0x38(%rsp), %rbp
movq 0x8(%rbp,%r12,8), %rsi
movq %r14, %rbx
movq %r14, %rdi
leaq 0x108(%rsp), %rdx
callq 0x336a
movq %rbx, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x34f7
movq %rax, 0x78(%rsp)
jmp 0x2dfc
movq 0x40ba(%rip), %rdi      # 0x6ff0
leaq 0x160d(%rip), %rsi      # 0x454a
callq 0x21a0
movq 0x38(%rsp), %rcx
movq (%rcx,%r12,8), %rsi
movq %rax, %rdi
callq 0x21a0
leaq 0x1608(%rip), %rsi      # 0x4562
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20d0
pushq $0x1
popq %rbx
jmp 0x2fb1
movq 0x38(%rsp), %rax
movq (%rax), %rsi
leaq 0xa8(%rsp), %rdi
leaq 0x238(%rsp), %rdx
callq 0x336a
leaq 0xa8(%rsp), %rdi
callq 0x29fd
leaq 0xa8(%rsp), %rdi
callq 0x2368
xorl %ebx, %ebx
jmp 0x2fb1
xorl %ebx, %ebx
callq 0x29d1
leaq 0x88(%rsp), %rdi
callq 0x2368
movl %ebx, %eax
addq $0x2988, %rsp           # imm = 0x2988
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x3e8, %eax            # imm = 0x3E8
xorl %edx, %edx
divl 0x68(%rsp)
movl %eax, %r13d
callq 0x298b
xorl %edi, %edi
callq 0x2220
movq %rax, %r14
movq 0xe8(%rax), %rax
movslq 0xe0(%r14), %rsi
movq %rsi, %rcx
shlq $0x7, %rcx
movq 0x10(%rax,%rcx), %r15
pushq $0x20
popq %rdx
pushq $0x4
popq %rcx
leaq 0xc8(%rsp), %r8
movq %r14, %rdi
callq 0x2200
movq %r14, %rdi
callq 0x2230
movq %rax, %r12
movslq 0xe0(%r14), %rbp
movq %rax, %rdi
callq 0x2320
movl %eax, %ebx
movq %r12, %rdi
callq 0x21c0
movl %eax, 0x40(%rsp)
movl $0x1, 0x220(%rsp)
movq 0xc8(%rsp), %rdx
movq %r14, %rdi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x2120
leaq 0x1c8(%rsp), %rcx
movq %rax, 0x60(%rcx)
andq $0x0, 0x18(%rcx)
andq $0x0, 0x8(%rcx)
movl 0xdc(%rsp), %eax
movq 0xc8(%rsp), %rdx
movq %rcx, 0x28(%rsp)
movq %rdx, 0x18(%rsp)
movl %eax, 0x8(%rsp)
andl $0x0, (%rsp)
movq $0x220a, 0x20(%rsp)     # imm = 0x220A
movl $0x1, 0x10(%rsp)
movq %r14, %rdi
movq %r15, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movl %ebx, %r8d
movl 0x40(%rsp), %r9d
callq 0x22b0
movq %rax, %r12
movl $0x28000, %edx          # imm = 0x28000
movq %r14, %rdi
movq %r15, %rsi
callq 0x2110
movq %r14, %rdi
movq %r12, %rsi
callq 0x22e0
movq %r14, %rdi
movq %r12, %rsi
callq 0x21b0
movq %r14, %rdi
movq %r15, %rsi
callq 0x21b0
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x20e0
movq %rax, %r15
leaq 0x1451(%rip), %rsi      # 0x4564
leaq 0x88(%rsp), %rdi
callq 0x3513
testb %al, %al
je 0x3134
movl $0xffff, 0x60(%rsp)     # imm = 0xFFFF
andw $0x0, 0x64(%rsp)
jmp 0x3180
leaq 0x142d(%rip), %rsi      # 0x4568
leaq 0x88(%rsp), %rdi
callq 0x3513
testb %al, %al
je 0x3153
andl $0x0, 0x60(%rsp)
jmp 0x317a
leaq 0x1413(%rip), %rsi      # 0x456d
leaq 0x88(%rsp), %rdi
callq 0x3513
testb %al, %al
je 0x3175
movl $0xffff0000, 0x60(%rsp) # imm = 0xFFFF0000
jmp 0x312c
orl $-0x1, 0x60(%rsp)
orw $-0x1, 0x64(%rsp)
leaq 0x58(%rsp), %rdx
movb $0x7, 0xe(%rdx)
movq 0xe8(%r14), %rax
shlq $0x7, %rbp
movq 0x50(%rax,%rbp), %rsi
movq %r14, %rdi
callq 0x2150
movq 0x58(%rsp), %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0x20a0
movq %r14, %rdi
callq 0x22a0
leaq 0x238(%rsp), %rdi
movl %ebx, %esi
movl 0x40(%rsp), %edx
callq 0x24cc
leaq 0x238(%rsp), %rdi
movq 0x70(%rsp), %rax
movl %eax, 0x8(%rdi)
movss 0x4c(%rsp), %xmm2
movss 0x54(%rsp), %xmm3
addss %xmm3, %xmm2
movss 0x48(%rsp), %xmm0
movss 0x50(%rsp), %xmm1
addss %xmm1, %xmm0
movss %xmm3, 0xc(%rdi)
movss %xmm2, 0x10(%rdi)
movss %xmm1, 0x14(%rdi)
movss %xmm0, 0x18(%rdi)
movl 0x44(%rsp), %eax
movl %eax, 0x1c(%rdi)
movq 0x80(%rsp), %rax
movq 0x78(%rsp), %rcx
addl %eax, %ecx
movl %eax, 0x20(%rdi)
movl %ecx, 0x24(%rdi)
callq 0x26f6
cvtsi2ss %r13d, %xmm0
movss %xmm0, 0x38(%rsp)
movl $0x28000, %esi          # imm = 0x28000
movq %r14, %rdi
leaq 0x108(%rsp), %rdx
callq 0x2210
cmpl $0x16, 0x108(%rsp)
jne 0x329f
movl 0x140(%rsp), %ebp
movl 0x144(%rsp), %r13d
movl %ebx, %eax
xorl %ebp, %eax
movl 0x40(%rsp), %ecx
xorl %r13d, %ecx
orl %eax, %ecx
je 0x329f
movl %ebp, 0x238(%rsp)
movl %r13d, 0x23c(%rsp)
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movl %r13d, %ecx
callq 0x2280
movl %ebp, %ebx
movl %r13d, 0x40(%rsp)
movq 0x2970(%rsp), %rcx
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rdx
movq 0x70(%rsp), %r8
callq 0x2060
movq %r14, %rdi
callq 0x22a0
movq %r14, %rdi
movq %r12, %rsi
callq 0x2190
leaq 0x238(%rsp), %rdi
movss 0x38(%rsp), %xmm0
callq 0x2830
movl $0xf4240, %eax          # imm = 0xF4240
xorl %edx, %edx
divl 0x68(%rsp)
movl %eax, %edi
callq 0x2260
jmp 0x323c
jmp 0x32fb
jmp 0x32fb
movq %rax, %rbx
leaq 0x238(%rsp), %rdi
callq 0x2570
jmp 0x3355
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
jmp 0x3349
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x333e
jmp 0x3352
jmp 0x333e
jmp 0x333e
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
jmp 0x3352
movq %rax, %rbx
leaq 0x238(%rsp), %rdi
callq 0x2368
jmp 0x3355
jmp 0x3352
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x2368
movq %rbx, %rdi
callq 0x2300