/*
    MSA - multiple sequence alignment utils

    Copyright (C) 2004-2015 Douglas L. Theobald

    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/>.

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

#ifndef MSA_SEEN
#define MSA_SEEN

#include "DLTutils.h"
#define MAXLINE           60
#define SEQ_NAME_LENGTH 8192

typedef struct
{
    char           *filename;    /* MSA file name */
    int             distance;
    int             allocnum;    /* number of sequences allocated in the MSA */
    int             alloclen;    /* allocated length of the alignment */
    int             seqnum;      /* number of actual sequences in the MSA */
    int             seqlen;      /* actual length of the alignment */
    int            *checksum;    /* GCG/MSF-style sequence checksums */
    int             msachecksum; /* MSA checksum */
    int            *flag;        /* external boolean flag */
    int            *flag2;       /* private boolean flag for MSA functions */
    char          **seq;         /* pointer to an array of sequences */
    char          **name;        /* pointer to an array of the sequence names */
    double        **dist;        /* pointer to array of distances */
} MSA;


typedef struct
{
    int             arraynum; /* number of MSAs allocated in the MSAA */
    int            *flag;     /* external boolean flag */
    MSA           **array;    /* pointer to an array of the sequence names */
} MSAA;


/* ////////////////////////////////////////////////////////////////////// */
MSA
*getmsa(char *msafile_name);

int
isnexdist(char *msafile_name);

int
ismsf(char *msafile_name);

MSA
*MSAinit(void);

void
MSAalloc(MSA *msa, int seqnum, int alignment_len, int name_size);

MSA
*DISTalloc(MSA *msa);

void
DISTfree(MSA *msa);

MSAA
*MSAAalloc(int arraynum);

void
MSAdestroy(MSA **msa_ptr);

void
MSAAdestroy(MSAA **msas_ptr);

/* ////////////////////////////////////////////////////////////////////// */
void
MSAprint(MSA *);

void
MSAmultiprint(MSAA *msas);

MSA
*MSAcpy(MSA *msa1, MSA *msa2);

MSA
*MSAduplicate(MSA *msa);

MSA
*MSAduplicate_noflags(MSA *msa);

MSA
*MSAmult(MSA *msa, int multiply);

MSA
*MSAduplicate_empty(MSA *msa);

int
MSAseqeq(MSA *msa1, MSA *msa2, int *seq1, int *begin1, int *end1, int *seq2, int *begin2, int *end2);

MSA
*MSAdeldups(MSA *msa);

MSA
*MSAfixnamesphy(MSA *msa);

MSA
*MSAdelallgaps(MSA *msa, int begcol, int endcol, int logap, int upgap, double frac);

MSA
*MSAdelgap(MSA *msa);

MSA
*MSAmingap(MSA *msa);

MSA
*MSAmerge(MSAA *msas);

void
MSAcombine2(MSAA *msaa, int msa1_i, int msa2_i, int seq1_i, int seq2_i, int msao_i);

/* ////////////////////////////////////////////////////////////////////// */
int
GCGchecksum(MSA *msa, int seq);

int
GCGmultichecksum(MSA *msa);

void
reada2m(char *msafile_name, MSA *msa);

void
reada2m2(char *msafile_name, MSA *msa);

void
readaln(char *msafile_name, MSA *msa);

void
readnex(char *msafile_name, MSA *msa);

void
readnexd(char *msafile_name, MSA *msa);

void
nexus_dist(MSA *msa, char *filestr, int filesize, int format);

int
getvali(char *string, char *key, char delimiter, char **endptr);

char *
getvals(char *string, char *key, char delimiter, char **endptr);

double
getvald(char *string, char *key, char delimiter, char **endptr);

char
getvalc(char *string, char *key, char delimiter, char **endptr);

void
readphylip(char *msafile_name, MSA *msa);

void
readphylipd(char *msafile_name, MSA *msa);

int
phylip_dist_format(MSA *msa, char *filestr, int filesize);

void
phylip_dist(MSA *msa, char *filestr, int filesize, int format);

void
readmsf(char *msafile_name, MSA *msa);

/* ////////////////////////////////////////////////////////////////////// */
void
writea2m_seq(MSA *msa, int seqID, char *outfile_root);

void
writealn_seq(MSA *msa, int seqID, char *outfile_root);

void
writenex_seq(MSA *msa, int seqID, char *outfile_root);

void
writenexd(MSA *msa, char *outfile_root);

void
writea2m(MSA *msa, int begin, int window, char *outfile_root);

void
writealn(MSA *msa, int begin, int window, char *outfile_root);

void
writephylip(MSA *msa, int begin, int window, char *outfile_root);

void
writenex(MSA *msa, int begin, int window, char *outfile_root);

void
writepsib(MSA *msa, int begin, int window, char *outfile_root);

void
writefasta_explode(MSA *msa, int nfield);

#endif
