/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.dtd.core.internal.saxparser;

/**
 * Reader for processing/parsing xml string
 * 
 * @version
 */
public class StringParser {
	String fData = null;
	int fEndOffset;
	int fMostRecentChar;
	int fCurrentOffset;
	boolean fCalledCharPropInit = false;

	public StringParser(String data) {
		fData = data;
		fCurrentOffset = 0;
		fEndOffset = fData.length();
		fMostRecentChar = fEndOffset == 0 ? -1 : fData.charAt(0);
	}

	public String getString(int offset, int length) {
		if (length == 0)
			return "";
		return fData.substring(offset, offset + length);
	}

	public String getData() {
		return fData;
	}

	public String getRemainingString() {
		return fData.substring(getCurrentOffset());
	}

	public int getCurrentOffset() {
		return fCurrentOffset;
	}

	//
	//
	public int loadNextChar() {
		if (++fCurrentOffset >= fEndOffset) {
			fMostRecentChar = -1;
		}
		else {
			fMostRecentChar = fData.charAt(fCurrentOffset);
		}
		return fMostRecentChar;
	}

	//
	//
	public boolean lookingAtChar(char chr, boolean skipPastChar) {
		int ch = fMostRecentChar;
		if (ch != chr) {
			return false;
		}
		if (skipPastChar) {
			if (++fCurrentOffset >= fEndOffset) {
				fMostRecentChar = -1;
			}
			else {
				fMostRecentChar = fData.charAt(fCurrentOffset);
			}
		}
		return true;
	}

	//
	//
	//
	public boolean lookingAtValidChar(boolean skipPastChar) {
		int ch = fMostRecentChar;
		if (ch < 0xD800) {
			if (ch < 0x20 && ch != 0x09 && ch != 0x0A && ch != 0x0D) {
				return false;
			}
			if (skipPastChar) {
				if (++fCurrentOffset >= fEndOffset) {
					fMostRecentChar = -1;
				}
				else {
					fMostRecentChar = fData.charAt(fCurrentOffset);
				}
			}
			return true;
		}
		if (ch > 0xFFFD) {
			return false;
		}
		if (ch < 0xDC00) {
			if (fCurrentOffset + 1 >= fEndOffset) {
				return false;
			}
			ch = fData.charAt(fCurrentOffset + 1);
			if (ch < 0xDC00 || ch >= 0xE000) {
				return false;
			}
			else if (!skipPastChar) {
				return true;
			}
			else {
				fCurrentOffset++;
			}
		}
		else if (ch < 0xE000) {
			return false;
		}
		if (skipPastChar) {
			if (++fCurrentOffset >= fEndOffset) {
				fMostRecentChar = -1;
			}
			else {
				fMostRecentChar = fData.charAt(fCurrentOffset);
			}
		}
		return true;
	}

	//
	//
	//
	public boolean lookingAtSpace(boolean skipPastChar) {
		int ch = fMostRecentChar;
		if (ch > 0x20)
			return false;
		if (ch == 0x20 || ch == 0x0A || ch == 0x0D || ch == 0x09) {
			if (skipPastChar) {
				loadNextChar();
			}
			return true;
		}
		return false;
	}

	//
	//
	//
	public void skipToChar(char chr, boolean skipPastChar) {
		//
		// REVISIT - this will skip invalid characters without reporting them.
		//
		int ch = fMostRecentChar;
		while (true) {
			if (ch == chr) {
				if (skipPastChar) {
					loadNextChar();
				}
				return;
			}
			if (ch == -1) {
				return;
			}
			ch = loadNextChar();
		}
	}

	//
	//
	//
	public void skipPastSpaces() {
		int ch = fMostRecentChar;
		if (ch == -1) {
			// changeReaders().skipPastSpaces();
			return;
		}
		while (true) {
			if (ch > 0x20 || (ch != 0x20 && ch != 0x0A && ch != 0x09 && ch != 0x0D)) {
				fMostRecentChar = ch;
				return;
			}
			if (++fCurrentOffset >= fEndOffset) {
				return;
			}
			ch = fData.charAt(fCurrentOffset);
		}
	}

	//
	//
	//

