/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2015 Douglas L. Theobald

    This file is part of THESEUS.

    THESEUS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    THESEUS is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public
    License along with THESEUS in the file 'COPYING'. If not, see
    <http://www.gnu.org/licenses/>.

    -/_|:|_|_\-
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include "DistMat.h"


DISTMAT
*DISTMATalloc(int ntax)
{
    int             i;
    int             name_size = 256;
    DISTMAT        *distmat = NULL;

    distmat = (DISTMAT *) malloc(sizeof(DISTMAT));

    distmat->taxa = (char **)   malloc(ntax * sizeof(char *));
    distmat->dist = (double **) malloc(ntax * sizeof(double *));
    distmat->flag = (int **)    malloc(ntax * sizeof(int *));

    for (i = 0; i < ntax; ++i)
    {
        distmat->dist[i] = (double *) calloc(ntax,       sizeof(double));
        distmat->flag[i] = (int *)    calloc(ntax,       sizeof(int));
        distmat->taxa[i] = (char *)   malloc(name_size * sizeof(char));
    }

    distmat->ntax = ntax;
    return(distmat);
}


void
DISTMATdestroy(DISTMAT **distmat_ptr)
{
    DISTMAT *distmat = *distmat_ptr;
    int             i;

    for (i = 0; i < distmat->ntax; ++i)
    {
        free(distmat->dist[i]);
        free(distmat->flag[i]);
        free(distmat->taxa[i]);
    }

    free(distmat->taxa);
    free(distmat->dist);
    free(distmat->flag);
    free(distmat);
    *distmat_ptr = NULL;
}


void
print_NX_distmat(DISTMAT *distmat, char *NXfile_name)
{
    int            i, j;
    FILE          *NXfile_ptr = NULL;

    NXfile_ptr  = fopen(NXfile_name, "w");

    fprintf(NXfile_ptr, "#NEXUS\n\n");
    fprintf(NXfile_ptr, "begin taxa;\n");
    fprintf(NXfile_ptr, "  dimensions ntax=%d;\n", distmat->ntax);
    fprintf(NXfile_ptr, "  taxlabels\n");

    for (i = 0; i < distmat->ntax; ++i)
        fprintf(NXfile_ptr, "    %-s\n", distmat->taxa[i]);

    fprintf(NXfile_ptr, "  ;\nend;\n\n");

    fprintf(NXfile_ptr, "begin distances;\n");
    fprintf(NXfile_ptr, "  format\n");
    fprintf(NXfile_ptr, "    triangle=lower;\n");
    /*fprintf(NXfile_ptr, "    missing=?;\n");*/
    fprintf(NXfile_ptr, "  matrix\n");

    fprintf(NXfile_ptr, "               [");
    for (i = 0; i < distmat->ntax; ++i)
        fprintf(NXfile_ptr, " %8.8s", distmat->taxa[i]);
    fprintf(NXfile_ptr, "]\n");

    for (i = 0; i < distmat->ntax; ++i) /* for all taxa (down the row) */
    {
        fprintf(NXfile_ptr, "    %-12.12s", distmat->taxa[i]);
        for (j = 0; j <= i; ++j) /* for each column from 0 up to the diagonal */
        {
            fprintf(NXfile_ptr, " %8.6f", distmat->dist[i][j]);
        }

        fprintf(NXfile_ptr, "\n"); /* end the row */
    }

    fprintf(NXfile_ptr, "               [");
    for (i = 0; i < distmat->ntax; ++i)
        fprintf(NXfile_ptr, " %8.8s", distmat->taxa[i]);
    fprintf(NXfile_ptr, "]\n");

    fprintf(NXfile_ptr, ";\nend;\n\n");
    //fprintf(stdout, "\n\nNEXUS file \'%s\' written out. \n", NXfile_name);
    /*fprintf(NXfile_ptr, "begin paup;\n    dset distance=user;\n    upgma;\nend;\n\n");
    */
    fclose(NXfile_ptr);
}

