/****************************************************************************
 *                                                                          *
 *     Loki - Programs for genetic analysis of complex traits using MCMC    *
 *                                                                          *
 *                      Simon Heath - MSKCC                                 *
 *                                                                          *
 *                          August 2000                                     *
 *                                                                          *
 * print_data.c:                                                            *
 *                                                                          *
 * Auxillary routines for writing out coded data                            *
 *                                                                          *
 * Copyright (C) Simon C. Heath 1997, 2000, 2002                            *
 * This is free software.  You can distribute it and/or modify it           *
 * under the terms of the Modified BSD license, see the file COPYING        *
 *                                                                          *
 ****************************************************************************/

#include <stdlib.h>
#include <string.h>
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#include <stdio.h>

#include "utils.h"
#include "loki.h"
#include "loki_peel.h"
#include "version.h"
#include "print_data.h"

#ifdef FUNC_NAME
#undef FUNC_NAME
#endif
#define FUNC_NAME "Print_Data"
void Print_Data(const char *filename,loki_time *lt)
{
	int i,k,k1,k2,rec,nrec,type;
	struct id_data *data;
	struct Variable *var;
	double x;
	FILE *fptr;
	char *s;
	
	if(!(fptr=fopen(filename,"w"))) {
		(void)fprintf(stderr,"Couldn't open output file '%s': ",filename);
		perror(0);
		return;
	}
	for(i=0;i<ped_size;i++) {
		nrec=id_array[i].n_rec;
		if(!nrec) nrec=1;
		for(rec=0;rec<nrec;rec++) {
			(void)fprintf(fptr,"%d ",id_array[i].comp+1);
			print_orig_triple(fptr,i+1);
			(void)fputc(' ',fptr);
			if(id_array[i].sex)	(void)fprintf(fptr,"%d ",id_array[i].sex);
			else (void)fputs("* ",fptr);
			for(k=0;k<models[0].n_terms;k++) {
				type=models[0].term[k].vars[0].type;
				if(type&(ST_TRAITLOCUS|ST_SEX)) continue;
				k1=models[0].term[k].vars[0].var_index;
				if(type&ST_MARKER) {
					if(marker[k1].haplo[i]) (void)fprintf(fptr,"%d %d ",marker[k1].haplo[i]&65535,marker[k1].haplo[i]>>16);
					else (void)fputs("* * ",fptr);
				} else {
					data=0;
					if(type&ST_CONSTANT) {
						if(id_array[i].data) data=id_array[i].data+k1;
					} else if(id_array[i].data1) data=id_array[i].data1[rec]+k1;
					if(!data || !data->flag) (void)fputs("* ",fptr);
					else {
						if(type&ST_FACTOR) {
							k2=(int)data->data.value;
							(void)fprintf(fptr,"%d ",k2);
						} else {
							if(data->flag&ST_INTTYPE) x=(double)data->data.value;
							else x=data->data.rvalue;
							(void)fprintf(fptr,"%g ",x);
						}
					}
				}
			}
			if(id_array[i].res[0]) {
				type=models[0].var.type;
				k1=models[0].var.var_index;
				if(type&ST_CONSTANT) data=id_array[i].data+k1;
				else data=id_array[i].data1[rec]+k1;
				if(type&ST_FACTOR) {
					k2=(int)data->data.value;
					(void)fprintf(fptr,"%d\n",k2);
				} else {
					if(data->flag&ST_INTTYPE) x=(double)data->data.value;
					else x=data->data.rvalue;
					(void)fprintf(fptr,"%g\n",x);
				}
			} else (void)fputs("*\n",fptr);
		}
	}
	(void)fclose(fptr);
	if(!(s=malloc(strlen(filename)+5))) ABT_FUNC(MMsg);
	(void)sprintf(s,"%s_idx",filename);
	if(!(fptr=fopen(s,"w"))) {
		(void)fprintf(stderr,"Couldn't open output index file '%s': ",s);
		perror(0);
	} else {
		(void)(void)fputs("******************* Phenotype Data **********************\n\n",fptr);
		(void)fprintf(fptr,"     %s: %s",LOKI_NAME,ctime(&lt->start_time));
		(void)fputs("\n\n     1  component\n     2  id\n     3  father\n     4  mother\n     5  sex\n",fptr);
		i=5;
		for(k=0;k<models[0].n_terms;k++) {
			type=models[0].term[k].vars[0].type;
			k1=models[0].term[k].vars[0].var_index;
			if(type&(ST_TRAITLOCUS|ST_SEX)) continue;
			if(type&ST_MARKER) {
				(void)fprintf(fptr,"   %3d  ",++i);
				print_marker_name(fptr,k);
			} else {
				if(type&ST_CONSTANT) var=id_variable+k1;
				else var=nonid_variable+k1;
				(void)fprintf(fptr,"   %3d  %s",++i,var->name);
				if(var->index) (void)fprintf(fptr,"(%d)",var->index);
			}
			(void)fputc('\n',fptr);
		}
		type=models[0].var.type;
		k1=models[0].var.var_index;
		if(type&ST_CONSTANT) var=id_variable+k1;
		else var=nonid_variable+k1;
		(void)fprintf(fptr,"   %3d  %s",++i,var->name);
		if(var->index) (void)fprintf(fptr,"(%d)",var->index);
		(void)fputc('\n',fptr);
		(void)fclose(fptr);
	}
	free(s);
}

