content: /*
   * Copyright (c) 1997 - 2016
   * Actelion Pharmaceuticals Ltd.
   * Gewerbestrasse 16
   * CH-4123 Allschwil, Switzerland
   *
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   * 3. Neither the name of the the copyright holder nor the
   *    names of its contributors may be used to endorse or promote products
   *    derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * @author Modest v. Korff
   */
  
  package com.actelion.research.chem.io.pdb.parser;
  
  import java.util.List;
  import java.util.TreeSet;
  
  /**
   * ModelParser
   * Created by korffmo1 on 11.04.18.
   */
  public class ModelParser {
  
      private int indexLine;
  
      public void parse(List<String> liRaw, int indexLine,
                        TreeSet<AtomRecord> atomRecords) {
      	
          String tagAtom = PDBFileParser.TAG_ATOM;
          String tagHeteroAtom = PDBFileParser.TAG_HETATM;
  
          String l0 = liRaw.get(indexLine);
          if(!l0.startsWith(tagAtom)
                  && !l0.startsWith(tagHeteroAtom)
                  && !l0.startsWith(PDBFileParser.TAG_MODEL)) {
              throw new RuntimeException("Error in parsing atoms.");
          }
  
          this.indexLine = indexLine;
  
          int start = indexLine;
          
          // rather use Optional here! 
          AtomRecord lastRecord = null;
          for (int i = start; i < liRaw.size(); i++) {
              String line = liRaw.get(i);
              if(line.startsWith(tagAtom)) {
                  AtomRecord modelAtom = parseAtom(line, false);
                  lastRecord = modelAtom;
                  atomRecords.add(modelAtom);
              }
               else if(line.startsWith(tagHeteroAtom)) {
                  AtomRecord modelAtom = parseAtom(line, true);
                  lastRecord = modelAtom;
                  atomRecords.add(modelAtom);
              } else if (line.startsWith(PDBFileParser.TAG_ANISOU)) {
                  continue;
              } else if (line.startsWith(PDBFileParser.TAG_TER)) { // End of chain or hetero atom group
                  if(lastRecord!=null)
                  	lastRecord.setTerminalC(true);
  
              } else if (line.startsWith(PDBFileParser.TAG_MODEL)){
                  continue;
              } else if (line.startsWith(PDBFileParser.TAG_ENDMDL)){
                  if(lastRecord!=null)
                  	lastRecord.setTerminalC(true);
              } else {
                  this.indexLine = i;
                  break;
              }
          }
      }
  
      private AtomRecord parseAtom(String line, boolean isHetAtom){
          int serialId = Integer.parseInt(line.substring(6,11).trim());
  
          String atomName = line.substring(12,16).trim();
  
          String altLoc = line.substring(16,17).trim();
  
          String residueName = line.substring(17,20).trim();
  
          String chainId = line.substring(21,22).trim();
  
          int resSeq = Integer.parseInt(line.substring(22,26).trim());
          
          String insertionCode = line.substring(26,27).trim();
  
          //invert y and z coordinates for compatibility with Java coordinate system (analogously to Molfileparser & Mol2FileParser)
          double x = Double.parseDouble(line.substring(30,38).trim());
          double y = -Double.parseDouble(line.substring(38,46).trim());
          double z = -Double.parseDouble(line.substring(46,54).trim());
  
          double occupancy = (line.length() < 60) ? 1.0 : Double.parseDouble(line.substring(54,60).trim());
  
          double tempFactor = (line.length() < 66) ? 50.0 : Double.parseDouble(line.substring(60,66).trim());
  
          String element = (line.length() < 78) ? atomName.substring(0, 1) : line.substring(76,78).trim();
          element = element.toLowerCase();
          element = element.substring(0, 1).toUpperCase() + element.substring(1);
  
          return new AtomRecord(
                  isHetAtom,
                  serialId,
                  atomName,
                  altLoc,
                  resSeq, // pdb files don't distinguish between label and author residue numbers
                  residueName,
                  chainId,
                  resSeq, // pdb files don't distinguish between label and author residue numbers
                  insertionCode,
                  x,
                  y,
                  z,
                  occupancy,
                  tempFactor,
                  element);
      }
  
      public int getIndexLine() {
          return indexLine;
      }
  
  
  }
  