// File: ryanbarringtoncox[P]AVLTree/AVLTree.cpp
// Function: AVLTree<int>::remove(int)
void AVLTree<T>::remove(T v) {
	Node<T>** curr =&root;
	Node<T>** mom;
		vector<Node<T>**> path;
	
	//is v in tree?
	while(*curr!=0 && (*curr)->getValue()!= v) {
		path.push_back(curr);
		if (v < (*curr)->getValue()) {
			curr = &((*curr)->getLeftChild());
		} else if (v > (*curr)->getValue()) {
			curr = &((*curr)->getRightChild());
		}    
	}
	
	//v not found
	if (*curr==0) {
		return;
	}
	
	//v is Found
	else {
		Node<T>* nodeToRemove = *curr;	
		//no left child
		if ((nodeToRemove)->getLeftChild()==0) {
			*curr=nodeToRemove->getRightChild();
		}
		//if there's a left child find in-order-predecessor
		else {
			Node<T>* iop = nodeToRemove->getLeftChild();
			while (iop->getRightChild()!=0) {
				iop = iop->getRightChild();	
			}
			iop->setRightChild(*(nodeToRemove->getRightChild()));
			*curr=nodeToRemove->getLeftChild();
		}	  
		
		//update balances through path to root
		T currValue = v;
		mom=&*(path.back());
		
		//increment parent as necessary
		if (currValue < ((*mom))->getValue()) (*mom)->incBalance();
		if (currValue > (*mom)->getValue()) (*mom)->decBalance();

		//keep going with grandparents
		while ((*mom)->getBalance()!=1 && (*mom)->getBalance()!=-1) {		
			
			//rotations
			if ((*mom)->getBalance()==2) {
				(*mom)->resetBalance();
				leftRotation(*mom, mom);
				(*mom)->decBalance();
				
			}			
			if ((*mom)->getBalance()==-2) {
				(*mom)->resetBalance();
				rightRotation(*mom, mom);
				(*mom)->incBalance();
				
			}
			
			//balance adjustments
			if ((*mom)->getBalance()==0) {				
				currValue = (*mom)->getValue();
				path.pop_back();
				if (*mom == root) break;
				mom=&*(path.back());
				if (*mom) {			
					if (currValue < (*mom)->getValue()) (*mom)->incBalance();
					if (currValue > (*mom)->getValue()) (*mom)->decBalance();	
				}
			}
			
		}
		delete nodeToRemove;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq %rax, -0x18(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x56b0
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, (%rcx)
movb %al, -0x69(%rbp)
je 0x51f3
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0x70(%rbp)
jmp 0x51e7
movl -0x70(%rbp), %eax
cmpl -0xc(%rbp), %eax
setne %al
movb %al, -0x69(%rbp)
movb -0x69(%rbp), %al
testb $0x1, %al
jne 0x51ff
jmp 0x52b9
leaq -0x38(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x56d0
jmp 0x520e
movl -0xc(%rbp), %eax
movl %eax, -0x78(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0x74(%rbp)
jmp 0x5225
movl -0x78(%rbp), %eax
movl -0x74(%rbp), %ecx
cmpl %ecx, %eax
jge 0x5265
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0xcba0
movq %rax, -0x80(%rbp)
jmp 0x5241
movq -0x80(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x52b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x57b0
jmp 0x569e
movl -0xc(%rbp), %eax
movl %eax, -0x88(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0x84(%rbp)
jmp 0x5282
movl -0x88(%rbp), %eax
movl -0x84(%rbp), %ecx
cmpl %ecx, %eax
jle 0x52b2
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0xcbe0
movq %rax, -0x90(%rbp)
jmp 0x52a7
movq -0x90(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x52b4
jmp 0x51c7
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x52cf
movl $0x1, -0x48(%rbp)
jmp 0x568c
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0xcba0
movq %rax, -0x98(%rbp)
jmp 0x52ec
movq -0x98(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x5321
movq -0x50(%rbp), %rdi
callq 0xcbe0
movq %rax, -0xa0(%rbp)
jmp 0x530b
movq -0xa0(%rbp), %rax
movq (%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x53da
movq -0x50(%rbp), %rdi
callq 0xcba0
movq %rax, -0xa8(%rbp)
jmp 0x5333
movq -0xa8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0xcbe0
movq %rax, -0xb0(%rbp)
jmp 0x5353
movq -0xb0(%rbp), %rax
cmpq $0x0, (%rax)
je 0x5382
movq -0x58(%rbp), %rdi
callq 0xcbe0
movq %rax, -0xb8(%rbp)
jmp 0x5372
movq -0xb8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
jmp 0x5341
movq -0x58(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x50(%rbp), %rdi
callq 0xcbe0
movq %rax, -0xc0(%rbp)
jmp 0x539f
movq -0xc8(%rbp), %rdi
movq -0xc0(%rbp), %rax
movq (%rax), %rsi
callq 0xcc00
jmp 0x53b7
movq -0x50(%rbp), %rdi
callq 0xcba0
movq %rax, -0xd0(%rbp)
jmp 0x53c9
movq -0xd0(%rbp), %rax
movq (%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl -0xc(%rbp), %eax
movl %eax, -0x5c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x5740
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0xd8(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0xd4(%rbp)
jmp 0x540d
movl -0xd8(%rbp), %eax
movl -0xd4(%rbp), %ecx
cmpl %ecx, %eax
jge 0x542d
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb20
jmp 0x542b
jmp 0x542d
movl -0x5c(%rbp), %eax
movl %eax, -0xe0(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0xdc(%rbp)
jmp 0x544a
movl -0xe0(%rbp), %eax
movl -0xdc(%rbp), %ecx
cmpl %ecx, %eax
jle 0x546a
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb40
jmp 0x5468
jmp 0x546a
jmp 0x546c
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb00
movl %eax, -0xe4(%rbp)
jmp 0x5480
movl -0xe4(%rbp), %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
movb %al, -0xe5(%rbp)
je 0x54b9
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb00
movl %eax, -0xec(%rbp)
jmp 0x54a7
movl -0xec(%rbp), %eax
cmpl $-0x1, %eax
setne %al
movb %al, -0xe5(%rbp)
movb -0xe5(%rbp), %al
testb $0x1, %al
jne 0x54c8
jmp 0x5661
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb00
movl %eax, -0xf0(%rbp)
jmp 0x54dc
movl -0xf0(%rbp), %eax
cmpl $0x2, %eax
jne 0x5517
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb60
jmp 0x54f5
movq -0x68(%rbp), %rdi
movq -0x20(%rbp), %rdx
movq (%rdx), %rsi
callq 0x4ef0
jmp 0x5507
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb40
jmp 0x5515
jmp 0x5517
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb00
movl %eax, -0xf4(%rbp)
jmp 0x552b
movl -0xf4(%rbp), %eax
cmpl $-0x2, %eax
jne 0x5566
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb60
jmp 0x5544
movq -0x68(%rbp), %rdi
movq -0x20(%rbp), %rdx
movq (%rdx), %rsi
callq 0x4fb0
jmp 0x5556
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb20
jmp 0x5564
jmp 0x5566
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb00
movl %eax, -0xf8(%rbp)
jmp 0x557a
movl -0xf8(%rbp), %eax
cmpl $0x0, %eax
jne 0x565c
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0xfc(%rbp)
jmp 0x559d
movl -0xfc(%rbp), %eax
movl %eax, -0x5c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x5780
movq -0x68(%rbp), %rcx
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpq (%rcx), %rax
jne 0x55c4
jmp 0x5661
leaq -0x38(%rbp), %rdi
callq 0x5740
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq $0x0, (%rax)
je 0x565a
movl -0x5c(%rbp), %eax
movl %eax, -0x104(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0x100(%rbp)
jmp 0x55fb
movl -0x104(%rbp), %eax
movl -0x100(%rbp), %ecx
cmpl %ecx, %eax
jge 0x561b
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb20
jmp 0x5619
jmp 0x561b
movl -0x5c(%rbp), %eax
movl %eax, -0x10c(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcaf0
movl %eax, -0x108(%rbp)
jmp 0x5638
movl -0x10c(%rbp), %eax
movl -0x108(%rbp), %ecx
cmpl %ecx, %eax
jle 0x5658
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0xcb40
jmp 0x5656
jmp 0x5658
jmp 0x565a
jmp 0x565c
jmp 0x546c
movq -0x50(%rbp), %rax
movq %rax, -0x118(%rbp)
cmpq $0x0, %rax
je 0x5683
movq -0x118(%rbp), %rdi
movl $0x20, %esi
callq 0x21c0
jmp 0x5685
movl $0x0, -0x48(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x57b0
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x22c0
nopw (%rax,%rax)