/*
 * History
 * Created on Aug 30, 2004 by kofke
 */
package etomica.nbratom.cell;

import etomica.Atom;
import etomica.AtomIterator;
import etomica.AtomPair;
import etomica.AtomSet;
import etomica.Phase;
import etomica.action.AtomsetAction;
import etomica.action.AtomsetCount;
import etomica.action.AtomsetDetect;
import etomica.atom.AtomList;
import etomica.atom.iterator.AtomIteratorListSimple;
import etomica.lattice.RectangularLattice;

/**
 * Returns occupants of all cells as iterates.
 */

public class AtomIteratorCell implements AtomIterator {

	/**
     * Constructor makes iterator that must have phase specified and then be
     * reset() before iteration.
     * 
     * @param D
     *            the dimension of the space of the simulation (used to
     *            construct cell iterators)
     */
	public AtomIteratorCell(int D) {
        cellIterator = new RectangularLattice.Iterator(D);
        atomIterator = new AtomIteratorListSimple();
	}

	public void setPhase(Phase phase) {
        cellIterator.setLattice(phase.getLattice());
        unset();
	}
    
    /**
     * Performs action on all iterates.
     */
    public void allAtoms(AtomsetAction action) {
        cellIterator.reset();
        while(cellIterator.hasNext()) {//outer loop over all cells
            //get cell without advancing -- advance is done via nextIndex,
            // below
            NeighborCell cell = (NeighborCell)cellIterator.peek();
            AtomList list = cell.occupants();
            
            //no molecules in cell
            if(list.isEmpty()) {
                cellIterator.nextIndex();
                continue;
            }
            
            //consider pairs formed from molecules in cell
            atomIterator.setList(list);
            atomIterator.allAtoms(action);
        }//end of outer loop over cells
    }//end of allAtoms
    
	/**
     * Returns the number of atom pairs the iterator will return if reset and
     * iterated in its present state.
     */
	public int size() {
        AtomsetCount counter = new AtomsetCount();
        allAtoms(counter);
        return counter.callCount();
	}
	
	/**
     * Indicates whether the given atom pair will be among the iterates given by
     * the iterator if reset in its present state. True only if an iterated pair
     * would match the atoms as ordered in the given array.
     */
	public boolean contains(AtomSet atoms) {
        if(!(atoms instanceof Atom)) return false;
        AtomsetDetect detector = new AtomsetDetect(atoms);
        allAtoms(detector);
        return detector.detectedAtom();
	}

    public boolean hasNext() {
        return atomIterator.hasNext();
    }
    
    public AtomSet next() {
        return nextAtom();
    }
    
    public Atom nextAtom() {
        if(!hasNext()) return null;
        Atom nextAtom = atomIterator.nextAtom();
        if(!atomIterator.hasNext()) {
            advanceLists();
        }
        return nextAtom;
    }
    
    public AtomSet peek() {
        return atomIterator.peek();
    }
    
    public void unset() {
        atomIterator.unset();
    }

    /**
     * Returns 1, indicating that this is an atom iterator.
     */
    public int nBody() {
        return 1;
    }
    
    public void reset() {
        cellIterator.reset();
        atomIterator.unset();
        advanceLists();

    }//end of reset
    
    // Moves to next pair of lists that can provide an iterate
    // This should be invoked only if listIterator.hasNext is false
    private void advanceLists() {
        do {
            if(cellIterator.hasNext()) {
                AtomList list = ((NeighborCell)cellIterator.next()).occupants();
                atomIterator.setList(list);
                atomIterator.reset();
            } else {//no more cells at all
                break;
            }
        } while(!atomIterator.hasNext());
    }//end of advanceCell
    
   
    private AtomIteratorListSimple atomIterator;
    private final RectangularLattice.Iterator cellIterator;

    }

@@ -132,33 +132,8 @@
 or;%0A
-import etomica.AtomPair;%0A
 impo
@@ -1258,104 +1258,8 @@
 lls%0A
-            //get cell without advancing -- advance is done via nextIndex,%0A            // below%0A
     
@@ -1305,36 +1305,36 @@
 ll)cellIterator.
-peek
+next
 ();%0A            
@@ -1394,18 +1394,42 @@
       //
-no
+consider pairs formed from
  molecul
@@ -1454,16 +1454,17 @@
      if(
+!
 list.isE
@@ -1481,158 +1481,8 @@
     
-            cellIterator.nextIndex();%0A                continue;%0A            %7D%0A            %0A            //consider pairs formed from molecules in cell%0A
     
@@ -1509,32 +1509,36 @@
 .setList(list);%0A
+    
             atom
@@ -1564,16 +1564,30 @@
 ction);%0A
+            %7D%0A
         

clean up