// File: yuansliu[P]HiRGC/hirgc.cpp
// Function: main
int main(int argc, char *argv[]) {
	vector<string> chr_name_list;
	vector<string> fold_list;

	bool flag = true, compressed = false;
	int oc;
	char *mode = NULL, *ref_file = NULL, *tar_file = NULL, *ref_fold = NULL, *tar_fold = NULL;

	struct  timeval  start;
	struct  timeval  end;
	unsigned long timer;
	gettimeofday(&start,NULL);

	if ((oc = getopt(argc, argv, "m:")) >= 0) {
		mode = optarg;
	} else {
		// printf("arguments error...\n");
		show_usage();
		return 0;
	}

	if (strcmp(mode, "file") == 0) {
		while ((oc = getopt(argc, argv, "r:t:")) >= 0) {
			switch(oc) {
				case 'r':
					ref_file = optarg;
					break;
				case 't':
					tar_file = optarg;
					break;
				case '?':
					flag = false;
					break;
			}
		}

		if (flag && ref_file && tar_file) {
			compressFile(ref_file, tar_file);
			compressed = true;
		}

	} else 
	if (strcmp(mode, "genome") == 0 ){
		while ((oc = getopt(argc, argv, "r:t:n:")) >= 0) {
			switch(oc) {
				case 'r':
					ref_fold = optarg;
					break;
				case 't':
					tar_fold = optarg;
					break;
				case 'n':
					if (strcmp(optarg, "default") == 0) {
						setDefaltName(chr_name_list);
					} else {
						flag &= getList(optarg, chr_name_list);
					}
					break;
				case '?':
					flag = false;
					break;
			}
		}

		if (flag && ref_fold && tar_fold && chr_name_list.size() > 0) {
			compressGenome(ref_fold, tar_fold, chr_name_list);
			compressed = true;
		}

	} else 
	if (strcmp(mode, "set") == 0) {
		while ((oc = getopt(argc, argv, "r:t:n:")) >= 0) {
			switch(oc) {
				case 'r':
					ref_fold = optarg;
					break;
				case 't':
					flag &= getList(optarg, fold_list);
					break;
				case 'n':
					if (strcmp(optarg, "default") == 0) {
						setDefaltName(chr_name_list);
					} else {
						flag &= getList(optarg, chr_name_list);
					}
					break;
				case '?':
					flag = false;
					break;
			}
		}

		if (flag && ref_fold && fold_list.size() > 0 && chr_name_list.size() > 0) {
			compressSet(ref_fold, fold_list, chr_name_list);
			compressed = true;
		}
	}

	if (!compressed) {
		// printf("arguments error...\n");
		show_usage();
		return 0;
	}

	gettimeofday(&end,NULL);
	timer = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
	printf("total compression timer = %lf ms; %lf min\n", timer/1000.0, timer/1000.0/1000.0/60.0);
}

