/*
FILE:     maxit_main.C
*/
/*
VERSION:  1.600
*/
/*
DATE:     2/3/2005
*/
/*
  Comments and Questions to: sw-help@rcsb.rutgers.edu
*/
/*
COPYRIGHT 1999-2005 Rutgers - The State University of New Jersey

This software is provided WITHOUT WARRANTY OF MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE OR ANY OTHER WARRANTY, EXPRESS OR
IMPLIED.  RUTGERS MAKE NO REPRESENTATION OR WARRANTY THAT THE
SOFTWARE WILL NOT INFRINGE ANY PATENT, COPYRIGHT OR OTHER
PROPRIETARY RIGHT.

The user of this software shall indemnify, hold harmless and defend
Rutgers, its governors, trustees, officers, employees, students,
agents and the authors against any and all claims, suits,
losses, liabilities, damages, costs, fees, and expenses including
reasonable attorneys' fees resulting from or arising out of the
use of this software.  This indemnification shall include, but is
not limited to, any and all claims alleging products liability.
*/
/*
               PDB SOFTWARE LICENSE AGREEMENT

BY CLICKING THE ACCEPTANCE BUTTON OR INSTALLING OR USING 
THIS "SOFTWARE, THE INDIVIDUAL OR ENTITY LICENSING THE  
SOFTWARE ("LICENSEE") IS CONSENTING TO BE BOUND BY AND IS 
BECOMING A PARTY TO THIS AGREEMENT.  IF LICENSEE DOES NOT 
AGREE TO ALL OF THE TERMS OF THIS AGREEMENT
THE LICENSEE MUST NOT INSTALL OR USE THE SOFTWARE.

1. LICENSE AGREEMENT

This is a license between you ("Licensee") and the Protein Data Bank (PDB) 
at Rutgers, The State University of New Jersey (hereafter referred to 
as "RUTGERS").   The software is owned by RUTGERS and protected by 
copyright laws, and some elements are protected by laws governing 
trademarks, trade dress and trade secrets, and may be protected by 
patent laws. 

2. LICENSE GRANT

RUTGERS grants you, and you hereby accept, non-exclusive, royalty-free 
perpetual license to install, use, modify, prepare derivative works, 
incorporate into other computer software, and distribute in binary 
and source code format, or any derivative work thereof, together with 
any associated media, printed materials, and on-line or electronic 
documentation (if any) provided by RUTGERS (collectively, the "SOFTWARE"), 
subject to the following terms and conditions: (i) any distribution 
of the SOFTWARE shall bind the receiver to the terms and conditions 
of this Agreement; (ii) any distribution of the SOFTWARE in modified 
form shall clearly state that the SOFTWARE has been modified from 
the version originally obtained from RUTGERS.  

2. COPYRIGHT; RETENTION OF RIGHTS.  

The above license grant is conditioned on the following: (i) you must 
reproduce all copyright notices and other proprietary notices on any 
copies of the SOFTWARE and you must not remove such notices; (ii) in 
the event you compile the SOFTWARE, you will include the copyright 
notice with the binary in such a manner as to allow it to be easily 
viewable; (iii) if you incorporate the SOFTWARE into other code, you 
must provide notice that the code contains the SOFTWARE and include 
a copy of the copyright notices and other proprietary notices.  All 
copies of the SOFTWARE shall be subject to the terms of this Agreement.  

3. NO MAINTENANCE OR SUPPORT; TREATMENT OF ENHANCEMENTS 

RUTGERS is under no obligation whatsoever to: (i) provide maintenance 
or support for the SOFTWARE; or (ii) to notify you of bug fixes, patches, 
or upgrades to the features, functionality or performance of the 
SOFTWARE ("Enhancements") (if any), whether developed by RUTGERS 
or third parties.  If, in its sole discretion, RUTGERS makes an 
Enhancement available to you and RUTGERS does not separately enter 
into a written license agreement with you relating to such bug fix, 
patch or upgrade, then it shall be deemed incorporated into the SOFTWARE 
and subject to this Agreement. You are under no obligation whatsoever 
to provide any Enhancements to RUTGERS or the public that you may 
develop over time; however, if you choose to provide your Enhancements 
to RUTGERS, or if you choose to otherwise publish or distribute your 
Enhancements, in source code form without contemporaneously requiring 
end users or RUTGERS to enter into a separate written license agreement 
for such Enhancements, then you hereby grant RUTGERS a non-exclusive,
royalty-free perpetual license to install, use, modify, prepare
derivative works, incorporate into the SOFTWARE or other computer
software, distribute, and sublicense your Enhancements or derivative
works thereof, in binary and source code form.

4. FEES.  There is no license fee for the SOFTWARE.  If Licensee
wishes to receive the SOFTWARE on media, there may be a small charge
for the media and for shipping and handling.  Licensee is
responsible for any and all taxes.

5. TERMINATION.  Without prejudice to any other rights, Licensor
may terminate this Agreement if Licensee breaches any of its terms
and conditions.  Upon termination, Licensee shall destroy all
copies of the SOFTWARE.

6. PROPRIETARY RIGHTS.  Title, ownership rights, and intellectual
property rights in the Product shall remain with RUTGERS.  Licensee 
acknowledges such ownership and intellectual property rights and will 
not take any action to jeopardize, limit or interfere in any manner 
with RUTGERS' ownership of or rights with respect to the SOFTWARE.  
The SOFTWARE is protected by copyright and other intellectual 
property laws and by international treaties.  Title and related 
rights in the content accessed through the SOFTWARE is the property 
of the applicable content owner and is protected by applicable law.  
The license granted under this Agreement gives Licensee no rights to such
content.

7. DISCLAIMER OF WARRANTY.  THE SOFTWARE IS PROVIDED FREE OF 
CHARGE, AND, THEREFORE, ON AN "AS IS" BASIS, WITHOUT WARRANTY OF 
ANY KIND, INCLUDING WITHOUT LIMITATION THE WARRANTIES THAT IT 
IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE 
OR NON-INFRINGING.  THE ENTIRE RISK AS TO THE QUALITY AND 
PERFORMANCE OF THE SOFTWARE IS BORNE BY LICENSEE.  SHOULD THE 
SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, THE LICENSEE AND NOT 
LICENSOR ASSUMES THE ENTIRE COST OF ANY SERVICE AND REPAIR.  
THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF 
THIS AGREEMENT.  NO USE OF THE PRODUCT IS AUTHORIZED HEREUNDER 
EXCEPT UNDER THIS DISCLAIMER.

8. LIMITATION OF LIABILITY.  TO THE MAXIMUM EXTENT PERMITTED BY
APPLICABLE LAW,  IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY 
INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 
OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, INCLUDING, 
WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL 
OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF ADVISED OF THE
POSSIBILITY THEREOF. 
*/
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/utsname.h>

