// File: dmarto[P]crrs-xlib/main.cpp
// Function: main
int main()
{
	const int W = 300;
	const int H = 300;

	//
	Display *display = XOpenDisplay(NULL);
	Window rWin = XDefaultRootWindow(display);

	Window win = XCreateSimpleWindow(display, rWin, 0, 0, W, H, 0, 0, 0);

	XStoreName(display, win, "Ray Tracer");

	unsigned long eventmask = PointerMotionMask | ButtonPressMask;
	XSelectInput(display, win, eventmask);

	XMapWindow(display, win);

	// TODO: render style
	GC render = XCreateGC(display, win, 0, NULL);
	XSync(display, False);

	// WORLD

	Colors color;

	Sphere sphere(Vec3(W * 0.5, H * 0.5, 40), 30, color.white);
	Sphere sphere1(Vec3(W * 0.3, H * 0.5, 20), 15, color.red);
	Sphere sphere2(Vec3(W * 0.25, H * 0.35, 30), 20, color.green);
	Sphere sphere3(Vec3(W * 0.85, H * 0.65, 40), 35, color.blue);

	Vec3 worldColor = Vec3(94, 0, 182);
	Sphere world(Vec3(W * 0.5, H * 3.8, 650), 1100, worldColor, "world");

	Sphere light(Vec3(W * 0.1, H * 0.5, 0), 40, color.white);

	std::vector<Sphere *> objList = {&world, &sphere, &sphere1, &sphere2, &sphere3};

	double theta = 0.0;

	std::vector<Vec3> background;
	for (int y = 0; y < H * 2; ++y)
		for (int x = 0; x < W * 2; ++x)
			background.emplace_back(Vec3(122, 11, 133) - (x + y) / 5);

	// WORLD LOOP

	XEvent event;
	while (1)
	{
		if (!XCheckMaskEvent(display, eventmask, &event))
			event.type = 0;

		HandleEvents(event, light, world);

		for (int y = 0; y < H; ++y)
			for (int x = 0; x < W; ++x)
			{
				ScreenData scrnData = {color, x, y, light, objList};
				Vec3 pixclr = RenderPixel(scrnData);
				ColorBoundary(pixclr);

				XSetForeground(display, render, _RGB((int)pixclr.x, (int)pixclr.y, (int)pixclr.z));
				XDrawPoint(display, win, render, x, y);
			}

		int startIdx = 1;
		objList[startIdx]->center.x = (W >> 1) + (W / 6) * sin(theta);
		objList[startIdx]->center.y = H / 2.8 + (H / 6) * cos(theta / 2);
		objList[startIdx + 1]->center.x = objList[startIdx + 1]->center.x + 2 * sin(theta);
		objList[startIdx + 1]->center.y = objList[startIdx + 1]->center.y + 2 * cos(theta);
		objList[startIdx + 2]->center.y = objList[startIdx + 2]->center.y + 2 * sin(theta);
		objList[startIdx + 3]->center.y = objList[startIdx + 3]->center.y + 2 * -sin(theta);
		// objList[startIdx + 3]->center.z = 50 + 10 * sin(theta);

		theta += 0.1;

		XFlush(display);
		XSync(display, False);
	}

	XCloseDisplay(display);
	return 0;
}

