
package uk.ac.sanger.pathogens.embl;

import java.lang.IndexOutOfBoundsException;
import java.lang.String;
import java.util.Iterator;

import org.biojava.bio.symbol.Symbol;
import org.biojava.bio.symbol.SymbolList;

import uk.ac.sanger.pathogens.ReadOnlyException;

public class BioJavaSequence implements Sequence
{
    private org.biojava.bio.symbol.SymbolList symbols;

    private int aCount;
    private int cCount;
    private int gCount;
    private int tCount;

    private boolean sequenceIsStale = true;

    public BioJavaSequence(final org.biojava.bio.symbol.SymbolList symbols)
    {
	// System.err.println("Setting symbols to: " + symbols);
	this.symbols = symbols;
    }
    
    public int length()
    {
	return symbols.length();
    }

    public int getACount()
    {
	if (sequenceIsStale)
	    countSymbols();

	return aCount;
    }

    public int getCCount()
    {
	if (sequenceIsStale)
	    countSymbols();

	return cCount;
    }

    public int getGCount()
    {
	if (sequenceIsStale)
	    countSymbols();

	return gCount;
    }

    public int getTCount()
    {
	if (sequenceIsStale)
	    countSymbols();

	return tCount;
    }

    public int getOtherCount()
    {
	if (sequenceIsStale)
	    countSymbols();

	return (symbols.length() - aCount - cCount - gCount -tCount);
    }

    public String getSubSequence(int index1, int index2)
    {
	String subSeq = "";

	try
	{
	    subSeq = symbols.subStr(index1, index2);
	}
	catch (IndexOutOfBoundsException ioe)
	{
	    System.err.println("An error occurred while extracting subsequence "
			       + ioe.getMessage());
	    ioe.printStackTrace();
	}

	return subSeq;
    }

    public void setFromString(String seqString) throws ReadOnlyException
    {
	throw new ReadOnlyException ("This sequence is read-only");
    }

    private void countSymbols()
    {
	int a = 0;
	int c = 0;
	int g = 0;
	int t = 0;

	for (Iterator si = symbols.iterator(); si.hasNext();)
	{
	    Symbol   s = (Symbol) si.next();
	    char token = s.getToken();

	    switch (token)
	    {
		case 'a':
		    a++;
		    break;

		case 'c':
		    c++;
		    break;

		case 'g':
		    g++;
		    break;

		case 't':
		    t++;
		    break;

		default:
		    break;
	    }
	}

	aCount = a;
	cCount = c;
	gCount = g;
	tCount = t;
    }
}
