import java.util.*;

public class CRISPR
{
	private Vector repeats;
	private int repeatLength;

	public CRISPR()
	{	repeats = new Vector();
		repeatLength = 0;
	}

	public CRISPR(Vector positions, int length)
	{	repeats = positions;
		repeatLength = length;
	}

	public Vector repeats()
	{	return repeats;
	}

	public int repeatLength()
	{	return repeatLength;
	}

	public void setRepeats(Vector _repeats)
	{	repeats = _repeats;
	}

	public void setRepeatLength(int length)
	{	repeatLength = length;
	}

	public int repeatSpacing(int pos1, int pos2)
	{		return Math.abs(repeatAt(pos2) - repeatAt(pos1));
	}

	public void addRepeat(int val)
	{	repeats.addElement(new Integer(val));
	}

	public void insertRepeatAt(int val, int pos)
	{	repeats.insertElementAt(new Integer(val), pos);
	}

	public void setRepeatAt(int val, int pos)
	{	repeats.setElementAt(new Integer(val), pos);
	}

	public void removeRepeat(int val)
	{	repeats.removeElement(new Integer(val));
	}

	public int repeatAt(int i)
	{	return ((Integer)repeats.elementAt(i)).intValue();
	}

	public int start()
	{	return ((Integer)repeats.firstElement()).intValue();
	}

	public int end()
	{	int lastRepeatBegin = ((Integer)repeats.lastElement()).intValue();
		return lastRepeatBegin + repeatLength - 1;
	}

	public int firstRepeat()
	{	return ((Integer)repeats.elementAt(0)).intValue();
	}

	public int lastRepeat()
	{	return ((Integer)repeats.lastElement()).intValue();
	}

	public int numRepeats()
	{	return repeats.size();
	}

	public int numSpacers()
	{	return numRepeats() - 1;
	}

	public String repeatStringAt(int i)
	{	int currRepeatStartIndex = ((Integer)repeats.elementAt(i)).intValue();
		//int currRepeatStartIndex = repeatAt(i);
		int currRepeatEndIndex = currRepeatStartIndex + repeatLength - 1;
		//added by YY
		if(currRepeatStartIndex < 0) 
			currRepeatStartIndex = 0;
		int maxlen = currRepeatEndIndex + 1;
		if(maxlen > DNASequence.seq.length())
			maxlen = DNASequence.seq.length();
		//return DNASequence.seq.substring(currRepeatStartIndex, currRepeatEndIndex + 1);
		return DNASequence.seq.substring(currRepeatStartIndex, maxlen);
	}
	
	public String getConsensus()
	{
		String consus = "";
		int	i, j, k;
		char	base, cbase;
		int	cA, cT, cG, cC;
		for(i = 0; i < repeatLength; i ++) 
		{
			cA = cT = cC = cG = 0;
			for(j = 0; j < repeats.size(); j ++)
			{
				k = repeatAt(j) + i;
				if((k < 0) || (k >= DNASequence.seq.length()))
				{
					base = '-';
				}
				else {
					base = DNASequence.seq.charAt(k);
				}
                                if (base == 'A')    cA++;
                                if (base == 'C')    cC++;
                                if (base == 'T')    cT++;
                                if (base == 'G')    cG++;
			}
			if((cA >= cC) && (cA >= cT) && (cA >= cG)) cbase = 'A'; 
			else if((cC >= cA) && (cC >= cT) && (cC >= cG)) cbase = 'C'; 
			else if((cT >= cC) && (cT >= cA) && (cT >= cG)) cbase = 'T'; 
			else cbase = 'G';
			consus += cbase;
		}
		return consus;
	}

	public String spacerStringAt(int i)
	{	
		int currRepeatEndIndex = ((Integer)repeats.elementAt(i)).intValue() + repeatLength - 1;
       		int nextRepeatStartIndex = ((Integer)repeats.elementAt(i + 1)).intValue();
		int currSpacerStartIndex = currRepeatEndIndex + 1;
		int currSpacerEndIndex = nextRepeatStartIndex - 1;

		return DNASequence.seq.substring(currSpacerStartIndex, currSpacerEndIndex + 1);
	}

    	public int averageSpacerLength()
  	{   
		int sum = 0;
      		for (int i = 0; i < numSpacers(); i++)
        	{   
			sum = sum + spacerStringAt(i).length();
        	}

        	return sum/numSpacers();
	}

	public int averageRepeatLength()
	{   
		int sum = 0;
		for (int i = 0; i < numRepeats(); i++)
		{   
			sum = sum + repeatStringAt(i).length();
		}

		return sum/numRepeats();
	}

	public int getRepeatLength()
	{   
		if(repeatAt(0) >= 0) 
		{
			return repeatStringAt(0).length();
		}
		else
		{
			return repeatStringAt(1).length();
		}
	}

	public String toString()
	{
		String str = "";

		String repeat, spacer, prevSpacer;
		repeat = spacer = prevSpacer = "";

		str += "POSITION\tREPEAT\t\t\t\tSPACER\n";

		str +="--------\t";

		for (int y = 0; y <  this.repeatLength(); y++)
			str +="-";
		str +="\t";

		for (int z = 0; z <  this.averageSpacerLength(); z++)
			str += "-";
		str +="\n";


		//add 1 to each position, to offset programming languagues that begin at 0 rather than 1
		for (int m = 0; m < numRepeats(); m++)
		{   //repeat = getRepeat(m);
			String bufbef = "";
			for(int j = repeatAt(m); j < 0; j ++) bufbef += "-";
			String bufaft = "";
			if(bufbef == "") {
				String thisrepeat = repeatStringAt(m);
				for(int j = thisrepeat.length(); j < this.repeatLength(); j ++) bufaft += "-"; 
			}
			str += (repeatAt(m) + 1) + "\t\t" + bufbef + repeatStringAt(m) + bufaft + "\t";

			// print spacer
			// because there are no spacers after the last repeat, we stop early (m < crisprIndexVector.size() - 1)
			if (m < numSpacers())
			{   prevSpacer = spacer;
				spacer = spacerStringAt(m);
				str += spacer;

				str +="\t[ " + repeatStringAt(m).length() + ", " + spacerStringAt(m).length() + " ]";
				//str +="--[" + DNASequence.getSimilarity(repeatStringAt(m), spacerStringAt(m)) + "]";
				//str +="--[" + DNASequence.getSimilarity(spacer, prevSpacer) + "]";
				str += "\n";

			}
		}


		str +="\n--------\t";

		for (int x = 0; x < this.repeatLength(); x++)
			str += "-";
		str +="\t";

		for (int z = 0; z <  this.averageSpacerLength(); z++)
			str += "-";
		str +="\n";

		str +="Repeat-con\t" + getConsensus() + "\n";

		return str;
	}

}
