/* 
 * Based on CS 2110 Assignment 1 Reference Solution 
 * 
 * Enhanced DNAParser ---- implements Iterator and Iterable interfaces 
 * 
 */

package cs2110.assignment1.solution;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cs2110.assignment1.DNAParser;

public class EnhancedDNAParser implements DNAParser, Iterator<String>, Iterable<String> {

	private ArrayList<String> genes;
	private int position;  // Current position for getNextGene()
	
	public EnhancedDNAParser(String dna) { 
		// We'll use regular expressions to parse the genes.  It's easier and less error-prone than
		// doing direct string manipulation.
		genes = new ArrayList<String>();
		Pattern p = Pattern.compile(Constants.GENE_START + "([AOCI]*?)" + Constants.GENE_STOP);

		// Extract and store all of the genes.  Alternately, we could parse the DNA string as
		// getNextGene() is called.  But that's somewhat awkward, since count() must return the full
		// count.
		Matcher matcher = p.matcher(dna);
		while(matcher.find()) {
			String gene = matcher.group(1);
			if(gene.length() == 0)
				continue;
			genes.add(gene);
		}
		reset(); // initializes position
	}
	
	public int count() {
		return genes.size();
	}
	
	public String getNextGene() {
		if(position >= genes.size()) 
			return null; // end of genes
		else
			return genes.get(position++);
	}

	public void reset() {
		position = 0;
	}

	// ----------------------- Iterator  interface methods ---------------------------------------

	public boolean hasNext() {
		return position < genes.size();
	}

	public String next() {
		String gene = getNextGene();
		if(gene == null) {
			throw new NoSuchElementException();
		}
		return gene;
	}

	// Not implemented by our parser
	public void remove() {		
		throw new UnsupportedOperationException();
	}

	// ------------------- Iterable interface methods ----------------------------------------
	public Iterator<String> iterator() {
		return this;
	}

	public static void main(String[] args) {
		
		String testDNA = "ACICAAOCOOIOAOCOICAIOAIIIIOAACIAAOOCAAOCCICAAIOIOAIICAIIOIACOOIACOCOICAICACAOACOAAOOOIAAOCOAAAAOCICAIOOCCIICOAOCIOIACOIOCOCAACOICIAAOOCCCOIAAOCCICAIAICACCOCOCCAOOAOCAC";
		
		EnhancedDNAParser parser = new EnhancedDNAParser(testDNA);
		
		// Loop using the original DNAParser interface
		/*
		while(true) {
			String gene = parser.getNextGene();
			if(gene == null) 
				break;
			System.out.println("Gene: " + gene);
		}*/
		
		
		// Loop using the iterable interface
		
		for(String gene : parser) {
			System.out.println("Gene: " + gene);
		}
		
	}
}