001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on 24.05.2004
021 * @author Andreas Prlic
022 *
023 */
024
025package org.biojava.nbio.structure;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.util.Iterator;
031import java.util.NoSuchElementException;
032
033
034/** an iterator over all atoms of a structure / group.
035 * @author Andreas Prlic
036 * @since 1.4
037 * @version %I% %G%
038 */
039
040public class AtomIterator implements Iterator<Atom> {
041
042        private final static Logger logger = LoggerFactory.getLogger(AtomIterator.class);
043
044        private Group     group         ;
045        private int current_atom_pos    ;
046        private GroupIterator groupiter ;
047
048        /**
049         * Constructs an AtomIterator object over all models
050         *
051         * @param struct  a Structure object
052         */
053        public AtomIterator(Structure struct) {
054                current_atom_pos = -1 ;
055
056                groupiter = new GroupIterator(struct) ;
057                if ( groupiter.hasNext() ) {
058                        group = groupiter.next() ;
059                }
060                else
061                        group = null ;
062        }
063
064        /**
065         * Constructs an AtomIterator object over a single model
066         *
067         * @param struct  a Structure object
068         */
069        public AtomIterator(Structure struct,int modelNr) {
070                current_atom_pos = -1 ;
071
072                groupiter = new GroupIterator(struct,modelNr) ;
073                if ( groupiter.hasNext() ) {
074                        group = groupiter.next() ;
075                }
076                else
077                        group = null ;
078        }
079
080        /** Get the  chain that contains the current atom.
081         *
082         * @return a Chain object
083         */
084        public Chain getCurrentChain(){
085                return groupiter.getCurrentChain();
086        }
087
088
089        /** Get the model number of the model containing the current atom.
090         *
091         * @return the number of the model
092         */
093        public int getCurrentModel(){
094                return groupiter.getCurrentModel();
095        }
096
097        /**
098         * Constructs an AtomIterator object.
099         *
100         * @param g  a Group object
101         */
102        public AtomIterator(Group g) {
103                group = g ;
104                current_atom_pos = -1 ;
105                groupiter = null ;
106        }
107
108        /** Is there a next atom ?
109         * @return true if there is an atom after the current one
110         * */
111        @Override
112        public boolean hasNext() {
113
114                // trying to iterate over an empty structure...
115
116                if ( group == null)
117                        return false;
118
119                // if there is another group ...
120                if ( current_atom_pos < group.size()-1 ) {
121                        return true ;
122                } else {
123                        // search through the next groups if they contain an atom
124                        if (groupiter != null) {
125                                GroupIterator tmp = (GroupIterator) groupiter.clone() ;
126                                while (tmp.hasNext()) {
127                                        Group tmpg = tmp.next() ;
128
129                                        if ( tmpg.size() > 0 ) {
130                                                return true ;
131                                        }
132
133                                }
134                        } else {
135                                // just an iterator over one group ...
136                                return false ;
137                        }
138                }
139                return false ;
140        }
141
142        /** Return next atom.
143         *
144         * @return the next Atom
145         * @throws NoSuchElementException if there is no atom after the current one
146         */
147        @Override
148        public Atom next()
149        throws NoSuchElementException
150        {
151                current_atom_pos++ ;
152                if ( current_atom_pos >= group.size() ) {
153                        if ( groupiter == null ) {
154                                throw new NoSuchElementException("no more atoms found in group!");
155
156                        }
157                        if ( groupiter.hasNext() ) {
158                                group = groupiter.next() ;
159                                current_atom_pos = -1 ;
160                                return next();
161                        } else {
162                                throw new NoSuchElementException("no more atoms found in structure!");
163                        }
164                }
165
166                Atom a ;
167
168
169                a = group.getAtom(current_atom_pos);
170                if ( a == null) {
171                        logger.error("current_atom_pos {} group {} size: {}", current_atom_pos, group, group.size());
172
173                        throw new NoSuchElementException("error wile trying to retrieve atom");
174                }
175
176                return a ;
177
178        }
179
180        /** does nothing. */
181        @Override
182        public void remove() {
183        }
184
185}
186