/*
 * treesort.h
 *
 *
 * Part of TREE-PUZZLE 5.2 (February 2005)
 *
 * (c) 2003-2005 by Heiko A. Schmidt, Korbinian Strimmer, and Arndt von Haeseler
 * (c) 1999-2003 by Heiko A. Schmidt, Korbinian Strimmer,
 *                  M. Vingron, and Arndt von Haeseler
 * (c) 1995-1999 by Korbinian Strimmer and Arndt von Haeseler
 *
 * All parts of the source except where indicated are distributed under
 * the GNU public licence.  See http://www.opensource.org for details.
 *
 * ($Id$)
 *
 */


#ifndef TREESORT_H
#define TREESORT_H

typedef struct treelistitemtypedummy {
	struct treelistitemtypedummy *pred;
	struct treelistitemtypedummy *succ;
	struct treelistitemtypedummy *sortnext;
	struct treelistitemtypedummy *sortlast;
	char  *tree;
	int    count;
	int    id;
	int    idx;
} treelistitemtype;

#include "puzzle.h"
#include "util.h"

#define PT_FTYPE_DEFAULT           0
#define PT_FTYPE_READABLE          1
#define PT_FTYPE_REPORT            2
#define PT_FTYPE_PTORDER           3
#define PT_FTYPE_NEXUS             4
#define PT_FTYPE_NEXUS_NOTRANSLATE 5

EXTERN treelistitemtype *psteptreelist;
EXTERN treelistitemtype *psteptreesortlist;
EXTERN int               psteptreenum;
EXTERN int               psteptreesum;

/*******************************************/
/* tree sorting                            */
/*******************************************/

/* compute address of the 4 int (sort key) in the 4 int node */
int ct_sortkeyaddr(int addr);

/**********/

/* compute address of the next edge pointer in a 4 int node (0->1->2->0) */
int ct_nextedgeaddr(int addr);

/**********/

/* compute address of 1st edge of a 4 int node from node number */
int ct_1stedge(int node);

/**********/

/* compute address of 2nd edge of a 4 int node from node number */
int ct_2ndedge(int node);

/**********/

/* compute address of 3rd edge of a 4 int node from node number */
int ct_3rdedge(int node);

/**********/

/* check whether node 'node' is a leaf (2nd/3rd edge pointer = -1) */
int ct_isleaf(int node, int *ctree);

/**********/

/* compute node number of 4 int node from an edge addr. */
int ct_addr2node(int addr);

/**********/

/* print graph pointers for checking */
void printctree(int *ctree);

/**********/

/* allocate memory for ctree 3 ints pointer plus 1 check byte */
int *initctree();

/**********/

/* free memory of a tree for sorting */
void freectree(int **snodes);

/**********/

/* copy subtree recursively */
void copyOTU_trueID(int          *ctree,      /* in/out: tree array struct         */
             int          *ct_nextnode,/* in/out: next free node            */
             int           ct_curredge,/* in: currend edge to add subtree   */
             int          *ct_nextleaf,/* in/out: next free leaf (0-maxspc) */
             int           ed,         /* in: current edge in puzzling tree */
             ONEEDGE      *edge,       /* in: tree topology                 */
             int          *edgeofleaf, /* in: external edge list            */
             int           numleaves,  /* in: number of leaves              */
             int          *trueID);     /* in: permutation vector            */

/**********/

/* copy treestructure to sorting structure */
void copytree_trueID(int          *ctree,      /* out: copy for effective sorting */
              int          *trueID,     /* in:  permutation vector         */
              ONEEDGE      *edgeset,    /* in: intermediate tree topology  */
              int          *edgeofleaf, /*     dito.                       */
              int           numleaves);  /* in: number of leaves            */

/**********/

/* copy subtree recursively */
void copyOTU(int          *ctree,      /* in/out: tree array struct         */
             int          *ct_nextnode,/* in/out: next free node            */
             int           ct_curredge,/* in: currend edge to add subtree   */
             int          *ct_nextleaf,/* in/out: next free leaf (0-maxspc) */
             int           ed,         /* in: current edge in puzzling tree */
             ONEEDGE      *edge,       /* in: tree topology                 */
             int          *edgeofleaf, /* in: external edge list            */
             int           numleaves); /* in: number of leaves              */

/**********/

/* copy treestructure to sorting structure */
void copytree(int          *ctree,      /* out: copy for effective sorting */
              ONEEDGE      *edgeset,    /* in: intermediate tree topology  */
              int          *edgeofleaf, /*     dito.                       */
              int           rootleaf,
              int           numleaves);  /* in: number of leaves            */

/**********/

/* sort subtree from edge recursively by indices */
int sortOTU(int edge, int *ctree);

/**********/

/* sort ctree recursively by indices */
int sortctree(int *ctree);

/**********/

/* print recursively subtree of edge of sorted tree ctree */
void fprintfsortOTU(FILE *ofp, int edge, int *ctree);

/**********/

/* print recursively sorted tree ctree */
int fprintfsortctree(FILE *ofp, int *ctree);

/**********/

/* print recursively subtree of edge of sorted tree ctree to string */
void sprintfOTU(char *str, int *len, int edge, int *ctree);

/**********/

/* print recursively sorted tree ctree to string */
char *sprintfctree(int *ctree, int strglen);

/***********************************************/
/* establish and handle a list of sorted trees */
/***********************************************/

/* initialize structure */
treelistitemtype *inittreelist(int *treenum);

/**********/

/* malloc new tree list item */
treelistitemtype *gettreelistitem();

/**********/

/* free whole tree list */
void freetreelist(treelistitemtype **list,
                  int               *numitems,
                  int               *numsum);

/**********/

/* add tree to the tree list */
treelistitemtype *addtree2list(char             **tree,         /* sorted tree string */
                               int                numtrees,     /* how many occurred, e.g. in parallel */
                               treelistitemtype **list,         /* addr. of tree list */
                               int               *numitems,     
                               int               *numsum);

/**********/

/* resort list of trees by number of occurences for output */
void sortbynum(treelistitemtype *list, treelistitemtype **sortlist);

/**********/

/* print puzzling step tree stuctures for checking */
void printfpstrees(treelistitemtype *list);

/**********/

/* print sorted puzzling step tree stuctures with names */
void fprintfnexustaxablock(FILE *nexusfp, int   maxspc);  /* number of species */
/**********/

/* print sorted puzzling step tree stucture with names */
void fprintffullpstree(FILE *outf, char *treestr);

/**********/

/* print sorted puzzling step tree stuctures with names */
void fprintfsortedpstrees(FILE *output, 
                          treelistitemtype *list,  /* tree list */
                          int itemnum,             /* order number */
                          int itemsum,             /* number of trees */
                          int ftype,               /* what kind of output file? */
                          float cutoff);           /* cutoff percentage */

/* print sorted puzzling step tree stuctures with names */
void fprintfsortedpstrees_old(FILE *output, 
                          treelistitemtype *list,  /* tree list */
                          int itemnum,             /* order number */
                          int itemsum,             /* number of trees */
                          int comment,             /* with statistics, or puzzle report ? */
                          float cutoff);            /* cutoff percentage */

/**********/

/* print sorted tree topologies for checking */
void printfsortedpstrees(treelistitemtype *list);

/*******************************************/
/* end of tree sorting                     */
/*******************************************/


#endif /* TREESORT_H */

