/*--------------------------------------------------------------------------
 *  Copyright 2010 utgenome.org
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *--------------------------------------------------------------------------*/
//--------------------------------------
// utgb-core Project
//
// ACGT.java
// Since: 2010/10/07
//
//--------------------------------------
package org.utgenome.gwt.utgb.client.bio;

import org.utgenome.format.fasta.CompactACGTWriter;

/**
 * Nucleotide ACGT <-> 2bit code conversion utility
 * 
 * @author leo
 * 
 */
public class ACGTEncoder {

	/**
	 * table for translating ASCII code to Nucleotide in 2 bit. (4 is for N); This table can be generated by
	 * {@link CompactACGTWriter#generateCharTo2BitACGTTable()}.
	 */
	private final static byte[] charToACGTCodeTable = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
			4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
			4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
			4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
			4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
			4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 };

	private static char[] acgt = { 'A', 'C', 'G', 'T' };

	public static byte to2bitCode(char base) {
		return charToACGTCodeTable[base];
	}

	public static char toBase(int code) {
		if (code > 3)
			return 'N';
		else
			return acgt[code & 0x03];
	}

	/**
	 * Return the k-mer interger of the given ACGT sequence
	 * 
	 * @param K
	 * @param acgt
	 * @return k-mer integer of the sequence, or -1 when N or the other invalid characters are contained in the sequence
	 */
	public static int toKmerInt(final int K, String acgt) {
		int kmer = 0;

		final int max = Math.min(K, acgt.length());
		for (int i = 0; i < max; i++) {
			byte b = to2bitCode(acgt.charAt(i));
			if (b >= 4)
				return -1;

			kmer <<= 2;
			kmer |= b;
		}

		return kmer;
	}

	public static String toString(int kmerInt, int K) {
		StringBuilder seq = new StringBuilder();
		for (int i = 0; i < K; i++) {
			int index = (kmerInt >>> (2 * (K - i - 1))) & 0x03;
			seq.append(acgt[index]);
		}
		return seq.toString();
	}

}

@@ -2354,16 +2354,28 @@
 f (code 
+%3C 0 %7C%7C code 
 %3E 3)%0D%0A%09%09

fix a bug when converting ACGT code -1 into N