// Assembly:
subq $0x648, %rsp            # imm = 0x648
movl $0x0, 0x644(%rsp)
movl $0x12c, 0x640(%rsp) # imm = 0x12C
movl $0x12c, 0x63c(%rsp) # imm = 0x12C
xorl %eax, %eax
movl %eax, 0xbc(%rsp)
movl %eax, %edi
movq %rdi, 0xb0(%rsp)
callq 0x2210
movq %rax, 0x630(%rsp)
movq 0x630(%rsp), %rdi
callq 0x2230
movl 0xbc(%rsp), %ecx
movq %rax, 0x628(%rsp)
movq 0x630(%rsp), %rdi
movq 0x628(%rsp), %rsi
movq %rsp, %rax
movq $0x0, 0x10(%rax)
movq $0x0, 0x8(%rax)
movl $0x0, (%rax)
movl $0x12c, %r9d            # imm = 0x12C
movl %ecx, %edx
movl %r9d, %r8d
callq 0x2080
movq %rax, 0x620(%rsp)
movq 0x630(%rsp), %rdi
movq 0x620(%rsp), %rsi
leaq 0x2ff2(%rip), %rdx      # 0x612e
callq 0x2050
movq $0x44, 0x618(%rsp)
movq 0x630(%rsp), %rdi
movq 0x620(%rsp), %rsi
movq 0x618(%rsp), %rdx
callq 0x2110
movq 0x630(%rsp), %rdi
movq 0x620(%rsp), %rsi
callq 0x21e0
movq 0xb0(%rsp), %rcx
movq 0x630(%rsp), %rdi
movq 0x620(%rsp), %rsi
movq %rcx, %rdx
callq 0x20f0
movl 0xbc(%rsp), %esi
movq %rax, 0x610(%rsp)
movq 0x630(%rsp), %rdi
callq 0x22c0
leaq 0x580(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
callq 0x3bd0
leaq 0x510(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
movsd 0x2ea0(%rip), %xmm1     # 0x6088
movsd %xmm1, 0xd0(%rsp)
movsd 0x2e1f(%rip), %xmm2     # 0x6018
movaps %xmm1, %xmm0
callq 0x4330
movq 0xc0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
leaq 0x528(%rsp), %rdi
movsd 0x2e4f(%rip), %xmm0     # 0x6070
callq 0x4370
movsd 0xd0(%rsp), %xmm1
leaq 0x4a0(%rsp), %rdi
movsd 0x2e51(%rip), %xmm0     # 0x6090
movsd 0x2e51(%rip), %xmm2     # 0x6098
callq 0x4330
jmp 0x324e
leaq 0x5c8(%rsp), %rdx
leaq 0x4b8(%rsp), %rdi
leaq 0x4a0(%rsp), %rsi
movsd 0x2e32(%rip), %xmm0     # 0x60a0
callq 0x4370
jmp 0x3275
leaq 0x420(%rsp), %rdi
movsd 0x2e23(%rip), %xmm0     # 0x60a8
movsd 0x2e23(%rip), %xmm1     # 0x60b0
movsd 0x2ddb(%rip), %xmm2     # 0x6070
callq 0x4330
jmp 0x329c
leaq 0x5e0(%rsp), %rdx
leaq 0x438(%rsp), %rdi
leaq 0x420(%rsp), %rsi
movsd 0x2ddc(%rip), %xmm0     # 0x6098
callq 0x4370
jmp 0x32c3
leaq 0x3b0(%rsp), %rdi
movsd 0x2d35(%rip), %xmm0     # 0x6008
movsd 0x2ddd(%rip), %xmm1     # 0x60b8
movsd 0x2d35(%rip), %xmm2     # 0x6018
callq 0x4330
jmp 0x32ea
leaq 0x5f8(%rsp), %rdx
leaq 0x3c8(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
movsd 0x2db6(%rip), %xmm0     # 0x60c0
callq 0x4370
jmp 0x3311
leaq 0x398(%rsp), %rdi
movsd 0x2da7(%rip), %xmm0     # 0x60c8
xorps %xmm1, %xmm1
movsd 0x2da4(%rip), %xmm2     # 0x60d0
callq 0x4330
jmp 0x3333
leaq 0x328(%rsp), %rdi
movsd 0x2d45(%rip), %xmm0     # 0x6088
movsd 0x2d8d(%rip), %xmm1     # 0x60d8
movsd 0x2d8d(%rip), %xmm2     # 0x60e0
callq 0x4330
jmp 0x335a
leaq 0x307(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
callq 0x2290
movq 0xa8(%rsp), %rdx
leaq 0x2daa(%rip), %rsi      # 0x6128
leaq 0x308(%rsp), %rdi
callq 0x43e0
jmp 0x338d
leaq 0x340(%rsp), %rdi
leaq 0x328(%rsp), %rsi
movsd 0x2d43(%rip), %xmm0     # 0x60e8
leaq 0x398(%rsp), %rdx
leaq 0x308(%rsp), %rcx
callq 0x44a0
jmp 0x33bc
leaq 0x308(%rsp), %rdi
callq 0x2100
leaq 0x307(%rsp), %rdi
callq 0x21b0
leaq 0x290(%rsp), %rdi
movsd 0x2c8a(%rip), %xmm0     # 0x6070
movsd 0x2c9a(%rip), %xmm1     # 0x6088
xorps %xmm2, %xmm2
callq 0x4330
jmp 0x33f8
leaq 0x2a8(%rsp), %rdi
leaq 0x290(%rsp), %rsi
movsd 0x2c08(%rip), %xmm0     # 0x6018
leaq 0x580(%rsp), %rdx
callq 0x4370
jmp 0x341f
leaq 0x340(%rsp), %rax
movq %rax, 0x240(%rsp)
leaq 0x528(%rsp), %rax
movq %rax, 0x248(%rsp)
leaq 0x4b8(%rsp), %rax
movq %rax, 0x250(%rsp)
leaq 0x438(%rsp), %rax
movq %rax, 0x258(%rsp)
leaq 0x3c8(%rsp), %rax
movq %rax, 0x260(%rsp)
leaq 0x240(%rsp), %rax
movq %rax, 0x268(%rsp)
movq $0x5, 0x270(%rsp)
leaq 0x23f(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x4520
movq 0xa0(%rsp), %rcx
movq 0x268(%rsp), %rsi
movq 0x270(%rsp), %rdx
leaq 0x278(%rsp), %rdi
callq 0x4530
jmp 0x34c7
leaq 0x23f(%rsp), %rdi
callq 0x45c0
xorps %xmm0, %xmm0
movsd %xmm0, 0x230(%rsp)
leaq 0x218(%rsp), %rdi
callq 0x45d0
movl $0x0, 0x214(%rsp)
cmpl $0x258, 0x214(%rsp) # imm = 0x258
jge 0x36f3
movl $0x0, 0x210(%rsp)
cmpl $0x258, 0x210(%rsp) # imm = 0x258
jge 0x36db
leaq 0x1e0(%rsp), %rdi
movsd 0x2bdb(%rip), %xmm0     # 0x6110
movsd 0x2bdb(%rip), %xmm1     # 0x6118
movsd 0x2bdb(%rip), %xmm2     # 0x6120
callq 0x4330
jmp 0x354c
movl 0x210(%rsp), %eax
movl 0x214(%rsp), %ecx
addl %ecx, %eax
cltq
imulq $0x66666667, %rax, %rax # imm = 0x66666667
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x21, %rax
addl %ecx, %eax
cvtsi2sd %eax, %xmm0
leaq 0x1f8(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x4660
jmp 0x358d
leaq 0x218(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x45e0
jmp 0x35a4
jmp 0x35a6
movl 0x210(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x210(%rsp)
jmp 0x3514
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3bb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3ba7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3b9a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3b8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3657
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x308(%rsp), %rdi
callq 0x2100
leaq 0x307(%rsp), %rdi
callq 0x21b0
jmp 0x3b8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3b80
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x23f(%rsp), %rdi
callq 0x45c0
jmp 0x3b73
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x218(%rsp), %rdi
callq 0x4700
leaq 0x278(%rsp), %rdi
callq 0x4760
jmp 0x3b73
jmp 0x36dd
movl 0x214(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x214(%rsp)
jmp 0x34f8
jmp 0x36f5
jmp 0x36f7
movq 0x630(%rsp), %rdi
movq 0x618(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0x2200
movl %eax, 0x9c(%rsp)
jmp 0x371d
movl 0x9c(%rsp), %eax
cmpl $0x0, %eax
jne 0x3734
movl $0x0, 0x120(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x2a8(%rsp), %rsi
leaq 0x340(%rsp), %rdx
callq 0x2f50
movl $0x0, 0x11c(%rsp)
cmpl $0x12c, 0x11c(%rsp) # imm = 0x12C
jge 0x38c0
movl $0x0, 0x118(%rsp)
cmpl $0x12c, 0x118(%rsp) # imm = 0x12C
jge 0x38a8
leaq 0x580(%rsp), %rax
movq %rax, 0xf8(%rsp)
movl 0x118(%rsp), %eax
movl %eax, 0x100(%rsp)
movl 0x11c(%rsp), %eax
movl %eax, 0x104(%rsp)
leaq 0x2a8(%rsp), %rax
movq %rax, 0x108(%rsp)
leaq 0x278(%rsp), %rax
movq %rax, 0x110(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x2e60
jmp 0x37ec
leaq 0xe0(%rsp), %rdi
callq 0x23e0
movq 0x630(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x610(%rsp), %rax
movq %rax, 0x88(%rsp)
cvttsd2si 0xe0(%rsp), %edi
cvttsd2si 0xe8(%rsp), %esi
cvttsd2si 0xf0(%rsp), %edx
callq 0x46b0
movq %rax, 0x90(%rsp)
jmp 0x3843
movq 0x90(%rsp), %rdx
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0x2090
jmp 0x3862
movq 0x630(%rsp), %rdi
movq 0x620(%rsp), %rsi
movq 0x610(%rsp), %rdx
movl 0x118(%rsp), %ecx
movl 0x11c(%rsp), %r8d
callq 0x2160
jmp 0x3890
jmp 0x3892
movl 0x118(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x118(%rsp)
jmp 0x3778
jmp 0x38aa
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x375c
movl $0x1, 0xdc(%rsp)
movsd 0x230(%rsp), %xmm0
callq 0x2040
movsd 0x280f(%rip), %xmm1     # 0x60f0
movsd %xmm1, 0x28(%rsp)
mulsd %xmm1, %xmm0
movsd 0x2795(%rip), %xmm1     # 0x6088
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movslq 0xdc(%rsp), %rsi
leaq 0x278(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x46e0
movsd 0x20(%rsp), %xmm0
movq (%rax), %rax
movsd %xmm0, (%rax)
movsd 0x230(%rsp), %xmm0
movsd 0x27c3(%rip), %xmm1     # 0x60f8
mulsd %xmm1, %xmm0
callq 0x22b0
movsd 0x28(%rsp), %xmm1
movq 0x68(%rsp), %rdi
mulsd %xmm1, %xmm0
movsd 0x27ab(%rip), %xmm1     # 0x6100
addsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
movslq 0xdc(%rsp), %rsi
callq 0x46e0
movsd 0x30(%rsp), %xmm0
movq 0x68(%rsp), %rdi
movq (%rax), %rax
movsd %xmm0, 0x8(%rax)
movl 0xdc(%rsp), %eax
incl %eax
movslq %eax, %rsi
callq 0x46e0
movq (%rax), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x230(%rsp), %xmm0
callq 0x2040
movq 0x68(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
addsd %xmm1, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
movl 0xdc(%rsp), %eax
incl %eax
movslq %eax, %rsi
callq 0x46e0
movsd 0x40(%rsp), %xmm0
movq 0x68(%rsp), %rdi
movq (%rax), %rax
movsd %xmm0, (%rax)
movl 0xdc(%rsp), %eax
incl %eax
movslq %eax, %rsi
callq 0x46e0
movq (%rax), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x230(%rsp), %xmm0
callq 0x22b0
movq 0x68(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x48(%rsp), %xmm0
addsd %xmm1, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0xdc(%rsp), %eax
incl %eax
movslq %eax, %rsi
callq 0x46e0
movsd 0x50(%rsp), %xmm0
movq 0x68(%rsp), %rdi
movq (%rax), %rax
movsd %xmm0, 0x8(%rax)
movl 0xdc(%rsp), %eax
addl $0x2, %eax
movslq %eax, %rsi
callq 0x46e0
movq (%rax), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x230(%rsp), %xmm0
callq 0x2040
movq 0x68(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x58(%rsp), %xmm0
addsd %xmm1, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movl 0xdc(%rsp), %eax
addl $0x2, %eax
movslq %eax, %rsi
callq 0x46e0
movsd 0x60(%rsp), %xmm0
movq 0x68(%rsp), %rdi
movq (%rax), %rax
movsd %xmm0, 0x8(%rax)
movl 0xdc(%rsp), %eax
addl $0x3, %eax
movslq %eax, %rsi
callq 0x46e0
movq (%rax), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0x230(%rsp), %xmm0
callq 0x2040
movq 0x68(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
addsd %xmm1, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
movl 0xdc(%rsp), %eax
addl $0x3, %eax
movslq %eax, %rsi
callq 0x46e0
movsd 0x78(%rsp), %xmm0
movq (%rax), %rax
movsd %xmm0, 0x8(%rax)
movsd 0x230(%rsp), %xmm0
movsd 0x25c7(%rip), %xmm1     # 0x6108
addsd %xmm1, %xmm0
movsd %xmm0, 0x230(%rsp)
movq 0x630(%rsp), %rdi
callq 0x2250
jmp 0x3b5d
movq 0x630(%rsp), %rdi
xorl %esi, %esi
callq 0x22c0
jmp 0x3b6e
jmp 0x36f5
leaq 0x2a8(%rsp), %rdi
callq 0x47c0
leaq 0x340(%rsp), %rdi
callq 0x47c0
leaq 0x3c8(%rsp), %rdi
callq 0x47c0
leaq 0x438(%rsp), %rdi
callq 0x47c0
leaq 0x4b8(%rsp), %rdi
callq 0x47c0
leaq 0x528(%rsp), %rdi
callq 0x47c0
movq 0x498(%rsp), %rdi
callq 0x2280
nop