#include "_maxit.h"
#include "erf_category.h"
#include "erf_util.h"
#include "ndb_filterexitlib.h"
#include "ndb_misclib.h"
#include "util.h"

#define MXSTRLEN                       200

#define MAX_OPTION_PDB_TO_CIF            1
#define MAX_OPTION_CIF_TO_PDB            2
#define MAX_OPTION_PDB_TO_NDB            3
#define MAX_OPTION_NDB_TO_PDB            4
#define MAX_OPTION_NDB_TO_CIF            5
#define MAX_OPTION_CIF_TO_NDB            6
#define MAX_OPTION_PDB_TO_ENCIF          7
#define MAX_OPTION_CIF_TO_CIF            8
#define MAX_OPTION_VALIDATION_PDB        9
#define MAX_OPTION_VALIDATION_NDB       10
#define MAX_OPTION_VALIDATION_CIF       11
#define MAX_OPTION_SYMMETRY_NDB         12
#define MAX_OPTION_SYMMETRY_CIF         13
#define MAX_OPTION_NCS_NDB              14
#define MAX_OPTION_NCS_CIF              15
#define MAX_OPTION_CHIRALITY_NDB        16
#define MAX_OPTION_CHIRALITY_CIF        17
#define MAX_OPTION_CORRESPND_NDB        18
#define MAX_OPTION_CORRESPND_CIF        19
#define MAX_OPTION_HYDROGEN_NDB         20
#define MAX_OPTION_HYDROGEN_CIF         21
#define MAX_OPTION_DEL_ATOM_NDB         22
#define MAX_OPTION_DEL_ATOM_CIF         23
#define MAX_OPTION_ADD_ATOM_NDB         24
#define MAX_OPTION_ADD_ATOM_CIF         25
#define MAX_OPTION_DEL_RESIDUE_NDB      26
#define MAX_OPTION_DEL_RESIDUE_CIF      27
#define MAX_OPTION_ADD_RESIDUE_NDB      28
#define MAX_OPTION_ADD_RESIDUE_CIF      29
#define MAX_OPTION_MERGE_RMK_NDB        30
#define MAX_OPTION_MERGE_RMK_CIF        31
#define MAX_OPTION_MERGE_COR_NDB        32
#define MAX_OPTION_MERGE_COR_CIF        33
#define MAX_OPTION_MOVE_HOH_NDB         34
#define MAX_OPTION_MOVE_HOH_CIF         35
#define MAX_OPTION_RES_NAME_NDB         36
#define MAX_OPTION_RES_NAME_CIF         37
#define MAX_OPTION_REP_RESIDUE_NDB      38
#define MAX_OPTION_REP_RESIDUE_CIF      39
#define MAX_OPTION_CHANGE_SYMMETRY      40
#define MAX_OPTION_CHANGE_NON_SYMM      41
#define MAX_OPTION_UPDATE_NA_FEATURE    42
#define MAX_OPTION_ORTH_TO_FRAC         43
#define MAX_OPTION_FRAC_TO_ORTH         44
#define MAX_OPTION_FRAC_TO_ORTH_CIF     45
#define MAX_OPTION_NDB_TO_NDBCIF        46
#define MAX_OPTION_NDBCIF_TO_NDB        47
#define MAX_OPTION_LAYER1_TO_2          48
#define MAX_OPTION_Q_ATOM_CIF           49
#define MAX_OPTION_MERGE_WATER          50
#define MAX_OPTION_GET_MATRIX           51
#define MAX_OPTION_UPDATE_HYDROGEN      52
#define MAX_OPTION_CHECK_FILE           53
#define MAX_OPTION_CLASSIFICATION       54
#define MAX_OPTION_BIOL_UNIT            55
#define MAX_OPTION_EXCHANGE             56
#define MAX_OPTION_ONE_LETTER_CODE      57
#define MAX_OPTION_HPUB_LETTER          58
#define MAX_OPTION_COMPLEXITY           59
#define MAX_OPTION_PACKING              60
#define MAX_OPTION_RENUMBER_PDB         61

static int output_ndb_format = NDB_FILE_FORMAT_NDBCIF;
static int is_prev_check = 0;
static int is_separate = 0;
static int is_short_cut = 0;
static int short_version = 0;
static int remark = 0;
static int is_binary = 0;
static int standardized = 0;
static int is_iupac = 0;
static int is_special = 0;
static int delete_atom = 0;
static int recover_asym = 0;
static int id_option = 0;
static int exchange_in = 0;
static int exchange_out = 0;
static int public_flag = 0;
static int together = 0;
static int no_deriv = 0;
static int identical_flag = 0;
static int symmetry_flag = 0;
static int keep_contact_author = 0;
static int no_pdbx_strand_id = 0;
static int is_nmr_view = 0;

static char File_ID[100];
static char object_name[MXSTRLEN];
static char defalut_dir[] = "/ndbapps";

static void maxit(const int choice, const int num_file, const char *infile_name,
               const char *support_file, FILE *summary, FILE *summary1);
static void maxit_check_files(const int choice, const char *infile_name, char *outfile_name);
static void maxit_usage(const char *prog_name);

