////////////////////////////////////////////////////////////////////////
//
// parsetools.h - some functions for the MScore main program
//
// $Id: parsetools.h,v 1.6 2002/01/28 20:26:30 goetz Exp $
//
////////////////////////////////////////////////////////////////////////

#ifndef PARSETOOLS_H
#define PARSETOOLS_H

#include "version.h"
#include "stdio.h"

// function to print out program parameters (short help screen)
void printShortHelp()
{
  cerr << PRGNAME 
       << " [-h] [options] alignmentfile.msf" << endl << endl
       << "Give option -h to get more information." << endl << endl;
}

// function to print out helpscreen
void printLongHelp()
{
  cerr << endl
       << PRGNAME << " " << VERSION 
       << " by Goetz Schwandtner 12/2001"
       << " <goetz@informatik.uni-mainz.de>" << endl << endl
       << "Usage:" << endl;
  printShortHelp();
  cerr << "-h              this helpscreen" << endl
       << "-a              print alignment parameters"<< endl
       << "-f secfile.ftb  use secondary structure info"<< endl
       << "-r reffile.msf  use reference file (needed for -f as well)"<< endl
       << "-d              calculate distance score (to ref alignment)"<< endl
       << "-s secscale     use secondary struc. function for alpha helix"<<endl
       << "-S secoffs      offset for alpha helix (<1: prop, =>1: abs)"<< endl
       << "-l              piecewise linear alpha helix sec str function"<<endl
       << "-t secscale     use secondary struc. function for beta strand"<<endl
       << "-T secoffs      offset for beta strand (<1: prop, =>1: abs)"<< endl
       << "-L              piecewise linear beta strand sec str function"<<endl
       << "-m matrname     use scoring matrix given by name matrname"<< endl
       << "-M              show valid matix names"<< endl
       << "-g gappenalty   use value as gappenalty, otherwise mean of mism."
       << endl
       << "-p              scale score by pairwise sequence distances"<< endl
       << "-P scale        as -p, but distances are scaled to [0..scale]"<<endl
       << "                if negative scale is given, distances are" << endl
       << "                scaled to [0..-scale] and reordered such that"<<endl
       << "                min -> scale and max -> 0 holds" << endl
       << "-q matrname     specify scoring system for parwise dist" << endl
       << "                if different from -m ... or no -m is given" << endl
       << "-Q gappenalty   gappenalty to -q scoring system, otherwise mean"
       << " of mism" << endl
       << "-G familyfile   pairwise scaling of sequences using families"<< endl
       << "-o scale        scale for same group/family"<< endl
       << "-O scale        scale for different group/family"<< endl
       << "-v              be verbose: Print Alignment and column-scores"<<endl
       << "-V              as -v and print pairwise distances"<< endl
       << endl << endl;
}

// function to print out matrix names
void printMatrixNames()
{
  cerr << "Matrix name given to option -m may be one of the following:" <<endl
       << "blosum30, 35, 40, 50, 55, 62, 622, 65, 70, 75, 80, 85, 90" << endl
       << "pam20, 60, 120, 160, 250, 350" << endl
       << "md40, 120, 250, 350" << endl
       << "idmat" << endl
       << "gon40, 80, 120, 160, 250, 300, 350" << endl << endl
       << "No whitespaces between name and number are allowed!" << endl
       << "Don't forget to give a gap penalty using the -g option!" 
       << endl << endl;
}

// function for displaying fatal errors
void fatal(const char *msg)
{
  cerr << "FATAL:" << msg << endl;
  exit (-1);
}

