/* Copyright (C) 2000-2003 Damir Zucic */

/*=============================================================================

				write_line.c

Purpose:
	Write a single line to output file. PDB format version 2.1 is used
	as the output format.
	
Input:
	(1) Pointer to the output file.
	(1) Pointer to RawAtomS structure, with raw atomic data.

Output:
	(1) Data written to file.
	(2) Return value.

Return value:
	(1) Positive always (trivial).

Notes:
	(1) Some columns (positions in line) are unused in PDB format. For
	    that reason  it is important to remove  the terminal zeros for
	    most characters!  For simplicity, zero was removed everywhere.

========includes:============================================================*/

#include <stdio.h>

#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======write line to output file:===========================================*/

int WriteLine_ (FILE *fileP, RawAtomS *raw_atomSP)
{
/*=================================================================*/
/* PDB ATOM and HETATM tokens:           ANSI C range:  PDB range: */
/*=================================================================*/
static int      atom_serial_start        =  6;          /*  7 ~ 11 */
static int      atom_serial_end          = 10;
static int      atom_name_start          = 12;          /* 13 ~ 16 */
static int      atom_name_end            = 15;
static int      chemical_symbol_start    = 12;          /* 13 ~ 14 */
static int      chemical_symbol_end      = 13;
static int      remoteness_ind_start     = 14;          /* 15 ~ 15 */
static int      remoteness_ind_end       = 14;
static int      branch_desig_start       = 15;          /* 16 ~ 16 */
static int      branch_desig_end         = 15;
static int      alt_location_start       = 16;          /* 17 ~ 17 */
static int      alt_location_end         = 16;
static int      residue_name_start       = 17;          /* 18 ~ 20 */
static int      residue_name_end         = 19;
static int      chainID_start            = 21;          /* 22 ~ 22 */
static int      chainID_end              = 21;
static int      residue_sequence_start   = 22;          /* 23 ~ 26 */
static int      residue_sequence_end     = 25;
static int      insertion_code_start     = 26;          /* 27 ~ 27 */
static int      insertion_code_end       = 26;
static int      x_start                  = 30;          /* 31 ~ 38 */
static int      z_end                    = 53;
static int      occupancy_start          = 54;          /* 55 ~ 60 */
static int      occupancy_end            = 59;
static int      temperature_factor_start = 60;          /* 61 ~ 66 */
static int      temperature_factor_end   = 65;
static int      segmentID_start          = 72;          /* 73 ~ 76 */
static int      segmentID_end            = 75;
static int      element_symbol_start     = 76;          /* 77 ~ 78 */
static int      element_symbol_end       = 77;
static int      charge_start             = 78;          /* 79 ~ 80 */

int		i;
char		stringA[STRINGSIZE];
char		*currP;

/* Fill line with 80 spaces: */
for (i = 0; i < 80; i++) stringA[i] = ' ';

/* The first token should be "ATOM  " or "HETATM": */
currP = stringA;
if (raw_atomSP->heteroF) strncpy (stringA, "HETATM", 6);
else strncpy (stringA, "ATOM  ", 6);
*(stringA + 6) = ' ';

/* The second token should be the atom serial number: */
currP = stringA + atom_serial_start;
sprintf (currP, "%5d", raw_atomSP->serialI);
*(stringA + atom_serial_end + 1) = ' ';

/* Atom name: */
currP = stringA + atom_name_start;
sprintf (currP, "%-4.4s", raw_atomSP->atom_nameA);
*(stringA + atom_name_end + 1) = ' ';

/* Chemical symbol: */
currP = stringA + chemical_symbol_start;
sprintf (currP, "%-2.2s", raw_atomSP->chemical_symbolA);
*(stringA + chemical_symbol_end + 1) = ' ';

/* Remoteness indicator: */
currP = stringA + remoteness_ind_start;
sprintf (currP, "%c", raw_atomSP->remoteness_indicator);
*(stringA + remoteness_ind_end + 1) = ' ';

/* Branch designator: */
currP = stringA + branch_desig_start;
sprintf (currP, "%c", raw_atomSP->branch_designator);
*(stringA + branch_desig_end + 1) = ' ';

/* Alternate location indicator: */
currP = stringA + alt_location_start;
sprintf (currP, "%c", raw_atomSP->alt_location);
*(stringA + alt_location_end + 1) = ' ';

/* Residue name: */
currP = stringA + residue_name_start;
sprintf (currP, "%-3.3s", raw_atomSP->residue_nameA);
*(stringA + residue_name_end + 1) = ' ';

/* Chain identifier: */
currP = stringA + chainID_start;
sprintf (currP, "%c", raw_atomSP->chainID);
*(stringA + chainID_end + 1) = ' ';

/* Residue sequence number: */
currP = stringA + residue_sequence_start;
sprintf (currP, "%4d", raw_atomSP->residue_sequenceI);
*(stringA + residue_sequence_end + 1) = ' ';

/* Insertion code for residues: */
currP = stringA + insertion_code_start;
sprintf (currP, "%c", raw_atomSP->residue_insertion_code);
*(stringA + insertion_code_end + 1) = ' ';

/* The coordinates x, y and z: */
currP = stringA + x_start;
sprintf (currP, "%8.3f%8.3f%8.3f",
	 raw_atomSP->x[0], raw_atomSP->y, raw_atomSP->z[0]);
*(stringA + z_end + 1) = ' ';

/* Occupancy: */
currP = stringA + occupancy_start;
sprintf (currP, "%6.2f", raw_atomSP->occupancy);
*(stringA + occupancy_end + 1) = ' ';

/* Temperature factor: */
currP = stringA + temperature_factor_start;
sprintf (currP, "%6.2f", raw_atomSP->temperature_factor);
*(stringA + temperature_factor_end + 1) = ' ';

/* Segment identifier: */
currP = stringA + segmentID_start;
sprintf (currP, "%-4.4s", raw_atomSP->segmentA);
*(stringA + segmentID_end + 1) = ' ';

/* Element symbol: */
currP = stringA + element_symbol_start;
sprintf (currP, "%-2.2s", raw_atomSP->elementA);
*(stringA + element_symbol_end + 1) = ' ';

/* Charge: */
currP = stringA + charge_start;
sprintf (currP, "%-2.2s", raw_atomSP->chargeA);

/* Print line to file: */
fprintf (fileP, "%s\n", stringA);

/* Return positive value: */
return 1;
}

/*===========================================================================*/


