/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2010 Douglas L. Theobald

    This program 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 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the:

    Free Software Foundation, Inc.,
    59 Temple Place, Suite 330,
    Boston, MA  02111-1307  USA

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

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <gsl/gsl_version.h>
#include "termcol.h"
#include "Error.h"

extern void
ilaver_(int *vers_major, int *vers_minor, int *vers_patch);

static void
Expert1(void)
{
    printf("\n");
    printf(" Default usage is equivalent to:                                                \n");
    printf("    theseus %s-a0 -e2 -g1 -i200 -k-1 -L0 -p1e-7 -v -P0%s your.pdb               \n", tc_GREEN, tc_NC);
    printf("\n");
    printf(" Expert options:\n");
    printf("    -b  Bayesian reference prior on inverse gamma scale param                   \n");
    printf("    -e  embedding algorithm for initializing the average structure              \n");
    printf("          0 = none; use randomly chosen model                                   \n");
    printf("         {%s2%s} = Maximum Likelihood                                           \n", tc_GREEN, tc_NC);
    printf("    -g  hierarchical model for variances                                        \n");
    printf("          0 = none (may not converge)                                           \n");
    printf("         {%s1%s} = inverse gamma distribution                                   \n", tc_GREEN, tc_NC);
    printf("    -k  constant minimum variance {%s-1%s}                                      \n", tc_GREEN, tc_NC);
    printf("         {if set to negative value, min var is determined empirically}          \n");
    printf("    -J  print very expert options                                               \n");
    printf("    -n  don't write transformed pdb file                                        \n");
    printf("    -o  reference file to superimpose on,                                       \n");
    printf("         all rotations are relative to the first model in this file             \n");
    printf("    -O  Olve's segID file                                                       \n");
    printf("    -p  requested relative precision for convergence  {%s1e-7%s}                \n", tc_GREEN, tc_NC);
    printf("    -Z  don't orient final superposition along principal axes                   \n");
    printf("    -z  n  fixed shape parameter for inverse gamma distribution                 \n");
    printf("    -8  preserve atom names; don't try to fix them for PDB3 standards           \n");
}


static void
Expert2(void)
{
    fputc('\n', stdout);
    printf(" Very expert options (i.e. unsupported, caveat emptor):\n");
    printf("    -0  don't calculate translations                                            \n");
    printf("    -1  don't calculate rotations                                               \n");
    printf("    -2  convert Lele file to PDB format                                         \n");
    printf("    -3  n:n  scale and shape params for inverse gamma for random variances      \n");
    printf("    -4  n:n:n  radius of gyration for Gaussian generated atoms                  \n");
    printf("    -6  write Bob Edgar's SSM (structure similarity matrix)                     \n");
    printf("    -7  very specific fix for Lele's 5x5 structured covariance matrix, test data\n");
    printf("    -8  hierarchical translations (broken)                                      \n");
    printf("    -B  read and write binary coordinate files                                  \n");
    printf("          1 = read a PDB file, write a binary of it and quit                    \n");
    printf("          2 = read a binary, superimpose, and write a PDB                       \n");
    printf("          3 = read a PDB file, superimpose, and write a binary                  \n");
    printf("          4 = read a binary, superimpose, and write a binary                    \n");
    printf("    -d  use ML dimensional/axes covariance weighting                            \n");
    printf("    -G  full 3D coordinate PCA (vector PCA is default)                          \n");
    printf("    -H  write 3D coordinate PCA morph files (for use with CNS/XPLOR)            \n");
    printf("    -j  # of times to bootstrap                                                 \n");
    printf("    -K  n  number of mixtures for mixture Gaussian                              \n");
    printf("    -m  Procrustes rotation method                                              \n");
    printf("    -N  do a \"null run\" -- no superposition                                   \n");
    printf("    -Q  do PCA across models (find families of models)                          \n");
    printf("    -q  axes variances for random structure generation (e.g. -q1:2:3)           \n");
    printf("    -R0 randomly translate and rotate before superpositioning                   \n");
    printf("    -t  weight by B-factor as a Bayesian prior                                  \n");
    printf("    -T  n  number of threads                                                    \n");
    printf("    -U  print logL for each iteration                                           \n");
    printf("    -u  calculate bias-corrected average structure                              \n");
    printf("    -W  wordy/verbose                                                           \n");
    printf("    -X  seed the algorithm with the superposition in the file                   \n");
    printf("    -x  no iterations in inner loop (superimposing to average)                  \n");
    printf("    -y  don't calculate the average structure                                   \n");
    printf("    -Y  print extra multivariate statistics, MV normality tests, etc.           \n");
}


