/*
    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 <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(" Expert options:\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("    -J  print very expert options                                               \n");
    printf("    -o  reference file to superimpose on,                                       \n");
    printf("         all rotations are relative to the first model in this file             \n");
    printf("    -p  requested relative precision for convergence  {%s1e-7%s}                \n", tc_GREEN, tc_NC);
    printf("    -t  ndf, degrees of freedom for scaled inverse chi2                         \n");
    printf("    -Z  don't orient final superposition along principal axes                   \n");
    printf("    -z  n  fixed shape parameter for inverse gamma distribution                 \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("    -5  TenBerge algorithm for mean                                             \n");
    printf("    -6  write Bob Edgar's SSM (structure similarity matrix)                     \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("    -c  use ML atomic covariance weighting (fit correlations, slower)           \n");
    printf("    -e  embedding algorithm for initializing the average structure              \n");
    printf("          0 = none; use randomly chosen model                                   \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 landmarks for random coords generation                             \n");
    printf("    -K  n  number of mixtures for mixture Gaussian                              \n");
    printf("    -N  do a \"null run\" -- no superposition                                   \n");
    printf("    -O  Olve's segID file                                                       \n");
    printf("    -Q  n  scale all coordinates by this factor                                 \n");
    printf("    -R0 randomly translate and rotate before superpositioning                   \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 stats, gyration radii, Durbin-Watson autocorrelation        \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("  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 specifying the atom-types PDB-style            \n");
    printf("        e.g., -a ' CA  : N  '                                                   \n");
    printf("        selects the alpha carbons and backone nitrogens                         \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("    --amber  for reading AMBER8 formatted PDB files                             \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);

    printf("\n Morphometrics: \n");
    printf("    -d  calculate scale factors (for morphometrics)                             \n");
    printf("    -q  read and write Rohlf TPS morphometric landmark files                    \n");

    if (expert)
        Expert1();

    if (expert == 2)
        Expert2();

    printf("\n");
    printf(" Citations: \n");
    printf("   Douglas L. Theobald and Phillip A. Steindel (2012) \n");
    printf("   \"Optimal simultaneous superpositioning of multiple structures with missing\n");
    printf("   data.\"\n");
    printf("   Bioinformatics 28(15):1972-1979\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("   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("   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);
}


#if defined(__clang__)
    /* Clang/LLVM. ---------------------------------------------- */

#elif defined(__ICC) || defined(__INTEL_COMPILER)
    /* Intel ICC/ICPC. ------------------------------------------ */

#elif defined(__GNUC__) || defined(__GNUG__)
    /* GNU GCC/G++. --------------------------------------------- */

#elif defined(__HP_cc) || defined(__HP_aCC)
    /* Hewlett-Packard C/aC++. ---------------------------------- */

#elif defined(__IBMC__) || defined(__IBMCPP__)
    /* IBM XL C/C++. -------------------------------------------- */

#elif defined(_MSC_VER)
    /* Microsoft Visual Studio. --------------------------------- */

#elif defined(__PGI)
    /* Portland Group PGCC/PGCPP. ------------------------------- */

#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
    /* Oracle Solaris Studio. ----------------------------------- */

#endif


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\n", GSL_VERSION);
    fflush(NULL);
}
