// File: tbonelaforge[P]gradebook/Main.cpp
// Function: main
int main() {
    int state; // 0 = unitialized, 1 = initialized, 2 = done
    bool idMode = true; // Whether to print students by id or by name.
    Gradebook gradebook;
    char C = '?';
    bool done = false;
    ifstream inData;

    try {
        inData.open("Grades.dat");
        if (!inData) {
            state = 0;
        } else {
            gradebook.deserialize(inData);
            state = 1;
        }
        while (C != 'Q' && state != 2) {
            displayMenu(state, gradebook, idMode);
            cin >> C;
            C = toupper(C);
            if (state == 0) {
                switch (C) {
                case 'Q':
                    handleQuit(state, gradebook);
                    break;
                case 'S':
                    handleSetup(state, gradebook);
                    break;
                default :
                    cout << "Unrecognized command." << endl;
                    break;
                }
            } else if (state == 1) {
                switch (C) {
                case 'A':
                    handleAddStudent(gradebook);
                    break;
                case 'G':
                    handleCalculateGrades(gradebook, idMode);
                    break;
                case 'O':
                    handleOutputGrades(gradebook, idMode);
                    break;
                case 'S':
                    handleSetup(state, gradebook);
                    break;
                case 'Q':
                    handleQuit(state, gradebook);
                    break;
                case 'M':
                    handleModeToggle(idMode);
                    break;
                case 'P':
                    if (gradebook.getNumStudents() > 0) {
                        handleAddProgramGrade(gradebook, idMode);
                        break;
                    }
                case 'T':
                    if (gradebook.getNumStudents() > 0) {
                        handleAddTestGrade(gradebook, idMode);
                        break;
                    }
                case 'F':
                    if (gradebook.getNumStudents() > 0) {
                        handleAddFinalExamGrade(gradebook, idMode);
                        break;
                    }
                case 'C':
                    if (gradebook.getNumStudents() > 0) {
                        handleChangeGrade(gradebook);
                        break;
                    }
                default :
                    cout << "Unrecognized Command." << endl;
                }
            }
        }
    } catch (string& e) {
        cout << "Got exception:" << endl << e;
        exit(1);
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movl $0x0, -0x4(%rbp)
movb $0x1, -0x9(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x5e50
movb $0x3f, -0x61(%rbp)
movb $0x0, -0x62(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x32b0
jmp 0x5a05
leaq 0x465c(%rip), %rsi      # 0xa068
leaq -0x270(%rbp), %rdi
movl $0x8, %edx
callq 0x3160
jmp 0x5a1f
movq -0x270(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x270(%rbp,%rax), %rdi
callq 0x3110
movb %al, -0x289(%rbp)
jmp 0x5a3f
movb -0x289(%rbp), %al
testb $0x1, %al
jne 0x5a4e
jmp 0x5b00
movl $0x0, -0x8(%rbp)
jmp 0x5b19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x5dfd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
movl -0x27c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5df1
movq -0x278(%rbp), %rdi
callq 0x30e0
movq %rax, -0x288(%rbp)
movq 0x8518(%rip), %rdi      # 0xdfc8
leaq 0x4f52(%rip), %rsi      # 0xaa09
callq 0x3220
movq %rax, -0x298(%rbp)
jmp 0x5ac5
movq -0x298(%rbp), %rdi
movq 0x84d5(%rip), %rsi      # 0xdfa8
callq 0x3250
movq %rax, -0x2a0(%rbp)
jmp 0x5ae1
movq -0x2a0(%rbp), %rdi
movq -0x288(%rbp), %rsi
callq 0x3200
jmp 0x5af6
movl $0x1, %edi
callq 0x32e0
leaq -0x60(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x69b0
jmp 0x5b12
movl $0x1, -0x8(%rbp)
jmp 0x5b1b
movsbl -0x61(%rbp), %ecx
xorl %eax, %eax
cmpl $0x51, %ecx
movb %al, -0x2a1(%rbp)
je 0x5b39
cmpl $0x2, -0x8(%rbp)
setne %al
movb %al, -0x2a1(%rbp)
movb -0x2a1(%rbp), %al
testb $0x1, %al
jne 0x5b48
jmp 0x5dac
movl -0x8(%rbp), %edi
movzbl -0x9(%rbp), %edx
andl $0x1, %edx
leaq -0x60(%rbp), %rsi
callq 0x5770
jmp 0x5b5d
movq 0x847c(%rip), %rdi      # 0xdfe0
leaq -0x61(%rbp), %rsi
callq 0x3330
jmp 0x5b6f
movsbl -0x61(%rbp), %edi
callq 0x3430
movb %al, -0x61(%rbp)
cmpl $0x0, -0x8(%rbp)
jne 0x5bf9
movsbl -0x61(%rbp), %eax
movl %eax, -0x2a8(%rbp)
subl $0x51, %eax
je 0x5b9f
jmp 0x5b92
movl -0x2a8(%rbp), %eax
subl $0x53, %eax
je 0x5bb0
jmp 0x5bc1
leaq -0x8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x3c60
jmp 0x5bae
jmp 0x5bf4
leaq -0x8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x37b0
jmp 0x5bbf
jmp 0x5bf4
movq 0x8400(%rip), %rdi      # 0xdfc8
leaq 0x4e0e(%rip), %rsi      # 0xa9dd
callq 0x3220
movq %rax, -0x2b0(%rbp)
jmp 0x5bdd
movq -0x2b0(%rbp), %rdi
movq 0x83bd(%rip), %rsi      # 0xdfa8
callq 0x3250
jmp 0x5bf2
jmp 0x5bf4
jmp 0x5da7
cmpl $0x1, -0x8(%rbp)
jne 0x5da5
movsbl -0x61(%rbp), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, -0x2b8(%rbp)
subl $0x13, %eax
ja 0x5d70
movq -0x2b8(%rbp), %rax
leaq 0x43da(%rip), %rcx      # 0xa004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x60(%rbp), %rdi
callq 0x5070
jmp 0x5c3e
jmp 0x5da3
movzbl -0x9(%rbp), %esi
andl $0x1, %esi
leaq -0x60(%rbp), %rdi
callq 0x4f90
jmp 0x5c55
jmp 0x5da3
movzbl -0x9(%rbp), %esi
andl $0x1, %esi
leaq -0x60(%rbp), %rdi
callq 0x3db0
jmp 0x5c6c
jmp 0x5da3
leaq -0x8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x37b0
jmp 0x5c80
jmp 0x5da3
leaq -0x8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x3c60
jmp 0x5c94
jmp 0x5da3
leaq -0x9(%rbp), %rdi
callq 0x3d00
jmp 0x5ca4
jmp 0x5da3
leaq -0x60(%rbp), %rdi
callq 0x6740
movl %eax, -0x2bc(%rbp)
jmp 0x5cba
movl -0x2bc(%rbp), %eax
cmpl $0x0, %eax
jle 0x5cdc
movzbl -0x9(%rbp), %esi
andl $0x1, %esi
leaq -0x60(%rbp), %rdi
callq 0x3ee0
jmp 0x5cd7
jmp 0x5da3
jmp 0x5cde
leaq -0x60(%rbp), %rdi
callq 0x6740
movl %eax, -0x2c0(%rbp)
jmp 0x5cef
movl -0x2c0(%rbp), %eax
cmpl $0x0, %eax
jle 0x5d11
movzbl -0x9(%rbp), %esi
andl $0x1, %esi
leaq -0x60(%rbp), %rdi
callq 0x4300
jmp 0x5d0c
jmp 0x5da3
jmp 0x5d13
leaq -0x60(%rbp), %rdi
callq 0x6740
movl %eax, -0x2c4(%rbp)
jmp 0x5d24
movl -0x2c4(%rbp), %eax
cmpl $0x0, %eax
jle 0x5d43
movzbl -0x9(%rbp), %esi
andl $0x1, %esi
leaq -0x60(%rbp), %rdi
callq 0x4750
jmp 0x5d41
jmp 0x5da3
jmp 0x5d45
leaq -0x60(%rbp), %rdi
callq 0x6740
movl %eax, -0x2c8(%rbp)
jmp 0x5d56
movl -0x2c8(%rbp), %eax
cmpl $0x0, %eax
jle 0x5d6e
leaq -0x60(%rbp), %rdi
callq 0x4a90
jmp 0x5d6c
jmp 0x5da3
jmp 0x5d70
movq 0x8251(%rip), %rdi      # 0xdfc8
leaq 0x4c75(%rip), %rsi      # 0xa9f3
callq 0x3220
movq %rax, -0x2d0(%rbp)
jmp 0x5d8c
movq -0x2d0(%rbp), %rdi
movq 0x820e(%rip), %rsi      # 0xdfa8
callq 0x3250
jmp 0x5da1
jmp 0x5da3
jmp 0x5da5
jmp 0x5da7
jmp 0x5b1b
jmp 0x5dc9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
callq 0x33b0
jmp 0x5dc7
jmp 0x5df1
movl $0x0, -0x4(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x30b0
leaq -0x60(%rbp), %rdi
callq 0x5ee0
movl -0x4(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
leaq -0x270(%rbp), %rdi
callq 0x30b0
leaq -0x60(%rbp), %rdi
callq 0x5ee0
movq -0x278(%rbp), %rdi
callq 0x33f0
movq %rax, %rdi
callq 0x5e40
nopw (%rax,%rax)