// getting a ScoreMatrix object from the accoring name "name"
// the gap penalty has to be set using the "gap" parameter
const PredefScore parseScoreMatr( const char *name, int gap, bool gotGap)
{
  PredefScore sc;
  int num;        // number to determine subtype of matrix, ie. pam250 -> 250
  // check for known types and determine subtype; then set "matrix" variable
  if (sscanf(name, "blosum %d", &num) == 1)
    switch (num) {
    case 30:
      sc= gotGap ? PredefScore( blosum30mt, gap ) : PredefScore( blosum30mt );
      break;
    case 35:
      sc= gotGap ? PredefScore( blosum35mt, gap ) : PredefScore( blosum35mt );
      break;
    case 40:
      sc= gotGap ? PredefScore( blosum40mt, gap ) : PredefScore( blosum40mt );
      break;
    case 50:
      sc= gotGap ? PredefScore( blosum50mt, gap ) : PredefScore( blosum50mt );
      break;
    case 55:
      sc= gotGap ? PredefScore( blosum55mt, gap ) : PredefScore( blosum55mt );
      break;
    case 62:
      sc= gotGap ? PredefScore( blosum62mt, gap ) : PredefScore( blosum62mt );
      break;
    case 622:
      sc= gotGap ? PredefScore( blosum62mt2, gap ) :PredefScore( blosum62mt2 );
      break;
    case 65:
      sc= gotGap ? PredefScore( blosum65mt, gap ) : PredefScore( blosum65mt );
      break;
    case 70:
      sc= gotGap ? PredefScore( blosum70mt, gap ) : PredefScore( blosum70mt );
      break;
    case 80:
      sc= gotGap ? PredefScore( blosum80mt, gap ) : PredefScore( blosum80mt );
      break;
    case 85:
      sc= gotGap ? PredefScore( blosum85mt, gap ) : PredefScore( blosum85mt );
      break;
    case 90:
      sc= gotGap ? PredefScore( blosum90mt, gap ) : PredefScore( blosum90mt );
      break;
    default:
      fatal("Trying to use undefined BLOSUM-matrix!");
    }
  else if (sscanf(name, "pam %d", &num) == 1)
    switch (num) {
    case 20:
      sc= gotGap ? PredefScore( pam20mt, gap ) : PredefScore( pam20mt );
      break;
    case 60:
      sc= gotGap ? PredefScore( pam60mt, gap ) : PredefScore( pam60mt );
      break;
    case 120:
      sc= gotGap ? PredefScore( pam120mt, gap ) : PredefScore( pam120mt );
      break;
    case 160:
      sc= gotGap ? PredefScore( pam160mt, gap ) : PredefScore( pam160mt );
      break;
    case 250:
      sc= gotGap ? PredefScore( pam250mt, gap ) : PredefScore( pam250mt );
      break;
    case 350:
      sc= gotGap ? PredefScore( pam350mt, gap ) : PredefScore( pam350mt );
      break;
    default:
      fatal("Trying to use undefined PAM-matrix!");
    }
  else if (sscanf(name, "md %d", &num) == 1)
    switch (num) {
    case 40:
      sc= gotGap ? PredefScore( md_40mt, gap ) : PredefScore( md_40mt );
      break;
    case 120:
      sc= gotGap ? PredefScore( md_120mt, gap ) : PredefScore( md_120mt );
      break;
    case 250:
      sc= gotGap ? PredefScore( md_250mt, gap ) : PredefScore( md_250mt );
      break;
    case 350:
      sc= gotGap ? PredefScore( md_350mt, gap ) : PredefScore( md_350mt );
      break;
    default:
      fatal("Trying to use undefined MD-matrix!");
    }
  else if (!strcmp(name, "idmat"))
    sc= gotGap ? PredefScore( idmat, gap ) : PredefScore( idmat );
  else if (sscanf(name, "gon %d", &num) == 1)
    switch (num) {
    case 40:
      sc= gotGap ? PredefScore( gon40mt, gap ) : PredefScore( gon40mt );
      break;
    case 80:
      sc= gotGap ? PredefScore( gon80mt, gap ) : PredefScore( gon80mt );
      break;
    case 120:
      sc= gotGap ? PredefScore( gon120mt, gap ) : PredefScore( gon120mt );
      break;
    case 160:
      sc= gotGap ? PredefScore( gon160mt, gap ) : PredefScore( gon160mt );
      break;
    case 250:
      sc= gotGap ? PredefScore( gon250mt, gap ) : PredefScore( gon250mt );
      break;
    case 300:
      sc= gotGap ? PredefScore( gon300mt, gap ) : PredefScore( gon300mt );
      break;
    case 350:
      sc= gotGap ? PredefScore( gon350mt, gap ) : PredefScore( gon350mt );
      break;
    default:
      fatal("Trying to use undefined GON-matrix!");
    }
  else
    fatal("Trying to use undefined matrix!");
  return sc;
}

#endif