	public void skipPastNameAndPEReference(char fastcheck) {
		int ch = fMostRecentChar;

		if (ch != '%') {
			if (ch < 0x80) {
				if (ch == -1 || XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
					return;
			}
			else {
				if (!fCalledCharPropInit) {
					XMLCharacterProperties.initCharFlags();
					fCalledCharPropInit = true;
				}
				if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
					return;
			}
		}
		while (true) {
			ch = loadNextChar();
			if (fastcheck == ch)
				return;
			if (ch == '%' || ch == ';') {
				continue;
			}

			if (ch < 0x80) {
				if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
					return;
			}
			else {
				if (!fCalledCharPropInit) {
					XMLCharacterProperties.initCharFlags();
					fCalledCharPropInit = true;
				}
				if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
					return;
			}
		}
	}

	public void skipPastName(char fastcheck) {
		int ch = fMostRecentChar;
		// System.out.println("skippastName ch: " +ch);

		if (ch < 0x80) {
			if (ch == -1 || XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
				return;
		}
		else {
			if (!fCalledCharPropInit) {
				XMLCharacterProperties.initCharFlags();
				fCalledCharPropInit = true;
			}
			if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
				return;
		}

		while (true) {
			ch = loadNextChar();
			if (fastcheck == ch)
				return;
			if (ch < 0x80) {
				if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
					return;
			}
			else {
				if (!fCalledCharPropInit) {
					XMLCharacterProperties.initCharFlags();
					fCalledCharPropInit = true;
				}
				if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
					return;
			}
		}
	}

	//
	//
	//

	public void skipPastNmtoken(char fastcheck) {
		int ch = fMostRecentChar;
		while (true) {
			if (fastcheck == ch)
				return;
			if (ch < 0x80) {
				if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
					return;
			}
			else {
				if (!fCalledCharPropInit) {
					XMLCharacterProperties.initCharFlags();
					fCalledCharPropInit = true;
				}
				if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
					return;
			}
			ch = loadNextChar();
		}
	}

	public void skipPastNmtokenAndPEReference(char fastcheck) {
		int ch = fMostRecentChar;
		while (true) {
			if (fastcheck == ch)
				return;
			if (ch == '%' || ch == ';') {
				ch = loadNextChar();
				continue;
			}
			if (ch < 0x80) {
				if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
					return;
			}
			else {
				if (!fCalledCharPropInit) {
					XMLCharacterProperties.initCharFlags();
					fCalledCharPropInit = true;
				}
				if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
					return;
			}
			ch = loadNextChar();
		}
	}

	//
	//
	//
	public boolean skippedString(char[] s) {
		int ch = fMostRecentChar;
		if (ch != s[0]) {
			return false;
		}
		if (fCurrentOffset + s.length > fEndOffset)
			return false;
		for (int i = 1; i < s.length; i++) {
			if (fData.charAt(fCurrentOffset + i) != s[i])
				return false;
		}
		fCurrentOffset += (s.length - 1);
		loadNextChar();
		return true;
	}

	//
	//
	//
	public int scanInvalidChar() throws Exception {
		int ch = fMostRecentChar;
		loadNextChar();
		return ch;
	}

	//
	//
	//
	/*
	 * public int scanCharRef(boolean hex) throws Exception { int ch =
	 * fMostRecentChar; if (ch == -1) // return
	 * changeReaders().scanCharRef(hex); return ch; int num = 0; if (hex) { if
	 * (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0) return
	 * XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR; num = ch - (ch < 'A' ?
	 * '0' : (ch < 'a' ? 'A' : 'a') - 10); } else { if (ch < '0' || ch > '9')
	 * return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR; num = ch - '0'; }
	 * boolean toobig = false; while (true) { ch = loadNextChar(); if (ch ==
	 * -1) return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED; if (hex) {
	 * if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
	 * break; } else { if (ch < '0' || ch > '9') break; } if (hex) { int dig =
	 * ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10); num = (num << 4) +
	 * dig; } else { int dig = ch - '0'; num = (num * 10) + dig; } if (num >
	 * 0x10FFFF) { toobig = true; num = 0; } } if (ch != ';') return
	 * XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED; loadNextChar(); if
	 * (toobig) return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE; return
	 * num; }
	 */
	//
	//
	//
	/*
	 * public int scanStringLiteral() throws Exception { boolean single; if
	 * (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
	 * return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED; } int offset =
	 * fCurrentOffset; char qchar = single ? '\'' : '\"'; while
	 * (!lookingAtChar(qchar, false)) { if (!lookingAtValidChar(true)) {
	 * return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR; } } // int
	 * stringIndex = addString(offset, fCurrentOffset - offset); int
	 * stringIndex = addString(offset, fCurrentOffset - offset);
	 * lookingAtChar(qchar, true); // move past qchar return stringIndex; }
	 */

	//
	//
	public boolean scanAttValue(char qchar) {
		int offset = fCurrentOffset;
		boolean result = true;
		while (true) {
			if (lookingAtChar(qchar, false)) {
				break;
			}
			if (lookingAtChar(' ', true)) {
				continue;
			}
			if (!lookingAtValidChar(true)) {
				result = false;
			}
		}
		lookingAtChar(qchar, true);
		return result;
	}

	//
	// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
	// | "'" ([^%&'] | PEReference | Reference)* "'"
	//
	// The values in the following table are defined as:
	//
	// 0 - not special
	// 1 - quote character
	// 2 - reference
	// 3 - peref
	// 4 - invalid
	//
	public static final byte fgAsciiEntityValueChar[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // '\"',
																																																			// '%',
																																																			// '&',
																																																			// '\''
				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

	/*
	 * public int scanEntityValue(int qchar, boolean createString) throws
	 * Exception { int offset = fCurrentOffset; int ch = fMostRecentChar;
	 * while (true) { if (ch == -1) { changeReaders(); // do not call next
	 * reader, our caller may need to change the parameters return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT; } if (ch < 0x80) {
	 * switch (fgAsciiEntityValueChar[ch]) { case 1: // quote char if (ch ==
	 * qchar) { if (!createString) return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED; int length =
	 * fCurrentOffset - offset; int result = length == 0 ?
	 * StringPool.EMPTY_STRING : addString(offset, length); loadNextChar();
	 * return result; } // the other quote character is not special // fall
	 * through case 0: // non-special char if (++fCurrentOffset >= fEndOffset) {
	 * if (oweTrailingSpace) { oweTrailingSpace = false; ch = fMostRecentChar = ' '; }
	 * else { ch = fMostRecentChar = -1; } } else { ch = fMostRecentChar =
	 * fData.charAt(fCurrentOffset); } continue; case 2: // reference return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE; case 3: // peref return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_PEREF; case 4: // invalid return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR; } } else if (ch <
	 * 0xD800) { ch = loadNextChar(); } else if (ch >= 0xE000 && (ch <= 0xFFFD ||
	 * (ch >= 0x10000 && ch <= 0x10FFFF))) { // // REVISIT - needs more code
	 * to check surrogates. // ch = loadNextChar(); } else { return
	 * XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR; } } }
	 */


}
