/*******************************************************************************
 * Copyright (c) 2006, 2007 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     QNX - Initial API and implementation
 *     Andrew Ferguson (Symbian)
 *     Markus Schorn (Wind River Systems)
 *******************************************************************************/

package org.eclipse.rephraserengine.internal.db.org.eclipse.cdt.internal.core.pdom.db;

import java.util.NoSuchElementException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.rephraserengine.internal.db.org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;


/**
 * This is for strings that take up more than on chunk.
 * The string will need to be broken up into sections and then
 * reassembled when necessary.
 * 
 * @author Doug Schaefer
 */
public class LongString implements IString {

	private final Database db;
	private final int record1;

	// Additional fields of first record
	private static final int LENGTH = 0; // must be first to match ShortString
	private static final int NEXT1 = 4;
	private static final int CHARS1 = 8;
	
	private static final int NUM_CHARS1 = (Database.MAX_SIZE - CHARS1) / 2;
	
	// Additional fields of subsequent records
	private static final int NEXTN = 0;
	private static final int CHARSN = 4;
	
	private static final int NUM_CHARSN = (Database.MAX_SIZE - CHARSN) / 2;
	
	public LongString(Database db, int record1) {
		this.db = db;
		this.record1 = record1;
	}
	
	private interface IWriter {
		public void writeChars(int start, int length, int p) throws CoreException;
	}

	private int createString(int length, IWriter writer) throws CoreException {
		// write the first record
		int firstRecord = db.malloc(Database.MAX_SIZE);
		int start = 0;
		db.putInt(firstRecord, length);
		writer.writeChars(start, NUM_CHARS1, firstRecord + CHARS1);
		
		// write the subsequent records
		int lastNext = firstRecord + NEXT1;
		start += NUM_CHARS1;
		while (length - start > NUM_CHARSN) {
			int nextRecord = db.malloc(Database.MAX_SIZE);
			db.putInt(lastNext, nextRecord);
			writer.writeChars(start, NUM_CHARSN, nextRecord + CHARSN);
			start += NUM_CHARSN;
			lastNext = nextRecord + NEXTN;
		}
		
		// Write the final record
		length -= start;
		int finalRecord = db.malloc(CHARSN + (length) * 2);
		db.putInt(lastNext, finalRecord);
		writer.writeChars(start, length, finalRecord + CHARSN);
		
		return firstRecord;
	}
	
	public LongString(Database db, final String string) throws CoreException {
		this.db = db;
		this.record1 = createString(string.length(), new IWriter() {
			public void writeChars(int start, int length, int p) throws CoreException {
				for (int i = start; i < start + length; ++i) {
					LongString.this.db.putChar(p, string.charAt(i));
					p += 2;
				}
			}
		});
	}
	
	public LongString(Database db, final char[] chars) throws CoreException {
		this.db = db;
		this.record1 = createString(chars.length, new IWriter() {
			public void writeChars(int start, int length, int p) throws CoreException {
				for (int i = start; i < start + length; ++i) {
					LongString.this.db.putChar(p, chars[i]);
					p += 2;
				}
			}
		});
	}
	
	public int getRecord() {
		return record1;
	}

	public void delete() throws CoreException {
		int length = db.getInt(record1 + LENGTH) - NUM_CHARS1;
		int nextRecord = db.getInt(record1 + NEXT1);
		db.free(record1);
		
		// Middle records
		while (length > NUM_CHARSN) {
			length -= NUM_CHARSN;
			int nextnext = db.getInt(nextRecord + NEXTN);
			db.free(nextRecord);
			nextRecord = nextnext;
		}
		
		// Last record
		db.free(nextRecord);
	}
	
	public boolean equals(Object obj) {
		throw new PDOMNotImplementedError();
	}
	
	public int hashCode() {
		return record1;
	}
	
	public int compare(IString string, boolean caseSensitive) throws CoreException {
		if (string instanceof LongString)
			return compare((LongString)string, caseSensitive);
		else if (string instanceof ShortString)
			return compare((ShortString)string, caseSensitive);
		else
			throw new IllegalArgumentException();
	}

	public int compare(char[] other, boolean caseSensitive) throws CoreException {
		CharIterator i1 = new CharIterator();
		int i2 = 0;
		int n2 = other.length;
		
		while (i1.hasNext() && i2 < n2) {
			int cmp= ShortString.compareChars(i1.next(), other[i2], caseSensitive);
			if(cmp!=0)
				return cmp;
			
			++i2;
		}

		if (!i1.hasNext() && i2 != n2)
			return -1;
		else if (i2 == n2 && i1.hasNext())
			return 1;
		else
			return 0;
	}
	
