// File: ratulSharker[P]Havec/src/common.cpp
// Function: partialHasher(unsigned long long, char, unsigned short, unsigned int)
unsigned long long partialHasher(unsigned long long hashVal, char lastNeucleotide, unsigned short int kSize,unsigned int whichHashFunc){
	
	//security checking -- can be stopped when releasing
	if(whichHashFunc > LAST_HASH_FUNC){ //|| whichHashFunc < 0){ // un-necessay checking is removed because whichHashFunc is unsigned which value would never be negative, caught by osx g++.
		std::cout<<"invalid hash function requested :: "<<whichHashFunc<<std::endl;
		std::cout<<"Exiting..."<<std::endl;
		exit(0);
	}
	
	unsigned char map_byte = two_bit_repr[whichHashFunc]; // A T G C
	//decide the hash values
	unsigned char hashA = ((map_byte & 0XC0)>>6),
				  hashT = ((map_byte & 0X30)>>4),
				  hashG = ((map_byte & 0X0C)>>2),
				  hashC = ((map_byte & 0X03));
	//unsigned int hByte = whichHashFunc;
	unsigned int hByte;
	
	neucleotide_status = NEUCLEOTIDE_CHAIN_IS_OK;//at first assume every neucleotide is ok
	
	switch(toupper(lastNeucleotide)){
				case 'A': //A = whichHashFunc % 4
					hByte = hashA;
					break;

				case 'T'://T (whichHashFunc + 1)  % 4
					hByte = hashT;
					break;

				case 'G'://G (whichHashFunc + 2)  % 4
					hByte = hashG;
					break;

				case 'C'://C (whichHashFunc + 3)  % 4
					hByte = hashC;
					break;
				
				default://N found no need to compute further
					neucleotide_status = N_FOUND_IN_NEUCLEOTIDE;
					return 0;
					
					break;
					
	}

	hashVal = (hashVal << 2) | hByte; //actual hashing
	
	//if the khmer size is less than 32 bit -> then the hash bit at the index > 2k is invalid -- clean them man :P
	unsigned long long bitmusk = 0xFFFFFFFFFFFFFFFF; //here assumed that unsigned long long is 64 bit long
	bitmusk = bitmusk >> ((sizeof(unsigned long long) * 8 )- (2 * kSize));

	hashVal = hashVal & bitmusk;

	return hashVal ;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movw %dx, %ax
movb %sil, %dl
movq %rdi, -0x10(%rbp)
movb %dl, -0x11(%rbp)
movw %ax, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl 0x70df(%rip), %eax      # 0x17354
jbe 0x102cd
movq 0x6d52(%rip), %rdi      # 0x16fd0
leaq 0x162f(%rip), %rsi      # 0x118b4
callq 0x32f0
movq %rax, %rdi
movl -0x18(%rbp), %esi
callq 0x3440
movq %rax, %rdi
movq 0x6d21(%rip), %rsi      # 0x16fc0
callq 0x3340
movq 0x6d25(%rip), %rdi      # 0x16fd0
leaq 0x1626(%rip), %rsi      # 0x118d8
callq 0x32f0
movq %rax, %rdi
movq 0x6cff(%rip), %rsi      # 0x16fc0
callq 0x3340
xorl %edi, %edi
callq 0x33d0
movl -0x18(%rbp), %eax
leaq 0x7089(%rip), %rcx      # 0x17360
movb (%rax,%rcx), %al
movb %al, -0x19(%rbp)
movzbl -0x19(%rbp), %eax
shrl $0x6, %eax
movb %al, -0x1a(%rbp)
movzbl -0x19(%rbp), %eax
andl $0x30, %eax
shrl $0x4, %eax
movb %al, -0x1b(%rbp)
movzbl -0x19(%rbp), %eax
andl $0xc, %eax
shrl $0x2, %eax
movb %al, -0x1c(%rbp)
movb -0x19(%rbp), %al
andb $0x3, %al
movb %al, -0x1d(%rbp)
movl $0x8, 0x7065(%rip)      # 0x17378
movsbl -0x11(%rbp), %edi
callq 0x3590
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, -0x38(%rbp)
subl $0x13, %eax
ja 0x10362
movq -0x38(%rbp), %rax
leaq 0x1503(%rip), %rcx      # 0x11838
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl -0x1a(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x10376
movzbl -0x1b(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x10376
movzbl -0x1c(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x10376
movzbl -0x1d(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x10376
movl $0x7, 0x700c(%rip)      # 0x17378
movq $0x0, -0x8(%rbp)
jmp 0x103c0
movq -0x10(%rbp), %rax
shlq $0x2, %rax
movl -0x24(%rbp), %ecx
orq %rcx, %rax
movq %rax, -0x10(%rbp)
movq $-0x1, -0x30(%rbp)
movq -0x30(%rbp), %rax
movzwl -0x14(%rbp), %ecx
shll %ecx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
shrq %cl, %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
andq -0x30(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)