/* readPDB.c 
 *
 * contains functions for reading PDB files
 * into the structure SEZNAM (suitable for next
 * work with molecule)
 * -----------------------------------------
 */

#include "main.h"

/* ------------------------------------------------------------------------- */
/* It reads from the PDB file all relevant pieces of information
 * about the molecule to the linearly concatenated list and
 * returns pointer on the first element of this list                         */
SEZNAM *nacti_PDB_do_LZS (char soubor[]) {
/* ------------------------------------------------------------------------- */

  SEZNAM *p_sfirst;   /* pointer on the first element of spine list */
  SEZNAM *p_sact;
  PRVEK *p_pact;
  FILE *fr;
  char radek[SLOUPCE], klicove_slovo[6];
  int uroven, cislo_at, resSeq, pruchod;
  float sX, sY, sZ;
  char znacka_at[3], pom[9], amk[4];
  int zdroj, cil;
  char *p_c;
  char *p_c2;

  fr = NULL;
  fr = fopen(soubor,"r");
  pruchod=1;
  p_sfirst = NULL;
  while (fgets(radek, SLOUPCE+1, fr) != NULL) { 
    strncpy(klicove_slovo,radek,6);
    klicove_slovo[6]='\0';
    p_c2 = strtok(klicove_slovo," ");
    p_c2[strlen(p_c2)]='\0';
    uroven=0;
    if (strcmp(p_c2,"ATOM")==0) {uroven=1;}
    if (strcmp(p_c2,"HETATM")==0) {uroven=1;}
    if (strcmp(p_c2,"CONECT")==0) {uroven=2;}
    switch (uroven) {
         case 0:  /* all keywords except for HETATM, ATOM a CONECT*/
            break;

         case 1: /* HETATM a ATOM */
	   /* reading index */
	   pom[0]=radek[6];
	   pom[1]=radek[7];
	   pom[2]=radek[8];
	   pom[3]=radek[9];
	   pom[4]=radek[10];
	   pom[5]='\0';
	   cislo_at = atoi(pom);
	   /* following reading the chemical symbol of atom (it can be in range of 12-15, 
        * but proteins contain atoms with only uniliteral name => it is
        * sufficient to read only 13. character, other characters are 
        * auxiliary and contains information helpful in case of localization 
        * of atom in scope of amino acids)
	    */
	   pom[0]=radek[13];
	   pom[1]='\0';
       strncpy(znacka_at,pom,2); /* 2 characters = name of atom + \0 */
       /* residue Name */
       amk[0]=radek[17];
       amk[1]=radek[18];
       amk[2]=radek[19];
       amk[3]='\0';
       
       pom[0]=radek[22];
       pom[1]=radek[23];
       pom[2]=radek[24];
       pom[3]=radek[25];
       pom[4]='\0';
       resSeq = atoi(pom);

	   /* reading X-coordinate */
	   pom[0]=radek[30];
	   pom[1]=radek[31];
	   pom[2]=radek[32];
	   pom[3]=radek[33];
	   pom[4]=radek[34];
	   pom[5]=radek[35];
	   pom[6]=radek[36];
	   pom[7]=radek[37];
	   pom[8]='\0';
	   sX = atof(pom);

	   /* reading Y-coordinate */
	   pom[0]=radek[38];
	   pom[1]=radek[39];
	   pom[2]=radek[40];
	   pom[3]=radek[41];
	   pom[4]=radek[42];
	   pom[5]=radek[43];
	   pom[6]=radek[44];
	   pom[7]=radek[45];
	   pom[8]='\0';
	   sY = atof(pom);

	   /* reading Z-coordinate */
	   pom[0]=radek[46];
	   pom[1]=radek[47];
	   pom[2]=radek[48];
	   pom[3]=radek[49];
	   pom[4]=radek[50];
	   pom[5]=radek[51];
	   pom[6]=radek[52];
	   pom[7]=radek[53];
	   pom[8]='\0';
	   sZ = atof(pom);

	   if (pruchod>2) {
               p_sact = vytvor_prvek_seznamu(p_sact,cislo_at,znacka_at,amk,resSeq,sX,sY,sZ);
               pruchod++;
	   }
	   if (pruchod==2) {
               p_sact = vytvor_prvek_seznamu(p_sfirst,cislo_at,znacka_at,amk,resSeq,sX,sY,sZ);
               pruchod++;
	   }
	   if (pruchod==1) {
               p_sfirst = vytvor_prvek_seznamu(p_sfirst,cislo_at,znacka_at,amk,resSeq,sX,sY,sZ);
               pruchod++;
	   }
	    
	   break;

         case 2: /* CONECT */
            p_c = strtok(radek," ");
            if (p_c != NULL) {
             /* pom contains keyword CONECT */
               strcpy(pom,p_c);
            }
            if ((p_c = strtok(NULL," ")) != NULL) {
                 /* 'zdroj' contains atom index to which 
                  * the others are connected */
                zdroj = atoi(p_c);
            }
            p_pact = NULL;
            while ((p_c = strtok(NULL," ")) != NULL) {
               cil = atoi(p_c);
	       if (cil != 0) { 
                 /* 'cil' == 0 means that line was terminated by spaces (which is incorrect)
                  * 'cil' != 0 means that given line was correct
                  */
     		 p_pact = vytvor_souseda(p_sfirst,p_pact,zdroj,cil);
	       }
	    }
            break;

         default : 
     	   /* opened file on this line does not begin with any of known keywords */
           fprintf(stderr,"\nFile %s does not have needed structure.\n",
                   soubor);
	          fclose(fr);
           exit(1);
      }

  }
  fclose(fr);

  return p_sfirst;
}
