// File: nishalkulkarni[P]fluid-wm/fluid_wm.cpp
// Function: WindowManager::Frame(unsigned long, bool)
void WindowManager::Frame(Window w, bool was_created_before_window_manager)
{
    assert(!clients_.count(w));

    XWindowAttributes x_window_attrs;
    assert(XGetWindowAttributes(display_, w, &x_window_attrs));

    if (was_created_before_window_manager) {
        if (x_window_attrs.override_redirect || x_window_attrs.map_state != IsViewable) {
            return;
        }
    }

    Node* parent_window;
    Node* new_window;
    if (clients_.size() == 0) {
        Window returned_root;
        int root_x, root_y;
        unsigned root_width, root_height, root_border_width, root_depth;

        assert(XGetGeometry(
            display_,
            root_,
            &returned_root,
            &root_x, &root_y,
            &root_width, &root_height,
            &root_border_width,
            &root_depth));

        std::tie(parent_window, new_window) = bsp->init_root(w, root_width, root_height, root_x, root_y);
    } else {
        std::tie(parent_window, new_window) = bsp->create_node(w);
    }

    int window_width, window_height, window_x, window_y;
    std::tie(window_width, window_height, window_x, window_y) = new_window->get_dimensions();
    std::cout << "\n\nhello" << window_width << " 0 " << window_height << "\n";
    std::cout << "bye" << window_x << " 0 " << window_y << "\n\n";

    bsp->display_tree();

    if (parent_window != nullptr) {
        int parent_width, parent_height, parent_x, parent_y;
        std::tie(parent_width, parent_height, parent_x, parent_y) = parent_window->get_dimensions();
        XResizeWindow(
            display_,
            clients_[parent_window->get_window()],
            parent_width - 2 * (BORDER_WIDTH + GAP), parent_height - 2 * (BORDER_WIDTH + GAP));
        XResizeWindow(
            display_,
            parent_window->get_window(),
            parent_width - 2 * (BORDER_WIDTH + GAP), parent_height - 2 * (BORDER_WIDTH + GAP));
    }

    XResizeWindow(
        display_,
        w,
        window_width - 2 * (BORDER_WIDTH + GAP), window_height - 2 * (BORDER_WIDTH + GAP));

    const Window frame = XCreateSimpleWindow(
        display_,
        root_,
        window_x + GAP,
        window_y + GAP,
        window_width - 2 * (BORDER_WIDTH + GAP),
        window_height - 2 * (BORDER_WIDTH + GAP),
        BORDER_WIDTH,
        BORDER_ACTIVE_COLOR,
        BG_COLOR);

    XSelectInput(
        display_,
        frame,
        SubstructureRedirectMask | SubstructureNotifyMask);

    XAddToSaveSet(display_, w);

    XReparentWindow(
        display_,
        w,
        frame,
        0, 0);

    XMapWindow(display_, frame);

    clients_[w] = frame;
    std::cout << " Map size " << clients_.size() << std::endl;
    for (auto i : clients_) {
        std::cout << i.first << " " << i.second << std::endl;
    }

    XSync(display_,false);
    //   Kill windows with alt + f4.
    XGrabKey(
        display_,
        XKeysymToKeycode(display_, XK_F4),
        MODKEY,
        w,
        false,
        GrabModeAsync,
        GrabModeAsync);
    //   Switch windows with alt + tab.
    XGrabKey(
        display_,
        XKeysymToKeycode(display_, XK_Tab),
        MODKEY,
        w,
        false,
        GrabModeAsync,
        GrabModeAsync);

    std::cout << "Framed window " << w << " [" << frame << "]\n\n";
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x1d0(%rbp)
addq $0x10, %rdi
leaq -0x10(%rbp), %rsi
callq 0x13200
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x11fd1
jmp 0x11fd3
jmp 0x11ff2
leaq 0x5c92(%rip), %rdi      # 0x17c6c
leaq 0x5c2e(%rip), %rsi      # 0x17c0f
movl $0x82, %edx
leaq 0x5c92(%rip), %rcx      # 0x17c7f
callq 0x4170
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0x44e0
cmpl $0x0, %eax
je 0x12013
jmp 0x12032
leaq 0x5c8d(%rip), %rdi      # 0x17ca7
leaq 0x5bee(%rip), %rsi      # 0x17c0f
movl $0x85, %edx
leaq 0x5c52(%rip), %rcx      # 0x17c7f
callq 0x4170
testb $0x1, -0x11(%rbp)
je 0x1204b
cmpl $0x0, -0x28(%rbp)
jne 0x12044
cmpl $0x2, -0x44(%rbp)
je 0x12049
jmp 0x12688
jmp 0x1204b
movq -0x1d0(%rbp), %rdi
addq $0x10, %rdi
callq 0x13230
cmpq $0x0, %rax
jne 0x12144
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
leaq -0xb8(%rbp), %rdx
leaq -0xbc(%rbp), %rcx
leaq -0xc0(%rbp), %r8
leaq -0xc4(%rbp), %r9
leaq -0xc8(%rbp), %r11
leaq -0xcc(%rbp), %r10
leaq -0xd0(%rbp), %rax
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x4410
cmpl $0x0, %eax
je 0x120be
jmp 0x120dd
leaq 0x5c15(%rip), %rdi      # 0x17cda
leaq 0x5b43(%rip), %rsi      # 0x17c0f
movl $0x9b, %edx
leaq 0x5ba7(%rip), %rcx      # 0x17c7f
callq 0x4170
movq -0x1d0(%rbp), %rax
movq 0x48(%rax), %rsi
movq -0x10(%rbp), %rdx
movl -0xc4(%rbp), %ecx
movl -0xc8(%rbp), %r8d
movl -0xbc(%rbp), %r9d
movl -0xc0(%rbp), %eax
leaq -0xe0(%rbp), %rdi
movl %eax, (%rsp)
callq 0xc2c0
leaq -0xf0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
callq 0xccd0
leaq -0xf0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0xcd10
jmp 0x1218c
movq -0x1d0(%rbp), %rax
movq 0x48(%rax), %rsi
movq -0x10(%rbp), %rdx
leaq -0x100(%rbp), %rdi
callq 0xc4a0
leaq -0x110(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
callq 0xccd0
leaq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xcd10
movq -0xb0(%rbp), %rsi
leaq -0x130(%rbp), %rdi
callq 0xbf30
leaq -0x150(%rbp), %rdi
leaq -0x114(%rbp), %rsi
leaq -0x118(%rbp), %rdx
leaq -0x11c(%rbp), %rcx
leaq -0x120(%rbp), %r8
callq 0x13250
leaq -0x150(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x132a0
movq 0x10def(%rip), %rdi     # 0x22fd0
leaq 0x5b6f(%rip), %rsi      # 0x17d57
callq 0x4240
movq %rax, %rdi
movl -0x114(%rbp), %esi
callq 0x4490
movq %rax, %rdi
leaq 0x5b5a(%rip), %rsi      # 0x17d5f
callq 0x4240
movq %rax, %rdi
movl -0x118(%rbp), %esi
callq 0x4490
movq %rax, %rdi
leaq 0x5d21(%rip), %rsi      # 0x17f43
callq 0x4240
movq 0x10da2(%rip), %rdi     # 0x22fd0
leaq 0x5b2e(%rip), %rsi      # 0x17d63
callq 0x4240
movq %rax, %rdi
movl -0x11c(%rbp), %esi
callq 0x4490
movq %rax, %rdi
leaq 0x5b0d(%rip), %rsi      # 0x17d5f
callq 0x4240
movq %rax, %rdi
movl -0x120(%rbp), %esi
callq 0x4490
movq %rax, %rdi
leaq 0x5cd3(%rip), %rsi      # 0x17f42
callq 0x4240
movq -0x1d0(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0xca90
cmpq $0x0, -0xa8(%rbp)
je 0x12381
movq -0xa8(%rbp), %rsi
leaq -0x170(%rbp), %rdi
callq 0xbf30
leaq -0x190(%rbp), %rdi
leaq -0x154(%rbp), %rsi
leaq -0x158(%rbp), %rdx
leaq -0x15c(%rbp), %rcx
leaq -0x160(%rbp), %r8
callq 0x13250
leaq -0x190(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x132a0
movq -0x1d0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x1e0(%rbp)
addq $0x10, %rax
movq %rax, -0x1e8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0xbf70
movq -0x1e8(%rbp), %rdi
movq %rax, -0x198(%rbp)
leaq -0x198(%rbp), %rsi
callq 0x132e0
movq -0x1e0(%rbp), %rdi
movq (%rax), %rsi
movl -0x154(%rbp), %edx
subl $0xe, %edx
movl -0x158(%rbp), %ecx
subl $0xe, %ecx
callq 0x4400
movq -0x1d0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1d8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0xbf70
movq -0x1d8(%rbp), %rdi
movq %rax, %rsi
movl -0x154(%rbp), %edx
subl $0xe, %edx
movl -0x158(%rbp), %ecx
subl $0xe, %ecx
callq 0x4400
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x114(%rbp), %edx
subl $0xe, %edx
movl -0x118(%rbp), %ecx
subl $0xe, %ecx
callq 0x4400
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
movl -0x11c(%rbp), %edx
addl $0x5, %edx
movl -0x120(%rbp), %ecx
addl $0x5, %ecx
movl -0x114(%rbp), %r8d
subl $0xe, %r8d
movl -0x118(%rbp), %r9d
subl $0xe, %r9d
movl $0x2, (%rsp)
movq $0x81a1c1, 0x8(%rsp)    # imm = 0x81A1C1
movq $0x2e3440, 0x10(%rsp)   # imm = 0x2E3440
callq 0x4090
movq %rax, %rcx
movq -0x1d0(%rbp), %rax
movq %rcx, -0x1a0(%rbp)
movq (%rax), %rdi
movq -0x1a0(%rbp), %rsi
movl $0x180000, %edx         # imm = 0x180000
callq 0x4160
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x4360
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
movq -0x1a0(%rbp), %rdx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0x4030
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
movq -0x1a0(%rbp), %rsi
callq 0x4300
movq -0x1d0(%rbp), %rdi
movq -0x1a0(%rbp), %rax
movq %rax, -0x1f8(%rbp)
addq $0x10, %rdi
leaq -0x10(%rbp), %rsi
callq 0x13310
movq -0x1f8(%rbp), %rcx
movq %rcx, (%rax)
movq 0x10b35(%rip), %rdi     # 0x22fd0
leaq 0x58c5(%rip), %rsi      # 0x17d67
callq 0x4240
movq -0x1d0(%rbp), %rdi
movq %rax, -0x1f0(%rbp)
addq $0x10, %rdi
callq 0x13230
movq -0x1f0(%rbp), %rdi
movq %rax, %rsi
callq 0x4050
movq %rax, %rdi
movq 0x10ae9(%rip), %rsi     # 0x22fc0
callq 0x4290
movq -0x1d0(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x1a8(%rbp)
movq -0x1a8(%rbp), %rdi
callq 0x13340
movq %rax, -0x1b0(%rbp)
movq -0x1a8(%rbp), %rdi
callq 0x13370
movq %rax, -0x1b8(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x133a0
testb $0x1, %al
jne 0x1252d
jmp 0x1259f
leaq -0x1b0(%rbp), %rdi
callq 0x133d0
movq (%rax), %rcx
movq %rcx, -0x1c8(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x1c0(%rbp)
movq -0x1c8(%rbp), %rsi
movq 0x10a74(%rip), %rdi     # 0x22fd0
callq 0x4050
movq %rax, %rdi
leaq 0x4d33(%rip), %rsi      # 0x1729e
callq 0x4240
movq %rax, %rdi
movq -0x1c0(%rbp), %rsi
callq 0x4050
movq %rax, %rdi
movq 0x10a37(%rip), %rsi     # 0x22fc0
callq 0x4290
leaq -0x1b0(%rbp), %rdi
callq 0x13400
jmp 0x12514
movq -0x1d0(%rbp), %rax
movq (%rax), %rdi
xorl %esi, %esi
callq 0x4520
movq -0x1d0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x208(%rbp)
movq (%rax), %rdi
movl $0xffc1, %esi           # imm = 0xFFC1
callq 0x4140
movq -0x208(%rbp), %rdi
movzbl %al, %esi
movq -0x10(%rbp), %rcx
movl $0x8, %edx
xorl %r8d, %r8d
movl $0x1, %r9d
movl $0x1, (%rsp)
callq 0x4230
movq -0x1d0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x200(%rbp)
movq (%rax), %rdi
movl $0xff09, %esi           # imm = 0xFF09
callq 0x4140
movq -0x200(%rbp), %rdi
movzbl %al, %esi
movq -0x10(%rbp), %rcx
movl $0x8, %edx
xorl %r8d, %r8d
movl $0x1, %r9d
movl $0x1, (%rsp)
callq 0x4230
movq 0x1098d(%rip), %rdi     # 0x22fd0
leaq 0x5728(%rip), %rsi      # 0x17d72
callq 0x4240
movq %rax, %rdi
movq -0x10(%rbp), %rsi
callq 0x4050
movq %rax, %rdi
leaq 0x57be(%rip), %rsi      # 0x17e23
callq 0x4240
movq %rax, %rdi
movq -0x1a0(%rbp), %rsi
callq 0x4050
movq %rax, %rdi
leaq 0x56fe(%rip), %rsi      # 0x17d81
callq 0x4240
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
nopw %cs:(%rax,%rax)