// Assembly:
subq $0xc8, %rsp
movl $0x0, 0xc4(%rsp)
movl %edi, 0xc0(%rsp)
movq %rsi, 0xb8(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x5710
leaq 0x88(%rsp), %rdi
callq 0x5710
movb $0x1, 0x87(%rsp)
movb $0x0, 0x86(%rsp)
movq $0x0, 0x78(%rsp)
movq $0x0, 0x70(%rsp)
movq $0x0, 0x68(%rsp)
movq $0x0, 0x60(%rsp)
movq $0x0, 0x58(%rsp)
leaq 0x48(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2240
movl 0xc0(%rsp), %edi
movq 0xb8(%rsp), %rsi
leaq 0x3815(%rip), %rdx      # 0x8461
callq 0x2070
movl %eax, 0x80(%rsp)
cmpl $0x0, %eax
jl 0x4c6e
movq 0x6364(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x78(%rsp)
jmp 0x4cba
callq 0x4ac0
jmp 0x4c75
movl $0x0, 0xc4(%rsp)
movl $0x1, 0x20(%rsp)
jmp 0x5179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x5610
leaq 0xa0(%rsp), %rdi
callq 0x5610
jmp 0x51a2
movq 0x78(%rsp), %rdi
leaq 0x379e(%rip), %rsi      # 0x8464
callq 0x21f0
cmpl $0x0, %eax
jne 0x4d89
jmp 0x4cd6
movl 0xc0(%rsp), %edi
movq 0xb8(%rsp), %rsi
leaq 0x377d(%rip), %rdx      # 0x8469
callq 0x2070
movl %eax, 0x80(%rsp)
cmpl $0x0, %eax
jl 0x4d51
movl 0x80(%rsp), %eax
movl %eax, 0x1c(%rsp)
subl $0x3f, %eax
je 0x4d47
jmp 0x4d0f
movl 0x1c(%rsp), %eax
subl $0x72, %eax
je 0x4d25
jmp 0x4d1a
movl 0x1c(%rsp), %eax
subl $0x74, %eax
je 0x4d36
jmp 0x4d4f
movq 0x629c(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x70(%rsp)
jmp 0x4d4f
movq 0x628b(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x68(%rsp)
jmp 0x4d4f
movb $0x0, 0x87(%rsp)
jmp 0x4cd6
testb $0x1, 0x87(%rsp)
je 0x4d84
cmpq $0x0, 0x70(%rsp)
je 0x4d84
cmpq $0x0, 0x68(%rsp)
je 0x4d84
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x4220
jmp 0x4d7c
movb $0x1, 0x86(%rsp)
jmp 0x50ba
movq 0x78(%rsp), %rdi
leaq 0x36d9(%rip), %rsi      # 0x846e
callq 0x21f0
cmpl $0x0, %eax
jne 0x4f00
jmp 0x4da5
movl 0xc0(%rsp), %edi
movq 0xb8(%rsp), %rsi
leaq 0x36ba(%rip), %rdx      # 0x8475
callq 0x2070
movl %eax, 0x80(%rsp)
cmpl $0x0, %eax
jl 0x4ead
movl 0x80(%rsp), %eax
movl %eax, 0x18(%rsp)
subl $0x3f, %eax
je 0x4ea0
jmp 0x4de6
movl 0x18(%rsp), %eax
subl $0x6e, %eax
je 0x4e2f
jmp 0x4df1
movl 0x18(%rsp), %eax
subl $0x72, %eax
je 0x4e0a
jmp 0x4dfc
movl 0x18(%rsp), %eax
subl $0x74, %eax
je 0x4e1e
jmp 0x4ea8
movq 0x61b7(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x60(%rsp)
jmp 0x4ea8
movq 0x61a3(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x58(%rsp)
jmp 0x4ea8
movq 0x6192(%rip), %rax      # 0xafc8
movq (%rax), %rdi
leaq 0x363c(%rip), %rsi      # 0x847c
callq 0x21f0
cmpl $0x0, %eax
jne 0x4e5b
leaq 0xa0(%rsp), %rdi
callq 0x4a50
jmp 0x4e59
jmp 0x4e9e
movq 0x6166(%rip), %rax      # 0xafc8
movq (%rax), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x48d0
movb %al, 0x17(%rsp)
jmp 0x4e78
movb 0x17(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movb 0x87(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x87(%rsp)
jmp 0x4ea8
movb $0x0, 0x87(%rsp)
jmp 0x4da5
testb $0x1, 0x87(%rsp)
je 0x4efb
cmpq $0x0, 0x60(%rsp)
je 0x4efb
cmpq $0x0, 0x58(%rsp)
je 0x4efb
leaq 0xa0(%rsp), %rdi
callq 0x5520
cmpq $0x0, %rax
jbe 0x4efb
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x42e0
jmp 0x4ef3
movb $0x1, 0x86(%rsp)
jmp 0x50b8
movq 0x78(%rsp), %rdi
leaq 0x3578(%rip), %rsi      # 0x8484
callq 0x21f0
cmpl $0x0, %eax
jne 0x50b6
jmp 0x4f1c
movl 0xc0(%rsp), %edi
movq 0xb8(%rsp), %rsi
leaq 0x3543(%rip), %rdx      # 0x8475
callq 0x2070
movl %eax, 0x80(%rsp)
cmpl $0x0, %eax
jl 0x5058
movl 0x80(%rsp), %eax
movl %eax, 0x10(%rsp)
subl $0x3f, %eax
je 0x504b
jmp 0x4f5d
movl 0x10(%rsp), %eax
subl $0x6e, %eax
je 0x4fda
jmp 0x4f68
movl 0x10(%rsp), %eax
subl $0x72, %eax
je 0x4f81
jmp 0x4f73
movl 0x10(%rsp), %eax
subl $0x74, %eax
je 0x4f95
jmp 0x5053
movq 0x6040(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x60(%rsp)
jmp 0x5053
movq 0x602c(%rip), %rax      # 0xafc8
movq (%rax), %rdi
leaq 0x88(%rsp), %rsi
callq 0x48d0
movb %al, 0xf(%rsp)
jmp 0x4fb2
movb 0xf(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movb 0x87(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x87(%rsp)
jmp 0x5053
movq 0x5fe7(%rip), %rax      # 0xafc8
movq (%rax), %rdi
leaq 0x3491(%rip), %rsi      # 0x847c
callq 0x21f0
cmpl $0x0, %eax
jne 0x5006
leaq 0xa0(%rsp), %rdi
callq 0x4a50
jmp 0x5004
jmp 0x5049
movq 0x5fbb(%rip), %rax      # 0xafc8
movq (%rax), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x48d0
movb %al, 0xe(%rsp)
jmp 0x5023
movb 0xe(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movb 0x87(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x87(%rsp)
jmp 0x5053
movb $0x0, 0x87(%rsp)
jmp 0x4f1c
testb $0x1, 0x87(%rsp)
je 0x50b4
cmpq $0x0, 0x60(%rsp)
je 0x50b4
leaq 0x88(%rsp), %rdi
callq 0x5520
cmpq $0x0, %rax
jbe 0x50b4
leaq 0xa0(%rsp), %rdi
callq 0x5520
cmpq $0x0, %rax
jbe 0x50b4
movq 0x60(%rsp), %rdi
leaq 0x88(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x4530
jmp 0x50ac
movb $0x1, 0x86(%rsp)
jmp 0x50b6
jmp 0x50b8
jmp 0x50ba
testb $0x1, 0x86(%rsp)
jne 0x50e3
callq 0x4ac0
jmp 0x50cb
movl $0x0, 0xc4(%rsp)
movl $0x1, 0x20(%rsp)
jmp 0x5179
xorl %eax, %eax
movl %eax, %esi
leaq 0x38(%rsp), %rdi
callq 0x2240
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rcx
subq %rsi, %rax
imulq $0xf4240, %rax, %rax    # imm = 0xF4240
addq %rdx, %rax
subq %rcx, %rax
movq %rax, 0x30(%rsp)
movaps 0x2eff(%rip), %xmm1     # 0x8020
movq 0x30(%rsp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x2efd(%rip), %xmm1     # 0x8030
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0x2ec6(%rip), %xmm2     # 0x8010
divsd %xmm2, %xmm0
movaps %xmm0, %xmm1
divsd %xmm2, %xmm1
movsd 0x2ebb(%rip), %xmm2     # 0x8018
divsd %xmm2, %xmm1
leaq 0x3320(%rip), %rdi      # 0x8488
movb $0x2, %al
callq 0x2040
jmp 0x5171
movl $0x0, 0x20(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x5610
leaq 0xa0(%rsp), %rdi
callq 0x5610
movl 0xc4(%rsp), %eax
addq $0xc8, %rsp
retq
movq 0x28(%rsp), %rdi
callq 0x2280
nopl (%rax)