// This file includes the main procedure of the PPH program
// It provides the menu for user to select and call pph procedure
// to solve the PPH problem.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream.h>
#include <math.h>
#include "pph.h"

// check the result with the input genotypes
int check(void) {
	FILE *fp1,*fp2;
	int row1,column1,row2,column2;
	int *data1,*data2,*temp;
	int i,j;
	int di;
	
	fp1 = fopen("temp.1","r");
	fp2 = fopen("temp.1co","r");
	
	if(fp1==NULL || fp2 == NULL) {
		printf("Can't open file\n");
		exit(0);
	}
	
	fscanf(fp1,"%d%d",&row1,&column1);
	fscanf(fp2,"%d%d",&row2,&column2);
	
	data1 = new int[column1];
	data2 = new int[column1];
	temp = new int[2*column1];
	
	for(i=0;i<row1;i++) {
		for(j=0;j<column1;j++) {
			fscanf(fp1,"%d",&di);
			data1[j] = di;
		}
		
		for(j=0;j<2*column1;j++) {
			fscanf(fp2,"%d",&di);
			temp[j] = di;
		}
		
		for(j=0;j<column1;j++) {
			if(temp[j] == temp[j+column1])
				data2[j] = temp[j];
			else
				data2[j] = 2;
		}	
		
		for(j=0;j<column1;j++) {
			if(data1[j] != data2[j]) {
				printf("Inconsistent in row %d and column %d.\n",i+1,j+1);
				return 0;
			}
		}
	}
	
	printf("The output haplotypes have been verified: they do generate the input genotypes.\n");
	fclose(fp1);
	fclose(fp2);
	return 1;
}

int main(void) {
	char filename[100];
	char *genfile = "temp";
	FILE *fp;
	int number;
	char command[200];
	char prefix[100];
	
	double isunique;
	while(1) {
		printf("Please input the filename: ");
		scanf("%s",filename);
		fp = fopen(filename,"r");
		if(fp == NULL) {
			printf("No such file or directory\n");
			continue;
		}
	
		while(1) {
			printf("Please input the number of the file format: ( Please refer to the file \"FORMAT\" ): ");
			scanf("%d",&number);
			if(number<1 || number>7) {
				printf("Input number must be from 1 to 7\n");
				continue;
			}
			
			// call perl program to parse the input file and make the input genotypes
			switch(number) {
				case 1:
					strcpy(command,"perl extract1.pl ");
					break;
				case 2:
					strcpy(command,"perl extract2.pl ");
					break;
				case 3:
					strcpy(command,"perl extract3.pl ");
					break;
				case 4:
					strcpy(command,"perl extract4.pl ");
					break;
				case 5:
					strcpy(command,"perl extract5.pl ");
					break;
				case 6:
					strcpy(command,"perl extract6.pl ");
					break;
				case 7:
					strcpy(command,"perl change01.pl ");
					strncat(command,filename,strlen(filename));
					system(command);
					strcpy(command,"perl extract7.pl ");
					break;
			}
			
			strncat(command,filename,strlen(filename));
			if(number==7)
				strncat(command,"o",1);
			
			strcpy(prefix,genfile);
			
			strncat(command," ",1);
			strncat(command,genfile,strlen(genfile));
			
			system(command);
			
			// pph() is in pph.cpp
			isunique = pph();
			
			
			switch(number) {
				case 1:
					write_format11(prefix,filename);
					write_format21(prefix,filename);
					break;
				case 2:
					write_format12(prefix,filename);
					write_format22(prefix,filename);
					break;
				case 3:
					write_format13(prefix,filename);
					write_format23(prefix,filename);
					break;
				case 4:
					write_format14(prefix,filename);
					write_format24(prefix,filename);
					break;
				case 5:
					write_format15(prefix,filename);
					write_format25(prefix,filename);
					break;
				case 6:
					write_format16(prefix,filename);
					write_format26(prefix,filename);
					break;
				case 7:
					write_format17(prefix,filename);
					write_format27(prefix,filename);
					break;
			}
			
			write_tree1(prefix,isunique);
			write_tree2(prefix,isunique);
			
			printf("A tree is created. Please see the output file \"output1\".\n");
			printf("Please see the output file \"output2\" which outputs an implicit representation of all the solutions.\n");
			check();
			
			int len = parse_output1(number);   // avoid line too long
			parse_output2(number,len);
			break;
		}
		break;
	}
	
	return 1;
}