	public int compare(ShortString other, boolean caseSensitive) throws CoreException {
		CharIterator i1 = new CharIterator();
		int index2 = 0;
		int length2 = other.getLength();
		
		while (i1.hasNext() && index2<length2) {
			int cmp= ShortString.compareChars(i1.next(), other.charAt(index2), caseSensitive);
			if(cmp!=0)
				return cmp;
			index2++;
		}

		if (!i1.hasNext() && index2 != length2)
			return -1;
		else if (index2 == length2 && i1.hasNext())
			return 1;
		else
			return 0;
	}
	
	public int compare(LongString other, boolean caseSensitive) throws CoreException {
		CharIterator i1 = new CharIterator();
		CharIterator i2 = other.new CharIterator();
		
		while (i1.hasNext() && i2.hasNext()) {
			int cmp= ShortString.compareChars(i1.next(), i2.next(), caseSensitive);
			if(cmp!=0)
				return cmp;
		}

		if (!i1.hasNext() && i2.hasNext())
			return -1;
		else if (!i2.hasNext() && i1.hasNext())
			return 1;
		else
			return 0;
	}
	
	public int compare(String other, boolean caseSensitive) throws CoreException {
		CharIterator i1 = new CharIterator();
		int i2 = 0;
		int n2 = other.length();
		
		while (i1.hasNext() && i2 < n2) {
			int cmp= ShortString.compareChars(i1.next(), other.charAt(i2), caseSensitive);
			if(cmp!=0)
				return cmp;
			
			++i2;
		}

		if (!i1.hasNext() && i2 != n2)
			return -1;
		else if (i2 == n2 && i1.hasNext())
			return 1;
		else
			return 0;
	}

	public int comparePrefix(char[] other, boolean caseSensitive) throws CoreException {
		CharIterator i1 = new CharIterator();
		int i2 = 0;
		int n2 = other.length;
		
		while (i1.hasNext() && i2 < n2) {
			int cmp= ShortString.compareChars(i1.next(), other[i2], caseSensitive);
			if(cmp!=0)
				return cmp;
			
			++i2;
		}

		if (!i1.hasNext() && i2 != n2)
			return -1;
		else
			return 0;
	}

	private interface IReader {
		public void appendChar(char c);
	}
	
	private void readChars(int length, IReader reader) throws CoreException {
		// First record
		int p = record1 + CHARS1;
		for (int i = 0; i < NUM_CHARS1; ++i) {
			reader.appendChar(db.getChar(p));
			p += 2;
		}
		length -= NUM_CHARS1;
		int nextRecord = db.getInt(record1 + NEXT1);
		
		// Middle records
		while (length > NUM_CHARSN) {
			p = nextRecord + CHARSN;
			for (int i = 0; i < NUM_CHARSN; ++i) {
				reader.appendChar(db.getChar(p));
				p += 2;
			}
			length -= NUM_CHARSN;
			nextRecord = db.getInt(nextRecord + NEXTN);
		}
		
		// Last record
		p = nextRecord + CHARSN;
		for (int i = 0; i < length; ++i) {
			reader.appendChar(db.getChar(p));
			p += 2;
		}
	}
	
	/**
     * Convenience class for sequential access to LongString characters
     */
	private class CharIterator {
		int p;
		int count;
		int length;
		
		public CharIterator() throws CoreException {
			p = record1 + CHARS1;
			length =  db.getInt(record1 + LENGTH);
		}
		
		public char next() throws CoreException {
			char result = db.getChar(p);
			p += 2;
			count++;
			if(count>length) {
				throw new NoSuchElementException();
			}
			if(count == NUM_CHARS1) {
				p = db.getInt(record1 + NEXT1) + CHARSN;
			}
			if(count > NUM_CHARS1 && ((count-NUM_CHARS1) % NUM_CHARSN)==0) {
				p = db.getInt(record1 + NEXTN) + CHARSN;
			}
			return result;
		}
		
		public boolean hasNext() {
			return count<length;
		}
	}
	
	public char[] getChars() throws CoreException {
		int length = db.getInt(record1 + LENGTH);
		final char[] chars = new char[length];
		readChars(length, new IReader() {
			int cp = 0;
			public void appendChar(char c) {
				chars[cp++] = c;
			}
		});
		return chars;
	}

	public String getString() throws CoreException {
		int length = db.getInt(record1 + LENGTH);
		final StringBuffer buffer = new StringBuffer(length);
		readChars(length, new IReader() {
			public void appendChar(char c) {
				buffer.append(c);
			}
		});
		return buffer.toString();
	}

	public int compareCompatibleWithIgnoreCase(IString string) throws CoreException {
		int cmp= compare(string, false);
		return cmp==0 ? compare(string, true) : cmp;	
	}

	public int compareCompatibleWithIgnoreCase(char[] chars) throws CoreException {
		int cmp= compare(chars, false);
		return cmp==0 ? compare(chars, true) : cmp;	
	}
}