int main(int argc, char *argv[])
{
       root_dir = getenv("RCSBROOT");
       if (root_dir == NULL) root_dir = defalut_dir;

       int i, answer, commandLine = 0, temp_c = 0, num_file = 0;
       char infile_name1[MXSTRLEN], reply[MXSTRLEN], errfile[MXSTRLEN];
       char support_file[MXSTRLEN], logfile[100];
       FILE *infile = NULL, *summary = NULL, *summary1 = NULL;
       struct stat stat1;

       memset(infile_name1, 0, MXSTRLEN);
       memset(support_file, 0, MXSTRLEN);
       memset(File_ID, 0, 100);
       memset(object_name, 0, MXSTRLEN);
       strcpy(logfile, "maxit.err");

       for (i = 1; i < argc; i++) {
            if (argv[i][0] == '-' ) {
                 if (!strcmp(argv[i], "-f")) {
                      i++; commandLine = 1;
                      strcpy(infile_name1, argv[i]);
                 } else if (!strcmp(argv[i], "-i")) {
                      i++; commandLine = 1;
                      strcpy(infile_name1, argv[i]);
                      num_file = 1;
                 } else if (!strcmp(argv[i], "-ib")) {
                      i++; commandLine = 1;
                      strcpy(infile_name1, argv[i]);
                      num_file = 1;
                      is_binary = 1;
                 } else if (!strcmp(argv[i], "-o")) {
                      i++; temp_c = atoi(argv[i]);
                 } else if (!strcmp(argv[i], "-NDB")) {
                      output_ndb_format = NDB_FILE_FORMAT_NDB;
                 } else if (!strcasecmp(argv[i], "-nmr")) {
                      is_nmr_view = 1;
                 } else if (!strcmp(argv[i], "-p")) {
                      is_prev_check = 1;
                 } else if (!strcmp(argv[i], "-adit")) {
                      is_prev_check = 2;
                 } else if (!strcmp(argv[i], "-path")) {
                      i++; root_dir = argv[i];
                 } else if (!strcasecmp(argv[i], "-s")) {
                      is_separate = 1;
                 } else if (!strcasecmp(argv[i], "-l")) {
                      is_short_cut = 1;
                 } else if (!strcasecmp(argv[i], "-M")) {
                      i++; strcpy(support_file, argv[i]);
                 } else if (!strcasecmp(argv[i], "-filename")) {
                      i++; strcpy(File_ID, argv[i]);
                 } else if (!strcasecmp(argv[i], "-ob")) {
                      i++; strcpy(object_name, argv[i]);
                      is_binary = 2;
                 } else if (!strcasecmp(argv[i], "-output")) {
                      i++; strcpy(logfile, argv[i]);
                 } else if (!strcasecmp(argv[i], "-x")) {
                 } else if (!strcasecmp(argv[i], "-remark")) {
                      remark = 1;
                 } else if (!strcasecmp(argv[i], "-standard")) {
                      standardized = 1;
                 } else if (!strcasecmp(argv[i], "-iupac")) {
                      is_iupac = 1;
/*
                 } else if (!strcasecmp(argv[i], "-special")) {
                      i++; is_special = atoi(argv[i]);
*/
                 } else if (!strcasecmp(argv[i], "-replace")) {
                      is_special = 2;
                 } else if (!strcasecmp(argv[i], "-delete")) {
                      delete_atom = 1;
                 } else if (!strcasecmp(argv[i], "-asym")) {
                      recover_asym = 1;
                 } else if (!strcasecmp(argv[i], "-pdbids")) {
                      id_option |= 1;
                 } else if (!strcasecmp(argv[i], "-ndbids")) {
                      id_option |= 2;
/*
                 } else if (!strcasecmp(argv[i], "-rcsbids")) {
                      id_option |= 4;
*/
                 } else if (!strcasecmp(argv[i], "-exchange_in")) {
                      exchange_in = 1;
                 } else if (!strcasecmp(argv[i], "-exchange_out")) {
                      exchange_out = 1;
                 } else if (!strcasecmp(argv[i], "-public")) {
                      public_flag = 1;
                 } else if (!strcasecmp(argv[i], "-together")) {
                      together = 1;
                 } else if (!strcasecmp(argv[i], "-short")) {
                      short_version = 1;
                 } else if (!strcasecmp(argv[i], "-no_deriv")) {
                      no_deriv = 1;
                 } else if (!strcasecmp(argv[i], "-identical")) {
                      identical_flag = 1;
                 } else if (!strcasecmp(argv[i], "-get_biol_unit")) {
                      symmetry_flag = 1;
                 } else if (!strcasecmp(argv[i], "-keep_contact_author")) {
                      keep_contact_author = 1;
                 } else if (!strcasecmp(argv[i], "-no_pdbx_strand_id")) {
                      no_pdbx_strand_id = 1;
                 } else {
                      maxit_usage("maxit");
                      exit(1);
                 }
            } else {
                 maxit_usage("maxit");
                 exit(1);
            }
       }
       // if (!id_option) id_option = 1;
       if (exchange_out) standardized = 1;

       ndb_set_debug_level(NDB_MSG_INFO);
       ndb_open_log("maxit", logfile);

       if (!ndb_filterlib_init(root_dir)) {
            printf("Initial filter libaray failed\n");
            return -1;
       }
       if (!ndb_maxitlib_init()) {
            printf("Initial maxit libaray failed\n");
            return -1;
       }
       for (i = 0; i < NUM_TOKEN; i++) {
            Check_Format[i].Token_ID = find_card_id(Check_Format[i].TokenName);
       }

       while (temp_c != 'Q' && temp_c != 'q') {
            if (!commandLine) {
                 num_file = 0;
                 system("clear");
                 printf("\n\nMaxIT\n\n");
                 printf("[1]  Translate PDB format file(s) to CIF format file(s)\n");
                 printf("[2]  Translate CIF format file(s) to PDB format file(s)\n");
                 printf("[3]  Translate PDB format file(s) to NDB format file(s)\n");
                 printf("[4]  Translate NDB format file(s) to PDB format file(s)\n");
                 printf("[5]  Translate NDB format file(s) to mmCIF format file(s)\n");
                 printf("[6]  Translate CIF format file(s) to NDB format file(s)\n");
                 printf("[7]  Translate PDB format file(s) to encapsulated CIF file(s)\n");
                 printf("[8]  Translate CIF format file(s) to mmCIF format file(s)\n");
                 printf("[9]  Validation: PDB format file(s)\n");
                 printf("[10] Validation: NDB format file(s)\n");
                 printf("[11] Validation: CIF format file(s)\n");
                 printf("[12] Generate symmetry related strands to NDB files(s)\n");
                 printf("[13] Generate symmetry related strands to mmCIF files(s)\n");
                 printf("[14] Generate NCS related strands to NDB file(s)\n");
                 printf("[15] Generate NCS related strands to mmCIF file(s)\n");
                 printf("[16] Correct Chirality of O1P/O2P and H atoms to NDB file(s)\n");
                 printf("[17] Correct Chirality of O1P/O2P and H atoms to mmCIF file(s)\n");
                 printf("[18] Create Correspondences between deposited and standard hydrogen atoms\n");
                 printf("     to NDB file(s)\n");
                 printf("[19] Create Correspondences between deposited and standard hydrogen atoms\n");
                 printf("     to mmCIF file(s)\n");
                 printf("[20] Remove Hydrogen atom(s) to NDB file(s)\n");
                 printf("[21] Remove Hydrogen atom(s) to mmCIF file(s)\n");
                 printf("[22] Delete Atom(s) to NDB file(s)\n");
                 printf("[23] Delete Atom(s) to mmCIF file(s)\n");
                 printf("[24] Insert Atom(s) to NDB file(s)\n");
                 printf("[25] Insert Atom(s) to mmCIF file(s)\n");
                 printf("[26] Delete Residue(s) to NDB file(s)\n");
                 printf("[27] Delete Residue(s) to mmCIF file(s)\n");
                 printf("[28] Insert Residue(s) to NDB file(s)\n");
                 printf("[29] Insert Residue(s) to mmCIF file(s)\n");
                 printf("[30] Merge Remarks to NDB file\n");
                 printf("[31] Merge Remarks to mmCIF file\n");
                 printf("[32] Merge Coordinates to NDB file\n");
                 printf("[33] Merge Coordinates to mmCIF file\n");
                 printf("[34] Moving Water(s) to NDB file(s)\n");
                 printf("[35] Moving Water(s) to CIF file(s)\n");
                 printf("[36] Switch Residue Name(s) to NDB file(s)\n");
                 printf("[37] Switch Residue Name(s) to CIF file(s)\n");
                 printf("[38] Replace Residue(s) to NDB file(s)\n");
                 printf("[39] Replace Residue(s) to mmCIF file(s)\n");
                 printf("[40] Moving coordinates using symmetry operation to mmCIF file(s)\n");
                 printf("[41] Moving coordinates using non-symmetry operation to mmCIF file(s)\n");
                 printf("[42] Update NA features to mmCIF file(s)\n");
                 printf("[43] Convert orthogonal coordinates to fractional using NDB files(s)\n");
                 printf("[44] Convert fractional coordinates to orthogonal using NDB files(s)\n");
                 printf("[45] Convert fractional coordinates to orthogonal using mmCIF file(s)\n");
                 printf("[46] Translating NDB format file(s) to NDBCIF format file(s)\n");
                 printf("[47] Translating NDBCIF format file(s) to NDB format file(s)\n");
                 printf("[48] Adding REVDAT for Layer1 to Layer2 using CIF file(s)\n");
                 printf("[49] Remove Q atom(s) to mmCIF file(s)\n");
                 printf("[50] Reorder Het Group(s) and Waters to mmCIF file(s)\n");
                 printf("[51] Get Virus Matrices to mmCIF file(s)\n");
                 printf("[52] Update Hydrogen Nomenclature to PDB file(s)\n");
                 printf("[53] Check PDB file(s)\n");
                 printf("[54] Get Classification of PDB file(s)\n");
                 printf("[55] Get Biological Unit PDB file(s)\n");
                 printf("[56] Convert mmCIF from exchange to internal dictionary\n");
                 printf("[57] Get one letter sequence from coordinates\n");
                 printf("[58] Get letter for 'HOLD FOR PUBLICATION' structures\n");
                 printf("[Q]  Quit\n");
                 printf("\nEnter selection -->");
                 fflush(stdout);
                 fflush(stdin);
                 fscanf(stdin, "%s", reply);
                 if (reply[0] == 'Q' || reply[0] == 'q') temp_c = 'q';
                 else temp_c = atoi(reply);
            }

            if (temp_c == 'Q' || temp_c == 'q') break;
            else if (temp_c < 1 || temp_c > MAX_OPTION_RENUMBER_PDB) {
                 if (!commandLine) continue;
                 else              break;
            } else {
                 if (!strcmp(infile_name1, "")) {
                      if (temp_c >= MAX_OPTION_DEL_ATOM_NDB &&
                          temp_c <= MAX_OPTION_MERGE_COR_CIF) {
                           num_file = 1;
                           printf("Please enter the name of a single file to be processed-> ");
                           fflush(stdout);
                           fflush(stdin);
                           fscanf(stdin, "%s", infile_name1);
                           ndb_clean_string(infile_name1);
                           printf("Please enter the name of the support file-> ");
                           fflush(stdout);
                           fflush(stdin);
                           fscanf(stdin, "%s", support_file);
                           ndb_clean_string(support_file);
                      } else {
                           printf("Please enter the number of files to be translated\n\n");
                           printf(" [1] for one file \n");
                           printf(" [2] for more than one file\n");
                           printf("\n     Enter selection (default: 1) -->");
                           fflush(stdin);
                           answer = fgetc(stdin);
                           if (answer == '2') num_file = 0;
                           else               num_file = 1;
                           fflush(stdin);
                           if (num_file == 1)
                                printf("\n\nPlease enter the name of a single file to be processed-> ");
                           else printf("\n\nPlease enter the name of the list of files to be processed-> ");
                           fflush(stdout);
                           fflush(stdin);
                           fscanf(stdin, "%s", infile_name1);
                           ndb_clean_string(infile_name1);
                      }
                 }
              
                 if (strcmp(infile_name1, "") && strcmp(infile_name1, "\n") &&
                     strcmp(infile_name1, "\t"))  {
                      if (stat(infile_name1, &stat1) < 0) {
                           fprintf(stdout, "File %s did not exist.\n", infile_name1);
                           ndb_log_message(NDB_MSG_ERR, "File %s did not exist.\n", infile_name1);
                           memset(infile_name1, 0, MXSTRLEN);
                           if (commandLine) break;
                           else          continue;
                      }
                      infile = fopen(infile_name1, "r");
                      if (infile == (FILE *) NULL) {
                           fprintf(stdout, "Can not read file %s!\n\n", infile_name1);
                           ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n\n", infile_name1);
                           memset(infile_name1, 0, MXSTRLEN);
                           if (commandLine) break;
                           else          continue;
                      }
                      for (i = strlen(infile_name1) - 1; i >= 0; i--)
                           if (infile_name1[i] == '/') break;
                      strcpy(reply, &infile_name1[i+1]);
                      if (temp_c == MAX_OPTION_CLASSIFICATION) {
                           summary = fopen("SUMMARY.bcp", "w");
                           summary1 = fopen("SUMMARY1.bcp", "w");
                      }
                      if (num_file == 0) {
                           num_file = 0;
                           while (!feof(infile)) {
                                memset(errfile, 0, MXSTRLEN); 
                                fscanf(infile, "%s", errfile);
                                num_file++;
                                ndb_clean_string(errfile);
                                if (strcmp(errfile, "") && strcmp(errfile, "\n") &&
                                    strcmp(errfile, "\t"))
                                     maxit(temp_c, num_file, errfile, support_file, summary, summary1);
                           }
                      } else {
                           maxit(temp_c, num_file, infile_name1, support_file, summary, summary1);
                      }
                      if (summary) fclose (summary);
                      if (summary1) fclose (summary1);
                      fclose(infile);
                 }
            }
            temp_c = 0;
            memset(infile_name1, 0, MXSTRLEN);
            if (commandLine) break;
       }
       ndb_filterlib_close();
       ndb_close_log();
       return 0;
}