void
Usage(int expert)
{
//    int vers_major, vers_minor, vers_patch;
    
//    ilaver_(&vers_major, &vers_minor, &vers_patch);

    PrintTheseusPre();
    printf("  Usage:                                                                        \n");
    printf("    theseus [options] <pdb files>                                               \n\n");
    /* printf("  For more help see the man page: type 'man theseus'                            \n\n"); */
    printf("  Algorithm options:                                                            \n");
    printf("    -a  atoms to include in superposition                                       \n");
    printf("          %s0%s = alpha carbons and phosphorous atoms                           \n", tc_GREEN, tc_NC);
    printf("          1 = backbone                                                          \n");
    printf("          2 = all                                                               \n");
    printf("          3 = alpha and beta carbons                                            \n");
    printf("          4 = all heavy atoms (all but hydrogens)                               \n");
    printf("            or                                                                  \n");
    printf("        a colon-delimited string explicitly specifying the atom-types PDB-style\n");
    printf("        e.g., -a' CA  : N  '                                                    \n");
    printf("        selects the alpha carbons and backone nitrogens                         \n");
    printf("    -c  use ML atomic covariance weighting (fit correlations, slower)           \n");
    printf("    -f  only read the first model of a multi-model PDB file                     \n");
    printf("    -i  maximum iterations {%s200%s}                                            \n", tc_GREEN, tc_NC);
    printf("    -l  superimpose with conventional least squares method                      \n");
    printf("    -s  residues to select (e.g. -s15-45:50-55) {%sall%s}                       \n", tc_GREEN, tc_NC);
    printf("    -S  residues to exclude (e.g. -S15-45:50-55) {%snone%s}                     \n", tc_GREEN, tc_NC);
    printf("    -%sv%s  use ML variance weighting (no correlations)                         \n", tc_GREEN, tc_NC);

    printf("\n Input/output options: \n");
    printf("    -A  sequence alignment file to use as a guide (CLUSTAL or A2M format)       \n");
    printf("    -E  print expert options                                                    \n");
    printf("    -F  print FASTA files of the sequences in PDB files and quit                \n");
    printf("    -h  help/usage                                                              \n");
    printf("    -I  just calculate statistics for input file (don't superposition)          \n");
    printf("    -M  file that maps sequences in the alignment file to PDB files             \n");
    printf("    -r  root name for output files {%stheseus%s}                                \n", tc_GREEN, tc_NC);
    printf("    -V  version                                                                 \n");
    printf("\n Principal components analysis: \n");
    printf("    -C  use covariance matrix for PCA (correlation matrix is default)           \n");
    printf("    -P  # of principal components to calculate {%s0%s}                          \n", tc_GREEN, tc_NC);

    if (expert == 1 || expert == 2)
        Expert1();

    if (expert == 2)
        Expert2();

    printf("\n");
    printf(" Citations: \n");
    printf("   Douglas L. Theobald and Deborah S. Wuttke (2006) \n");
    printf("   \"Empirical Bayes models for regularizing maximum likelihood estimation in\n");
    printf("   the matrix Gaussian Procrustes problem.\"\n");
    printf("   PNAS 103(49):18521-18527\n");
    printf("\n");
    printf("   Douglas L. Theobald and Deborah S. Wuttke (2006) \n");
    printf("   \"THESEUS: Maximum likelihood superpositioning and analysis of molecular\n");
    printf("   structures.\"\n");
    printf("   Bioinformatics 22(17):2171-2172\n");
    printf("\n");
    printf("   Douglas L. Theobald and Deborah S. Wuttke (2008) \n");
    printf("   \"Accurate structural correlations from maximum likelihood superpositions.\"\n");
    printf("   PLOS Computational Biology, 4(2):e43\n");
    printf("\n");
    printf("   http://www.theseus3d.org/\n");
    printf("   Compiled with GSL version %s\n", GSL_VERSION);
    //printf("   Compiled with LAPACK version %d.%d.%d\n", vers_major, vers_minor, vers_patch);
    printf("I===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-==I\n");
    printf("                            %s<  END THESEUS %s  >%s \n\n\n",
           tc_RED, VERSION, tc_NC);
    fflush(NULL);
}


void
PrintTheseusPre(void)
{
    printf("\n\n");
    printf("                            %s< BEGIN THESEUS %s >%s \n", tc_RED, VERSION, tc_NC);
    printf("I===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-=I\n");
    printf("I                %sTHESEUS%s: Maximum likelihood multiple superpositioning        I\n", tc_CYAN, tc_NC);
    printf("I=-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===I\n");
}


void
PrintTheseusTag(void)
{
    printf("    Done. \n");
    printf("I===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-===-==I\n");
    printf("                            %s<  END THESEUS %s  >%s \n\n\n",
           tc_RED, VERSION, tc_NC);
    fflush(NULL);
}


void
Version(void)
{
    printf("\n  THESEUS version %s compiled on %s %s\n  by user %s with machine \"%s\" \n\n",
           VERSION, __DATE__, __TIME__, getenv("USER"), getenv("HOST"));
    printf("  Compiled with GSL version %s\n", GSL_VERSION);
    fflush(NULL);
}
