// File: /workspace/github_cpp_makefile_star2_O2/joao18araujo[P]pierluigi/src/fourth_species_counterpoint.cpp
// Function: FourthSpeciesCounterpoint::analyse_and_add_interval(bool, bool, std::vector<Interval, std::allocator<Interval>>&, Note, Note, Interval, Song*)
void FourthSpeciesCounterpoint::analyse_and_add_interval(bool reverse_movement, bool melodic_ascendant, vector<Interval> & possible_intervals, Note previous_note, Note note, Interval interval, Song * counterpoint){
  Note next_note;
  auto previous_counterpoint_note = counterpoint->notes.back();

  if(interval.is_consonant())
    next_note = Scale::interval_to_note_on_scale(note, interval, song->scale);
  else
    next_note = Interval::interval_to_note(note, interval);

  auto previous_interval = Interval(previous_note, previous_counterpoint_note);

  if(!next_note.valid or (interval.is_dissonant() and previous_interval.is_dissonant())){
    return;
  }

  Interval melodic_interval(previous_counterpoint_note, next_note);

  bool is_valid_passing_or_neighbor = true;
  if(interval.is_dissonant()){
    is_valid_passing_or_neighbor = (melodic_interval == "m2" or melodic_interval == "M2");
  }else if(previous_interval.is_dissonant()){
    auto pre_previous_counterpoint_note = counterpoint->notes[counterpoint->size() - 2];
    Interval previous_melodic_interval(pre_previous_counterpoint_note, previous_counterpoint_note);
    bool passing = melodic_interval.ascendant() == previous_melodic_interval.ascendant();
    bool neighbor = (pre_previous_counterpoint_note == next_note and melodic_interval.ascendant());
    is_valid_passing_or_neighbor = (passing || neighbor) && (melodic_interval == "m2" or melodic_interval == "M2");
  }

  bool can_jump = (reverse_movement or
                  melodic_interval.quantitative <= 4 or
                  melodic_interval.quantitative == 8);

  if(((can_jump and (melodic_ascendant == melodic_interval.ascendant()) and note.valid) or
      previous_counterpoint_note.rest()) and is_valid_passing_or_neighbor)
    possible_intervals.push_back(interval);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5b8, %rsp            # imm = 0x5B8
movq %r9, %rbx
movq %r8, %r15
movq %rcx, %r14
movq %rdx, 0x8(%rsp)
movl %esi, %ebp
movl %edi, %r12d
movq 0x5f0(%rsp), %r13
leaq 0x138(%rsp), %rdi
callq 0x12712
movq 0x8(%r13), %rsi
addq $-0x58, %rsi
leaq 0x1f0(%rsp), %rdi
callq 0x12676
movq %rbx, %rdi
callq 0xf624
testb %al, %al
je 0xeb81
leaq 0x4b0(%rsp), %rdi
movq %r15, %rsi
callq 0x12676
leaq 0x1c0(%rsp), %rdi
movq %rbx, %rsi
callq 0x97b4
leaq 0x9bf499d(%rip), %rax   # 0x9c034a8
movq (%rax), %rsi
addq $0x18, %rsi
leaq 0x508(%rsp), %rdi
callq 0x98ec
leaq 0x40(%rsp), %rdi
leaq 0x4b0(%rsp), %rsi
leaq 0x1c0(%rsp), %rdx
leaq 0x508(%rsp), %rcx
callq 0x14414
leaq 0x138(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x97e8
leaq 0x40(%rsp), %rdi
callq 0x979a
leaq 0x508(%rsp), %rdi
callq 0x9946
leaq 0x1c8(%rsp), %rdi
callq 0x51b0
leaq 0x4b0(%rsp), %rdi
jmp 0xebec
leaq 0x458(%rsp), %rdi
movq %r15, %rsi
callq 0x12676
leaq 0x190(%rsp), %rdi
movq %rbx, %rsi
callq 0x97b4
leaq 0x40(%rsp), %rdi
leaq 0x458(%rsp), %rsi
leaq 0x190(%rsp), %rdx
callq 0xf750
leaq 0x138(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x97e8
leaq 0x40(%rsp), %rdi
callq 0x979a
leaq 0x198(%rsp), %rdi
callq 0x51b0
leaq 0x458(%rsp), %rdi
callq 0x979a
leaq 0x400(%rsp), %rdi
movq %r14, %rsi
callq 0x12676
leaq 0x3a8(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x12676
leaq 0x108(%rsp), %rdi
leaq 0x400(%rsp), %rsi
leaq 0x3a8(%rsp), %rdx
callq 0xf41a
leaq 0x3a8(%rsp), %rdi
callq 0x979a
leaq 0x400(%rsp), %rdi
callq 0x979a
cmpb $0x1, 0x18c(%rsp)
jne 0xef32
movq %rbx, %rdi
callq 0xf5ea
testb %al, %al
je 0xec7c
leaq 0x108(%rsp), %rdi
callq 0xf5ea
testb %al, %al
jne 0xef32
leaq 0x350(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x12676
leaq 0x2f8(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x12676
leaq 0x10(%rsp), %rdi
leaq 0x350(%rsp), %rsi
leaq 0x2f8(%rsp), %rdx
callq 0xf41a
leaq 0x2f8(%rsp), %rdi
callq 0x979a
leaq 0x350(%rsp), %rdi
callq 0x979a
movq %rbx, %rdi
callq 0xf5ea
testb %al, %al
je 0xed62
leaq 0x1a3c5(%rip), %rsi     # 0x290b2
leaq 0x40(%rsp), %rdi
leaq 0xe8(%rsp), %rdx
callq 0x96e6
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0xf50e
movb $0x1, %r14b
testb %al, %al
jne 0xed53
leaq 0x1a399(%rip), %rsi     # 0x290b5
leaq 0x98(%rsp), %rdi
leaq 0xc8(%rsp), %rdx
callq 0x96e6
leaq 0x10(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0xf50e
movl %eax, %r14d
leaq 0x98(%rsp), %rdi
callq 0x51b0
leaq 0x40(%rsp), %rdi
callq 0x51b0
jmp 0xeed9
leaq 0x108(%rsp), %rdi
callq 0xf5ea
movb $0x1, %r14b
testb %al, %al
je 0xeed9
movq %r13, %rdi
callq 0x17ce4
addl $-0x2, %eax
imulq $0x58, %rax, %rsi
addq (%r13), %rsi
leaq 0x40(%rsp), %rdi
callq 0x12676
leaq 0x2a0(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x12676
leaq 0x248(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x12676
leaq 0x98(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
leaq 0x248(%rsp), %rdx
callq 0xf41a
leaq 0x248(%rsp), %rdi
callq 0x979a
leaq 0x2a0(%rsp), %rdi
callq 0x979a
leaq 0x10(%rsp), %rdi
callq 0xf856
movl %eax, %r14d
leaq 0x98(%rsp), %rdi
callq 0xf856
movl %eax, %r13d
leaq 0x40(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x12f5e
testb %al, %al
je 0xee34
leaq 0x10(%rsp), %rdi
callq 0xf856
jmp 0xee36
xorl %eax, %eax
testb %al, %al
jne 0xee48
xorb %r13b, %r14b
xorb $0x1, %r14b
jne 0xee48
xorl %r14d, %r14d
jmp 0xeec2
leaq 0x1a263(%rip), %rsi     # 0x290b2
leaq 0xe8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x96e6
leaq 0x10(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0xf50e
movb $0x1, %r14b
testb %al, %al
jne 0xeeb5
leaq 0x1a234(%rip), %rsi     # 0x290b5
leaq 0xc8(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x96e6
leaq 0x10(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xf50e
movl %eax, %r14d
leaq 0xc8(%rsp), %rdi
callq 0x51b0
leaq 0xe8(%rsp), %rdi
callq 0x51b0
leaq 0xa0(%rsp), %rdi
callq 0x51b0
leaq 0x40(%rsp), %rdi
callq 0x979a
testb %r12b, %r12b
jne 0xeeec
movl 0x10(%rsp), %eax
cmpl $0x5, %eax
jl 0xeeec
cmpl $0x8, %eax
jne 0xef09
leaq 0x10(%rsp), %rdi
callq 0xf856
cmpb %bpl, %al
jne 0xef09
cmpb $0x0, 0x54(%r15)
je 0xef09
testb %r14b, %r14b
jne 0xef1b
jmp 0xef28
leaq 0x1f0(%rsp), %rdi
callq 0x1302a
testb %al, %r14b
je 0xef28
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x9968
leaq 0x18(%rsp), %rdi
callq 0x51b0
leaq 0x110(%rsp), %rdi
callq 0x51b0
leaq 0x1f0(%rsp), %rdi
callq 0x979a
leaq 0x138(%rsp), %rdi
callq 0x979a
addq $0x5b8, %rsp            # imm = 0x5B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x51b0
jmp 0xef82
jmp 0xef7f
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x51b0
jmp 0xefd5
jmp 0xefd2
movq %rax, %rbx
leaq 0x248(%rsp), %rdi
callq 0x979a
jmp 0xefa8
movq %rax, %rbx
leaq 0x2a0(%rsp), %rdi
callq 0x979a
jmp 0xefe2
movq %rax, %rbx
jmp 0xefe2
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x51b0
jmp 0xeff9
jmp 0xeff6
jmp 0xefd2
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x51b0
leaq 0x40(%rsp), %rdi
callq 0x979a
jmp 0xf0b0
jmp 0xf0ad
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x51b0
jmp 0xf0b0
jmp 0xf0ad
movq %rax, %rbx
leaq 0x2f8(%rsp), %rdi
callq 0x979a
jmp 0xf022
movq %rax, %rbx
leaq 0x350(%rsp), %rdi
callq 0x979a
jmp 0xf0bf
jmp 0xf0bc
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x979a
jmp 0xf05a
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x979a
jmp 0xf06c
movq %rax, %rbx
leaq 0x508(%rsp), %rdi
callq 0x9946
jmp 0xf07e
movq %rax, %rbx
leaq 0x198(%rsp), %rdi
callq 0x51b0
jmp 0xf090
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x51b0
jmp 0xf09d
movq %rax, %rbx
leaq 0x458(%rsp), %rdi
jmp 0xf0eb
movq %rax, %rbx
leaq 0x4b0(%rsp), %rdi
jmp 0xf0eb
jmp 0xf0f4
jmp 0xf0f4
jmp 0xf0ad
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x51b0
jmp 0xf0bf
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x51b0
jmp 0xf0f7
movq %rax, %rbx
leaq 0x3a8(%rsp), %rdi
callq 0x979a
jmp 0xf0e3
movq %rax, %rbx
leaq 0x400(%rsp), %rdi
callq 0x979a
jmp 0xf0f7
jmp 0xf0f4
movq %rax, %rbx
leaq 0x1f0(%rsp), %rdi
callq 0x979a
leaq 0x138(%rsp), %rdi
callq 0x979a
movq %rbx, %rdi
callq 0x55d0
movq %rax, %rbx
jmp 0xf104