static void maxit(const int choice, const int num_file, const char *infile_name,
               const char *support_file, FILE *summary, FILE *summary1)
{
       int fd, i, compressFlag = 0;
       char tmp_infile[MXSTRLEN], tmpfile[MXSTRLEN], name[100];
       char outfile_name[MXSTRLEN], buffer[100], command[800], templateFileName[9] = "./XXXXXX";
       CifString message("");
       FILE *tlog = NULL;
       struct stat stat1;
       struct utsname sname;

       if (stat(infile_name, &stat1) < 0) {
            fprintf(stdout, "File %s did not exist.\n", infile_name);
            ndb_log_message(NDB_MSG_ERR, "File %s did not exist.\n", infile_name);
            return;
       }
       if (strcmp(support_file, "") && stat(support_file, &stat1) < 0) {
            fprintf(stdout, "File %s did not exist.\n", support_file);
            ndb_log_message(NDB_MSG_ERR, "File %s did not exist.\n", support_file);
            return;
       }
       strcpy(name, templateFileName);
       fd = mkstemp(name);
       close (fd);
       for (i = strlen(name) - 1; i >= 0; i--) {
            if (name[i] == '/') break;
       }
       strcpy(tmp_infile, &name[i + 1]);

       strcpy(tmpfile, infile_name);
       for (i = strlen(tmpfile) - 1; i >= 0; i--) {
            if (tmpfile[i] == '/') {
                 strcpy(tmpfile, &tmpfile[i + 1]);
                 break;
            }
       }
       compressFlag = 0;
       if (!strcmp(&tmpfile[strlen(tmpfile)-2], ".Z")) {
            compressFlag = 1;
            tmpfile[strlen(tmpfile)-2] = '\0';
            strcpy(name, templateFileName);
            fd = mkstemp(name);
            close (fd);
            for (i = strlen(name) - 1; i >= 0; i--) {
                 if (name[i] == '/') {
                      strcpy(name, &name[i + 1]);
                      break;
                 }
            }
            sprintf(command, "zcat %s > %s", infile_name, name);
            system(command);
            preprocess_file(name, tmp_infile);
            sprintf(command, "rm %s", name);
            system(command);
       } else if (!strcmp(&tmpfile[strlen(tmpfile)-3], ".gz")) {
            compressFlag = 2;
            tmpfile[strlen(tmpfile)-3] = '\0';
            strcpy(name, templateFileName);
            fd = mkstemp(name);
            close (fd);
            for (i = strlen(name) - 1; i >= 0; i--) {
                 if (name[i] == '/') {
                      strcpy(name, &name[i + 1]);
                      break;
                 }
            }
            uname(&sname);
            if (!strncmp(sname.sysname, "Linux", 5))
                 sprintf(command, "zcat %s > %s", infile_name, name);
            else sprintf(command, "gzcat %s > %s", infile_name, name);
            system(command);
            preprocess_file(name, tmp_infile);
            sprintf(command, "rm %s", name);
            system(command);
       } else preprocess_file(infile_name, tmp_infile);

       if (strcmp(support_file, "")) {
            strcpy(name, templateFileName);
            fd = mkstemp(name);  
            close (fd);
            for (i = strlen(name) - 1; i >= 0; i--) {
                 if (name[i] == '/') {
                      strcpy(name, &name[i + 1]);
                      break;
                 }
            }
            sprintf(command, "mv %s %s", support_file, name);
            system(command);
            preprocess_file(name, support_file);
            sprintf(command, "rm %s", name);
            system(command);
       }

       maxit_check_files(choice, tmpfile, outfile_name);
       if (strcmp(object_name, "")) strcpy(outfile_name, object_name);

       switch (choice) {
            case MAX_OPTION_PDB_TO_CIF:
                 fprintf(stdout, "Translating a PDB format file [%d] %s to a mmCIF file %s\n",
                                 num_file, tmpfile, outfile_name);
                 pdb_to_cif(tmpfile, tmp_infile, outfile_name, is_binary, public_flag, standardized,
                            is_iupac, id_option, exchange_out, together, no_deriv,
                            support_file, keep_contact_author, no_pdbx_strand_id, is_nmr_view);
                 break;
            case MAX_OPTION_CIF_TO_PDB:
                 fprintf(stdout, "Translating a CIF format file [%d] %s to a PDB file %s\n",
                                 num_file, tmpfile, outfile_name);
                 cif_to_pdb(tmpfile, tmp_infile, outfile_name, remark, is_binary, is_special, is_iupac,
                            exchange_in, symmetry_flag, support_file, is_nmr_view);
                 break;
            case MAX_OPTION_PDB_TO_NDB:
                 fprintf(stdout, "Translating a PDB format file [%d] %s to a NDB file %s\n",
                                 num_file, tmpfile, outfile_name);
                 pdb_to_ndb(tmpfile, tmp_infile, outfile_name, output_ndb_format, public_flag,
                             short_version, support_file, is_nmr_view);
                 break;
            case MAX_OPTION_NDB_TO_PDB:
                 fprintf(stdout, "Translating a NDB format file [%d] %s to a PDB file %s\n",
                                 num_file, tmpfile, outfile_name);
                 ndb_to_pdb(tmpfile, tmp_infile, outfile_name, remark, is_iupac);
                 break;
            case MAX_OPTION_NDB_TO_CIF:
                 fprintf(stdout, "Translating a NDB format file [%d] %s to a mmCIF file %s\n",
                                 num_file, tmpfile, outfile_name);
                 ndb_to_cif(tmpfile, tmp_infile, outfile_name, is_binary, standardized, is_iupac,
                            id_option, exchange_out, together, no_deriv, keep_contact_author,
                            no_pdbx_strand_id);
                 break;
            case MAX_OPTION_CIF_TO_NDB:
                 fprintf(stdout, "Translating a CIF format file [%d] %s to a NDB file %s\n",
                                 num_file, tmpfile, outfile_name);
                 cif_to_ndb(tmpfile, tmp_infile, outfile_name, output_ndb_format, is_binary, is_special,
                       exchange_in, short_version, symmetry_flag, support_file, is_nmr_view);
                 break;
            case MAX_OPTION_PDB_TO_ENCIF:
                 fprintf(stdout, "Translating a PDB format file [%d] %s to a encapsulated CIF file %s\n",
                                 num_file, tmpfile, outfile_name);
                 pdb_to_encapsulated_cif(tmpfile, tmp_infile, outfile_name, id_option, exchange_out, is_nmr_view);
                 break;
            case MAX_OPTION_CIF_TO_CIF:
                 fprintf(stdout, "Translating a CIF format file [%d] %s to a mmCIF file %s\n",
                                 num_file, tmpfile, outfile_name);
                 cif_to_cif(tmpfile, tmp_infile, outfile_name, 0, is_binary, standardized, is_special,
                    delete_atom, is_iupac, recover_asym, id_option, exchange_in, exchange_out,
                    together, no_deriv, symmetry_flag, support_file, keep_contact_author,
                    no_pdbx_strand_id, is_nmr_view);
                 break;
            case MAX_OPTION_VALIDATION_PDB:
                 fprintf(stdout, "Validation of a PDB format file [%d] %s\n", num_file, tmpfile);
                 validation_pdb(tmpfile, tmp_infile, is_separate, is_prev_check, is_short_cut,
                                         File_ID, NULL, public_flag, is_nmr_view);
                 memset(File_ID, 0, 100);
                 break;
            case MAX_OPTION_VALIDATION_NDB:
                 fprintf(stdout, "Validation of a NDB format file [%d] %s\n", num_file, tmpfile);
                 validation_ndb(tmpfile, tmp_infile, is_separate, is_prev_check, is_short_cut,
                                          File_ID, public_flag);
                 memset(File_ID, 0, 100);
                 break;
            case MAX_OPTION_VALIDATION_CIF:
                 fprintf(stdout, "Validation of a CIF format file [%d] %s\n", num_file, tmpfile);
                 validation_cif(tmpfile, tmp_infile, is_separate, is_prev_check, is_short_cut,
                                         File_ID, NULL, public_flag, exchange_in, is_nmr_view);
                 memset(File_ID, 0, 100);
                 break;
            case MAX_OPTION_SYMMETRY_NDB:
                 fprintf(stdout, "Generate symmetry related strands to NDB files(s) ");
                 fprintf(stdout, "for [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 generate_sym_strands_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_SYMMETRY_CIF:
                 fprintf(stdout, "Generate symmetry related strands to CIF files(s) ");
                 fprintf(stdout, "for [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 generate_sym_strands_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_NCS_NDB:
                 fprintf(stdout, "Generate NCS related strands to NDB files(s) for ");
                 fprintf(stdout, "[%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 generate_ncs_strands_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_NCS_CIF:
                 fprintf(stdout, "Generate NCS related strands to CIF files(s) for ");
                 fprintf(stdout, "[%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 generate_ncs_strands_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_CHIRALITY_NDB:
                 fprintf(stdout, "Correct Chirality of O1P/O2P and H atoms of NDB file ");
                 fprintf(stdout, "[%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 correction_chirality_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_CHIRALITY_CIF:
                 fprintf(stdout, "Correct Chirality of O1P/O2P and H atoms of mmCIF file ");
                 fprintf(stdout, "[%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 correction_chirality_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_CORRESPND_NDB:
                 fprintf(stdout, "Create Correspondences between deposited and standard hydrogen atoms");
                 fprintf(stdout, " of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 restraints_correspondences_NDB(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_CORRESPND_CIF:
                 fprintf(stdout, "Create Correspondences between deposited and standard hydrogen atoms");
                 fprintf(stdout, " of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 restraints_correspondences_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_HYDROGEN_NDB:
                 fprintf(stdout, "Remove Hydrogen atom(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 remove_hydrogen_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_HYDROGEN_CIF:
                 fprintf(stdout, "Remove Hydrogen atom(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 remove_hydrogen_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_ORTH_TO_FRAC:
                 fprintf(stdout, "Convert orthogonal coordinates to fractional for NDB file ");
                 fprintf(stdout, "[%d] %s, the output file will be %s\n", 
                                 num_file, tmpfile, outfile_name);
                 orthogonal_to_fractional(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_FRAC_TO_ORTH:
                 fprintf(stdout, "Convert fractional coordinates to orthogonal for NDB file ");
                 fprintf(stdout, "[%d] %s, the output file will be %s\n", 
                                 num_file, tmpfile, outfile_name);
                 fractional_to_orthogonal(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_NDB_TO_NDBCIF:
                 fprintf(stdout, "Translating a NDB format file [%d] %s to NDBCIF file %s\n",
                                 num_file, tmpfile, outfile_name);
                 ndb_to_ndb(tmpfile, tmp_infile, outfile_name, NDB_FILE_FORMAT_NDBCIF);
                 break;
            case MAX_OPTION_NDBCIF_TO_NDB:
                 fprintf(stdout, "Translating a NDBCIF format file [%d] %s to NDB file %s\n",
                                 num_file, tmpfile, outfile_name);
                 ndb_to_ndb(tmpfile, tmp_infile, outfile_name, NDB_FILE_FORMAT_NDB);
                 break;
            case MAX_OPTION_DEL_ATOM_NDB:
                 fprintf(stdout, "Delete atom(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 delete_atoms_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_DEL_ATOM_CIF:
                 fprintf(stdout, "Delete atom(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 delete_atoms_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_ADD_ATOM_NDB:
                 fprintf(stdout, "Insert atom(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 insert_atoms_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_ADD_ATOM_CIF:
                 fprintf(stdout, "Insert atom(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 insert_atoms_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_DEL_RESIDUE_NDB:
                 fprintf(stdout, "Delete residue(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 delete_residues_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_DEL_RESIDUE_CIF:
                 fprintf(stdout, "Delete residue(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 delete_residues_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_ADD_RESIDUE_NDB:
                 fprintf(stdout, "Insert residue(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 insert_residues_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_ADD_RESIDUE_CIF:
                 fprintf(stdout, "Insert residue(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 insert_residues_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_MERGE_RMK_NDB:
                 fprintf(stdout, "Merge Remarks of %s into NDB file [%d] %s, output file will be %s\n",
                                 support_file, num_file, tmpfile, outfile_name);
                 merge_remarks_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_MERGE_RMK_CIF:
                 fprintf(stdout, "Merge Remarks of %s into mmCIF file [%d] %s, output file will be %s\n",
                                 support_file, num_file, tmpfile, outfile_name);
                 merge_remarks_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_MERGE_COR_NDB:
                 fprintf(stdout, "Merge Coordinates of %s into NDB file [%d] %s, output file will be %s\n",
                                 support_file, num_file, tmpfile, outfile_name);
                 merge_coordinates_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_MERGE_COR_CIF:
                 fprintf(stdout, "Merge Coordinates of %s into mmCIF file [%d] %s, output file will be %s\n",
                                 support_file, num_file, tmpfile, outfile_name);
                 merge_coordinates_CIF(tmpfile, tmp_infile, outfile_name, support_file, is_binary);
                 break;
            case MAX_OPTION_MOVE_HOH_NDB:
                 fprintf(stdout, "Moving Water(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 moving_waters_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_MOVE_HOH_CIF:     
                 fprintf(stdout, "Moving Water(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 moving_waters_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_RES_NAME_NDB:
                 fprintf(stdout, "Switch Residue Name(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 switch_residue_names_NDB(tmpfile, tmp_infile, outfile_name, output_ndb_format);
                 break;
            case MAX_OPTION_RES_NAME_CIF:     
                 fprintf(stdout, "Switch Residue Name(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 switch_residue_names_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_GET_MATRIX:
                 fprintf(stdout, "Get Virus Matrices of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 get_virus_matrix_from_remark_350(tmpfile, tmp_infile, outfile_name, identical_flag);
                 break;
            case MAX_OPTION_UPDATE_HYDROGEN:
                 fprintf(stdout, "Update Hydrogen Nomenclature of PDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 update_hydrogen_nomenclature(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_CHECK_FILE:
                 fprintf(stdout, "Checking PDB file [%d] %s\n", num_file, tmpfile);
                 strcpy(buffer, templateFileName);
                 fd = mkstemp(buffer);
                 close (fd);
                 tlog = fopen(buffer, "w");
                 check_file(tmpfile, tmp_infile, tlog, public_flag);
                 fclose (tlog);
                 tlog = fopen(buffer, "r");
                 while (!feof(tlog)) {
                      fgets(command, 199, tlog);
                      if (feof(tlog)) break;
                      message += command;
                 }
                 fclose (tlog);
                 sprintf(command, "rm -f %s", buffer);
                 system(command);
                 if (message != "") ndb_log_message(NDB_MSG_WARN, "%s\n", message.Text());
                 break;
            case MAX_OPTION_CLASSIFICATION:
                 fprintf(stdout, "Get Classification of PDB file [%d] %s\n", num_file, tmpfile);
                 classification(tmpfile, tmp_infile, summary, summary1);
                 break;
            case MAX_OPTION_LAYER1_TO_2:
                 fprintf(stdout, "Update REVDAT of Layer1 CIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 cif_layer1_to_layer2(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_CHANGE_SYMMETRY:
                 fprintf(stdout, "Changing coordinates of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 change_coordinates_symm_CIF(tmpfile, tmp_infile, outfile_name, support_file);
                 break;
            case MAX_OPTION_CHANGE_NON_SYMM:
                 fprintf(stdout, "Changing coordinates of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 change_coordinates_non_symm_CIF(tmpfile, tmp_infile, outfile_name, support_file);
                 break;
            case MAX_OPTION_COMPLEXITY:
                 fprintf(stdout, "Search Complexity of mmCIF file [%d] %s\n",
                                 num_file, tmpfile);
                 search_complexity(tmpfile, tmp_infile);
                 break;
            case MAX_OPTION_FRAC_TO_ORTH_CIF:
                 fprintf(stdout, "Changing coordinates from Fractional to Orthogonal\n");
                 fractional_to_orthogonal(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_Q_ATOM_CIF:
                 fprintf(stdout, "Remove Q atom(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 remove_Q_atoms_CIF(tmpfile, tmp_infile, outfile_name, is_binary);
                 break;
            case MAX_OPTION_MERGE_WATER:
                 fprintf(stdout, "Reorder Het Group(s) and Waters of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 merge_waters_CIF(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_REP_RESIDUE_NDB:
                 fprintf(stdout, "Replace residue(s) of NDB file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 replace_residues_NDB(tmpfile, tmp_infile, outfile_name, support_file, output_ndb_format);
                 break;
            case MAX_OPTION_REP_RESIDUE_CIF:
                 fprintf(stdout, "Replace residue(s) of mmCIF file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 replace_residues_CIF(tmpfile, tmp_infile, outfile_name, support_file);
                 break;
            case MAX_OPTION_UPDATE_NA_FEATURE:
                 fprintf(stdout, "Update NA features of mmCIF format file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 cif_to_cif(tmpfile, tmp_infile, outfile_name, 1, is_binary, standardized, is_special,
                             0, 0, 0, id_option, 0, 0, 0, 0, 0, "", keep_contact_author, 0, 0);
                 break;
            case MAX_OPTION_RENUMBER_PDB:
                 fprintf(stdout, "Re-number PDB numbers of mmCIF format file [%d] %s, output file will be %s\n",
                                 num_file, tmpfile, outfile_name);
                 renumber_pdb_number_CIF(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_BIOL_UNIT:
                 fprintf(stdout, "Creat biological unit PDB file(s) %s from CIF format file [%d] %s\n",
                                 outfile_name, num_file, tmpfile);
                 cif_to_biol_unit_pdb(tmpfile, tmp_infile, outfile_name, exchange_in, id_option & 1);
                 break;
            case MAX_OPTION_ONE_LETTER_CODE:
                 fprintf(stdout, "Get one letter sequence from coordinates for file [%d] %s\n",
                                 num_file, tmpfile);
                 get_one_letter_code_from_coordinates(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_HPUB_LETTER:
                 fprintf(stdout, "Get letter for 'HOLD FOR PUBLICATION' file [%d] %s\n", num_file, tmpfile);
                 get_hpub_letter(tmp_infile);
                 break;
            case MAX_OPTION_EXCHANGE:
                 fprintf(stdout, "Convert exchange format mmCIF %s into internal format mmCIF [%d] %s\n",
                                 outfile_name, num_file, tmpfile);
                 exchange_cif_to_internal_cif(tmpfile, tmp_infile, outfile_name);
                 break;
            case MAX_OPTION_PACKING:
                 fprintf(stdout, "Creat packing unit PDB file(s) %s from CIF format file [%d] %s\n",
                                 outfile_name, num_file, tmpfile);
                 cif_to_packing_pdb(tmpfile, tmp_infile, outfile_name, exchange_in);
                 break;
       }

       sprintf(command, "rm -rf %s", tmp_infile);
       system(command);    
       if (compressFlag == 1) {
            sprintf(command, "compress -f %s", outfile_name);
            system(command);
       } else if (compressFlag == 2) {
            sprintf(command, "gzip -f %s", outfile_name);
            system(command);
       }
}

static void maxit_check_files(const int choice, const char *infile_name, char *outfile_name)
{
       memset(outfile_name, 0, MXSTRLEN);

       switch(choice){
            case MAX_OPTION_PDB_TO_CIF:
            case MAX_OPTION_NDB_TO_CIF:
            case MAX_OPTION_PDB_TO_ENCIF:
            case MAX_OPTION_CIF_TO_CIF:
            case MAX_OPTION_SYMMETRY_CIF:
            case MAX_OPTION_NCS_CIF:
            case MAX_OPTION_CHIRALITY_CIF:
            case MAX_OPTION_HYDROGEN_CIF:
            case MAX_OPTION_DEL_ATOM_CIF:
            case MAX_OPTION_ADD_ATOM_CIF:
            case MAX_OPTION_DEL_RESIDUE_CIF:
            case MAX_OPTION_ADD_RESIDUE_CIF:
            case MAX_OPTION_MERGE_RMK_CIF:
            case MAX_OPTION_MERGE_COR_CIF:
            case MAX_OPTION_MOVE_HOH_CIF:
            case MAX_OPTION_RES_NAME_CIF:
            case MAX_OPTION_GET_MATRIX:
            case MAX_OPTION_LAYER1_TO_2:
            case MAX_OPTION_CHANGE_SYMMETRY:
            case MAX_OPTION_CHANGE_NON_SYMM:
            case MAX_OPTION_FRAC_TO_ORTH_CIF:
            case MAX_OPTION_Q_ATOM_CIF:
            case MAX_OPTION_MERGE_WATER:
            case MAX_OPTION_REP_RESIDUE_CIF:
            case MAX_OPTION_UPDATE_NA_FEATURE:
            case MAX_OPTION_RENUMBER_PDB:
            case MAX_OPTION_EXCHANGE:
                 sprintf(outfile_name, "%s.cif", infile_name);
                 break;
            case MAX_OPTION_CIF_TO_PDB:
            case MAX_OPTION_NDB_TO_PDB:
            case MAX_OPTION_UPDATE_HYDROGEN:
            case MAX_OPTION_BIOL_UNIT:
            case MAX_OPTION_PACKING:
                 sprintf(outfile_name, "%s.pdb", infile_name);
                 break;
            case MAX_OPTION_PDB_TO_NDB:
            case MAX_OPTION_CIF_TO_NDB:
            case MAX_OPTION_SYMMETRY_NDB:
            case MAX_OPTION_NCS_NDB:
            case MAX_OPTION_CHIRALITY_NDB:
            case MAX_OPTION_HYDROGEN_NDB:
            case MAX_OPTION_ORTH_TO_FRAC:
            case MAX_OPTION_FRAC_TO_ORTH:
            case MAX_OPTION_NDBCIF_TO_NDB:
            case MAX_OPTION_DEL_ATOM_NDB:
            case MAX_OPTION_ADD_ATOM_NDB:
            case MAX_OPTION_DEL_RESIDUE_NDB:
            case MAX_OPTION_ADD_RESIDUE_NDB:
            case MAX_OPTION_MERGE_RMK_NDB:
            case MAX_OPTION_MERGE_COR_NDB:
            case MAX_OPTION_MOVE_HOH_NDB:
            case MAX_OPTION_RES_NAME_NDB:
            case MAX_OPTION_REP_RESIDUE_NDB:
                 sprintf(outfile_name, "%s.ndb", infile_name);
                 break;
            case MAX_OPTION_CORRESPND_NDB:
            case MAX_OPTION_CORRESPND_CIF:
                 sprintf(outfile_name, "%s.cor", infile_name);
                 break;
            case MAX_OPTION_NDB_TO_NDBCIF:
                 sprintf(outfile_name, "%s.ndbcif", infile_name);
                 break;
            case MAX_OPTION_ONE_LETTER_CODE:
                 sprintf(outfile_name, "%s.seq", infile_name);
                 break;
       }
}

static void maxit_usage(const char *prog_name)
{
  fprintf(stdout, "Usage:  %s [-f file -i file -M merge_file -o num -replace ", prog_name);
  fprintf(stdout, "-path -filename -p -adit -s -standard -exchange_in -exchange_out -pdbids -ndbids -public -together -short -no_deriv -get_biol_unit]\n");   
  fprintf(stdout,"  [-f   batch_file_name ]\n"); 
  fprintf(stdout,"  [-i   single_file_name]\n");
  fprintf(stdout,"  [-o  1: Translate PDB format file(s) to CIF format file(s)]\n");
  fprintf(stdout,"  [-o  2: Translate CIF format file(s) to PDB format file(s)]\n");
  fprintf(stdout,"  [-o  3: Translate PDB format file(s) to NDB format file(s)]\n");
  fprintf(stdout,"  [-o  4: Translate NDB format file(s) to PDB format file(s)]\n");
  fprintf(stdout,"  [-o  5: Translate NDB format file(s) to mmCIF format file(s)]\n");
  fprintf(stdout,"  [-o  6: Translate CIF format file(s) to NDB format file(s)]\n");
  fprintf(stdout,"  [-o  7: Translate PDB format file(s) to encapsulated CIF file(s)\n");
  fprintf(stdout,"  [-o  8: Translate CIF format file(s) to mmCIF format file(s)\n");
  fprintf(stdout,"  [-o  9: Validation: PDB format file(s)]\n");
  fprintf(stdout,"  [-o 10: Validation: NDB format file(s)]\n");
  fprintf(stdout,"  [-o 11: Validation: CIF format file(s)]\n");
  fprintf(stdout,"  [-o 12: Generate symmetry related strands to NDB files(s)]\n");
  fprintf(stdout,"  [-o 13: Generate symmetry related strands to mmCIF files(s)]\n");
  fprintf(stdout,"  [-o 14: Generate NCS related strands to NDB file(s)]\n");
  fprintf(stdout,"  [-o 15: Generate NCS related strands to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 16: Correct Chirality of O1P/O2P and H atoms to NDB file(s)]\n");
  fprintf(stdout,"  [-o 17: Correct Chirality of O1P/O2P and H atoms to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 18: Create Correspondences between deposited and standard hydrogen atoms to NDB file(s)]\n");
  fprintf(stdout,"  [-o 19: Create Correspondences between deposited and standard hydrogen atoms to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 20: Remove Hydrogen atom(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 21: Remove Hydrogen atom(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 22: Delete Atom(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 23: Delete Atom(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 24: Insert Atom(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 25: Insert Atom(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 26: Delete Residue(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 27: Delete Residue(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 28: Insert Residue(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 29: Insert Residue(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 30: Merge Remarks to NDB file]\n");
  fprintf(stdout,"  [-o 31: Merge Remarks to mmCIF file]\n");
  fprintf(stdout,"  [-o 32: Merge Coordinates to NDB file]\n");
  fprintf(stdout,"  [-o 33: Merge Coordinates to mmCIF file]\n");
  fprintf(stdout,"  [-o 34: Moving Water(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 35: Moving Water(s) to CIF file(s)]\n");
  fprintf(stdout,"  [-o 36: Switch Residue Name(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 37: Switch Residue Name(s) to CIF file(s)]\n");
  fprintf(stdout,"  [-o 38: Replace Residue(s) to NDB file(s)]\n");
  fprintf(stdout,"  [-o 39: Replace Residue(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 40: Moving coordinates using symmetry operation to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 41: Moving coordinates using non-symmetry operation to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 42: Update NA features to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 43: Convert orthogonal coordinates to fractional using NDB files(s)]\n");
  fprintf(stdout,"  [-o 44: Convert fractional coordinates to orthogonal using NDB files(s)]\n");
  fprintf(stdout,"  [-o 45: Convert fractional coordinates to orthogonal using mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 46: Translating NDB format file(s) to NDBCIF format file(s)]\n");
  fprintf(stdout,"  [-o 47: Translating NDBCIF format file(s) to NDB format file(s)]\n");
  fprintf(stdout,"  [-o 48: Adding REVDAT for Layer1 to Layer2 using CIF file(s)]\n");
  fprintf(stdout,"  [-o 49: Remove Q atom(s) to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 50: Reorder Het group(s) and Waters to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 51: Get Virus Matrices to mmCIF file(s)]\n");
  fprintf(stdout,"  [-o 52: Update Hydrogen Nomenclature to PDB file(s)]\n");
  fprintf(stdout,"  [-o 53: Check PDB file(s)]\n");
  fprintf(stdout,"  [-o 54: Get Classification of PDB file(s)]\n");
  fprintf(stdout,"  [-o 55: Get Biological Unit PDB file(s)]\n");
  fprintf(stdout,"  [-o 56: Convert mmCIF from exchange to internal dictionary]\n");
  fprintf(stdout,"  [-o 57: Get one letter sequence from coordinates]\n");
  fprintf(stdout,"  [-o 58: Get letter for 'HOLD FOR PUBLICATION' structures]\n");
}