#ifdef FUNC_NAME
#undef FUNC_NAME
#endif
#define FUNC_NAME "Print_Genotypes"
void Print_Genotypes(const struct output_gen *og,loki_time *lt)
{
	int i,j,k,k1,k2,l,*perm;
	FILE *fptr;
	char *s;
	
	if(!n_markers) return;
	if(!(perm=malloc(sizeof(int)*n_markers))) ABT_FUNC(MMsg);
	if(!(fptr=fopen(og->file,"w"))) {
		(void)fprintf(stderr,"Couldn't open output file '%s': ",og->file);
		perror(0);
		return;
	}
	for(j=0;j<ped_size;j++) {
		if(og->link_group) i=k=og->link_group-1;
		else {
			i=0;
			k=n_links-1;
		}
		for(;i<=k;i++) if(linkage[i].n_markers) {
			for(k1=0;k1<linkage[i].n_markers;k1++) {
				k2=linkage[i].mk_index[k1];
				if(marker[k2].haplo[j]) break;
			}
			if(k1<linkage[i].n_markers) break;
		}
		if(i>k) continue;
		if(family_id) {
			print_orig_family(fptr,j+1,0);
			(void)fputc(' ',fptr);
		}
		print_orig_id1(fptr,j+1);
		(void)fputc(' ',fptr);
		if(og->link_group) i=k=og->link_group-1;
		else {
			i=0;
			k=n_links-1;
		}
		for(;i<=k;i++) if(linkage[i].n_markers) {
			for(k1=0;k1<linkage[i].n_markers;k1++) perm[k1]=linkage[i].mk_index[k1];
			gnu_qsort(perm,(size_t)linkage[i].n_markers,(size_t)sizeof(int),cmp_loci_pos);
			for(k1=0;k1<linkage[i].n_markers;k1++) {
				k2=perm[k1];
				(void)fprintf(fptr,"%d %d ",marker[k2].haplo[j]>>16,marker[k2].haplo[j]&65535);
			}
		}
		(void)fputc('\n',fptr);
	}
	(void)fclose(fptr);
	if(!(s=malloc(strlen(og->file)+5))) ABT_FUNC(MMsg);
	(void)sprintf(s,"%s_idx",og->file);
	if(!(fptr=fopen(s,"w"))) {
		(void)fprintf(stderr,"Couldn't open output index file '%s': ",s);
		perror(0);
	} else {
		(void)(void)fputs("******************** Genotype Data **********************\n\n",fptr);
		(void)fprintf(fptr,"     %s: %s",LOKI_NAME,ctime(&lt->start_time));
		if(og->link_group) (void)fprintf(fptr,"\n     Linkage group '%s'\n",linkage[og->link_group-1].name);
		(void)fputs("\n     1      id\n",fptr);
		if(og->link_group) i=k=og->link_group-1;
		else {
			i=0;
			k=n_links-1;
		}
		j=2;
		for(;i<=k;i++) if(linkage[i].n_markers) {
			for(k1=0;k1<linkage[i].n_markers;k1++) perm[k1]=linkage[i].mk_index[k1];
			gnu_qsort(perm,(size_t)linkage[i].n_markers,(size_t)sizeof(int),cmp_loci_pos);
			for(k1=0;k1<linkage[i].n_markers;k1++) {
				k2=perm[k1];
				(void)fprintf(fptr,"   %3d-%-3d  %s",j,j+1,marker[k2].name);
				j+=2;
				if(marker[k2].index) (void)fprintf(fptr,"(%d)",marker[k2].index);
				(void)fputc('\n',fptr);
			}
		}
		(void)fputs("\n   Allele frequencies\n\n",fptr);
		if(og->link_group) i=k=og->link_group-1;
		else i=0;
		for(;i<=k;i++) if(linkage[i].n_markers) {
			for(k1=0;k1<linkage[i].n_markers;k1++) perm[k1]=linkage[i].mk_index[k1];
			gnu_qsort(perm,(size_t)linkage[i].n_markers,(size_t)sizeof(int),cmp_loci_pos);
			for(k1=0;k1<linkage[i].n_markers;k1++) {
				(void)fputs("   ",fptr);
				k2=perm[k1];
				for(l=0;l<marker[k2].locus.n_alleles;l++)	{
					if(marker[k2].freq_set[0][l]) (void)fprintf(fptr,"%g ",marker[k2].locus.freq[0][l]);
					else (void)fputs("* ",fptr);
				}
				(void)fputc('\n',fptr);
			}
		}
		(void)fclose(fptr);
	}
	free(s);
	free(perm);
}

