/*******************************************************************************
 * 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;

import java.util.Enumeration;
import java.util.Vector;

/**
 * Scanning / parsing the content string from the Decl statement
 * 
 * @version
 */
public class DTDScanner {
	// element content model strings
	private static final char[] empty_string = {'E', 'M', 'P', 'T', 'Y'};
	private static final char[] any_string = {'A', 'N', 'Y'};
	private static final char[] pcdata_string = {'#', 'P', 'C', 'D', 'A', 'T', 'A'};

	// attribute type and default type strings
	private static final char[] cdata_string = {'C', 'D', 'A', 'T', 'A'};
	private static final char[] id_string = {'I', 'D'};
	private static final char[] ref_string = {'R', 'E', 'F'};
	private static final char[] entit_string = {'E', 'N', 'T', 'I', 'T'};
	private static final char[] ies_string = {'I', 'E', 'S'};
	private static final char[] nmtoken_string = {'N', 'M', 'T', 'O', 'K', 'E', 'N'};
	private static final char[] notation_string = {'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N'};
	private static final char[] required_string = {'#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D'};
	private static final char[] implied_string = {'#', 'I', 'M', 'P', 'L', 'I', 'E', 'D'};
	private static final char[] fixed_string = {'#', 'F', 'I', 'X', 'E', 'D'};

	private static final char[] system_string = {'S', 'Y', 'S', 'T', 'E', 'M'};
	private static final char[] public_string = {'P', 'U', 'B', 'L', 'I', 'C'};
	private static final char[] ndata_string = {'N', 'D', 'A', 'T', 'A'};

	private int[] fOpStack = null;
	private CMGroupNode[] fGrpStack = null;

	private EntityPool entityPool;

	/* Attribute Def scanner state */
	static final int Att_Scanner_State_Name = 1, Att_Scanner_State_Type = 2, Att_Scanner_State_DefaultType = 3, Att_Scanner_State_DefaultValue = 4;

	private StringParser contentString;
	private String cData;
	private int prevNodeOffset = 0;
	private int nodeOffset = 1;
	private String ownerDTD;

	private String errorString;

	public DTDScanner(String ownerDTD, String cm) {
		// System.out.println("Cm: " + cm);
		contentString = new StringParser(cm);
		cData = cm;
		this.ownerDTD = ownerDTD;
	}

	//
	// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
	//
	// Specific to VisualDTD : also allows %PEReference;
	//
	public CMNode scanContentModel() {
		CMNode cmNode = null;
		contentString.skipPastSpaces();
		if (contentString.skippedString(empty_string)) {
			cmNode = new CMBasicNode("EMPTY", CMNodeType.EMPTY);
		}
		else if (contentString.skippedString(any_string)) {
			cmNode = new CMBasicNode("ANY", CMNodeType.ANY);
		}
		else if (contentString.lookingAtChar('%', true)) {
			cmNode = new CMReferenceNode(contentString.getData(), CMNodeType.ENTITY_REFERENCE);
		}
		else if (!contentString.lookingAtChar('(', true)) {
			// This means that the contentmodel string is bad...
			// System.out.println("!!! exception - no (");
			return cmNode;
		}
		else {
			// System.out.println("Remaining String = " +
			// contentString.getRemainingString());

			contentString.skipPastSpaces();
			boolean skippedPCDATA = contentString.skippedString(pcdata_string);
			if (skippedPCDATA) {
				cmNode = scanMixed();
			}
			else {
				cmNode = scanChildren();
			}

		}
		return cmNode;
	}

	//
	// [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S?
	// '#PCDATA' S? ')'
	//
	// Called after scanning past '(' S? '#PCDATA'
	//
	private CMNode scanMixed() {
		// System.out.println("ScanMixed...");
		CMGroupNode cmNode = new CMGroupNode();
		cmNode.setGroupKind(CMNodeType.GROUP_CHOICE);
		cmNode.addChild(new CMBasicNode("#PCDATA", CMNodeType.PCDATA));

		// int prevNodeIndex = -1;
		boolean starRequired = false;


		while (true) {
			if (contentString.lookingAtSpace(true)) {
				contentString.skipPastSpaces();
			}
			prevNodeOffset = contentString.getCurrentOffset();

			if (!contentString.lookingAtChar('|', true)) {
				if (!contentString.lookingAtChar(')', true)) {
					break;
				}
				if (contentString.lookingAtChar('*', true)) {
					cmNode.setOccurrence(CMNodeType.ZERO_OR_MORE);
				}
				else if (starRequired) {
					// System.out.println(" * is required ... ");
				}
				break;
			}

			if (contentString.lookingAtSpace(true)) {
				contentString.skipPastSpaces();
			}

			nodeOffset = contentString.getCurrentOffset();
			if (nodeOffset != -1) {
				// skip pass "|"
				prevNodeOffset = nodeOffset;
			}

			starRequired = true;
			contentString.skipPastNameAndPEReference(')');
			nodeOffset = contentString.getCurrentOffset();

			if (nodeOffset == -1)
				break;

			// add leave node
			int len = nodeOffset - prevNodeOffset;
			String refName = contentString.getString(prevNodeOffset, len);
			prevNodeOffset = nodeOffset;
			if (refName.startsWith("%"))
				cmNode.addChild(new CMReferenceNode(refName, CMNodeType.ENTITY_REFERENCE));
			else
				cmNode.addChild(new CMReferenceNode(refName, CMNodeType.ELEMENT_REFERENCE));

		} // end while


		if (cmNode.getChildren().size() == 1) {
			// simplify the contentModel if the CMGroupNode only has one child
			// node.
			return (CMBasicNode) cmNode.getChildren().elementAt(0);
		}

		return cmNode;
	}

	//
	// [47] children ::= (choice | seq) ('?' | '*' | '+')?
	// [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
	// [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
	// [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
	//
	// Called after scanning past '('

	private CMNode scanChildren() {

		// System.out.println("scanChildren...");

		if (contentString.lookingAtSpace(true)) {
			contentString.skipPastSpaces();
		}

		prevNodeOffset = contentString.getCurrentOffset();
		nodeOffset = contentString.getCurrentOffset();
		int depth = 1;
		initializeContentModelStack(depth);
		int len;

		String nodeName;
		CMGroupNode cmNode = new CMGroupNode();
		fGrpStack[depth] = cmNode;

		while (true) {

			// System.out.println(" Begin outter while loop ..." );
			if (contentString.lookingAtChar('(', true)) {
				if (contentString.lookingAtSpace(true)) {
					// skip past any white spaces after the '('
					contentString.skipPastSpaces();
				}

				depth++;
				initializeContentModelStack(depth);
				fGrpStack[depth] = new CMGroupNode();
				fGrpStack[depth - 1].addChild(fGrpStack[depth]);
				continue;
			}

			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipPastNameAndPEReference(')');
			nodeOffset = contentString.getCurrentOffset();

			/*
			 * System.out.println(" prevNodeOFfset " + prevNodeOffset);
			 * System.out.println(" currentNodeOFfset " + nodeOffset);
			 */

			len = nodeOffset - prevNodeOffset;

			if (nodeOffset == -1 || len < 1) {
				break;
			}

			nodeName = contentString.getString(prevNodeOffset, len);

			CMRepeatableNode rn;
			if (nodeName.startsWith("%")) {
				rn = new CMReferenceNode(nodeName, CMNodeType.ENTITY_REFERENCE);
			}
			else {
				rn = new CMReferenceNode(nodeName, CMNodeType.ELEMENT_REFERENCE);
			}

			fGrpStack[depth].addChild(rn);

			prevNodeOffset = nodeOffset;

			if (contentString.lookingAtChar('?', true)) {
				rn.setOccurrence(CMNodeType.OPTIONAL);
			}
			else if (contentString.lookingAtChar('*', true)) {
				rn.setOccurrence(CMNodeType.ZERO_OR_MORE);
			}
			else if (contentString.lookingAtChar('+', true)) {
				rn.setOccurrence(CMNodeType.ONE_OR_MORE);
			}

			if (contentString.lookingAtSpace(true)) {
				contentString.skipPastSpaces();
			}

			prevNodeOffset = contentString.getCurrentOffset();

			while (true) {
				// System.out.println(" Begin inner while loop ... depth " +
				// depth );
				if (fOpStack[depth] != CMNodeType.GROUP_SEQUENCE && contentString.lookingAtChar('|', true)) {
					fOpStack[depth] = CMNodeType.GROUP_CHOICE;
					fGrpStack[depth].setGroupKind(CMNodeType.GROUP_CHOICE);
					if (contentString.lookingAtSpace(true))
						contentString.skipPastSpaces();
					break;
				}
				else if (fOpStack[depth] != CMNodeType.GROUP_CHOICE && contentString.lookingAtChar(',', true)) {
					fOpStack[depth] = CMNodeType.GROUP_SEQUENCE;
					fGrpStack[depth].setGroupKind(CMNodeType.GROUP_SEQUENCE);
					if (contentString.lookingAtSpace(true))
						contentString.skipPastSpaces();
					break;
				}
				else {
					if (contentString.lookingAtSpace(true)) {
						contentString.skipPastSpaces();
					}
					if (!contentString.lookingAtChar(')', true)) {
						// System.out.println(" error ) not found");
					}
					// end of the curent group node
					if (contentString.lookingAtChar('?', true)) {
						fGrpStack[depth].setOccurrence(CMNodeType.OPTIONAL);
					}
					else if (contentString.lookingAtChar('*', true)) {
						fGrpStack[depth].setOccurrence(CMNodeType.ZERO_OR_MORE);
					}
					else if (contentString.lookingAtChar('+', true)) {
						fGrpStack[depth].setOccurrence(CMNodeType.ONE_OR_MORE);
					}
					depth--;
					if (depth == 0) {
						break;
					}
					if (contentString.lookingAtSpace(true))
						contentString.skipPastSpaces();

					// System.out.println(" End end inner while loop ... depth
					// " + depth );

				}
			} // inner while

			if (depth == 0) {
				break;
			}
		} // outer while

		if (cmNode.getChildren().size() == 1) {
			// simplify the contentModel if the CMGroupNode only has one child
			// node and that node is an element ref.
			CMRepeatableNode rn = (CMRepeatableNode) cmNode.getChildren().elementAt(0);
			if (rn instanceof CMReferenceNode) {
				CMReferenceNode ref = (CMReferenceNode) rn;
				if (ref.getType() == CMNodeType.ELEMENT_REFERENCE) {
					if (ref.getOccurrence() == CMNodeType.ONE) {
						ref.setOccurrence(cmNode.getOccurrence());
						return ref;
					}
					else if (cmNode.getOccurrence() == CMNodeType.ONE) {
						return ref;
					}
				} // end of if ()
			}
		}

		return cmNode;
	}

	//
	// [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
	// [53] AttDef ::= S Name S AttType S DefaultDecl
	// [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)?
	// AttValue)
	//

	public Vector scanAttlistDecl(EntityPool entityPool) {
		Vector attList = new Vector();
		this.entityPool = entityPool;

		int scannerState = Att_Scanner_State_Name;
		;
		AttNode attNode;

		while (true) {
			attNode = new AttNode();

			// System.out.println(" scanner state: " + scannerState);

			// scanning att name
			if (scannerState == Att_Scanner_State_Name) {
				// System.out.println("scan att Name...");
				scannerState = checkForAttributeWithPEReference(attNode, scannerState);
				if (scannerState == -1) {
					return attList;
				}
			}

			// scanning att type
			if (scannerState == Att_Scanner_State_Type) {
				// System.out.println("scan att type...");

				if (contentString.skippedString(cdata_string)) {
					attNode.type = new String(cdata_string);
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(id_string)) {
					if (!contentString.skippedString(ref_string)) {
						attNode.type = new String(id_string);
					}
					else if (!contentString.lookingAtChar('S', true)) {
						attNode.type = "IDREF";
					}
					else {
						attNode.type = "IDREFS";
					}
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(entit_string)) {
					if (contentString.lookingAtChar('Y', true)) {
						attNode.type = "ENTITY";
					}
					else if (contentString.skippedString(ies_string)) {
						attNode.type = "ENTITIES";
					}
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(nmtoken_string)) {
					if (contentString.lookingAtChar('S', true)) {
						attNode.type = "NMTOKENS";
					}
					else {
						attNode.type = "NMTOKEN";
					}
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(notation_string)) {
					if (contentString.lookingAtSpace(true)) {
						contentString.skipPastSpaces();
					}
					if (!contentString.lookingAtChar('(', true)) {
						System.out.println(" missing ( in notation ");
					}
					attNode.type = "NOTATION";
					attNode.enumList = scanEnumeration(contentString, true);
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.lookingAtChar('(', true)) {
					attNode.type = "ENUMERATION";
					attNode.enumList = scanEnumeration(contentString, false);
					scannerState = Att_Scanner_State_DefaultType;
				}
				else {
					scannerState = checkForAttributeWithPEReference(attNode, scannerState);
					if (scannerState == Att_Scanner_State_Type) {
						setErrorString("Failed to find type for attribute '" + attNode.name + "'.  Please refer to the original DTD file.");
						// we failed to find a type for this attribute
						return attList;
					}
				}
			}

			if (scannerState == Att_Scanner_State_DefaultType) {
				contentString.skipPastSpaces();
				// System.out.println("scan default type...");
				if (contentString.skippedString(required_string)) {
					attNode.defaultType = new String(required_string);
				}
				else if (contentString.skippedString(implied_string)) {
					attNode.defaultType = new String(implied_string);
				}
				else {
					if (contentString.skippedString(fixed_string)) {
						contentString.skipPastSpaces();
						attNode.defaultType = new String(fixed_string);
					}
					else
						// "default"
						attNode.defaultType = "NOFIXED";

					if (contentString.lookingAtSpace(true))
						contentString.skipPastSpaces();
					attNode.defaultValue = scanDefaultAttValue(contentString);
				}
				scannerState = Att_Scanner_State_Name; // next
			}


			attList.addElement(attNode);
			if (contentString.lookingAtSpace(true))
				contentString.skipPastSpaces();
			nodeOffset = contentString.getCurrentOffset();

			if (nodeOffset >= cData.length())
				return attList;

			prevNodeOffset = contentString.getCurrentOffset();

		}// end while loop
	}

	//
	// content model stack
	//
	private void initializeContentModelStack(int depth) {
		if (fOpStack == null) {
			fOpStack = new int[8];
			fGrpStack = new CMGroupNode[8];
		}
		else if (depth == fOpStack.length) {
			int[] newStack = new int[depth * 2];
			System.arraycopy(fOpStack, 0, newStack, 0, depth);
			fOpStack = newStack;

			CMGroupNode[] newGrpStack = new CMGroupNode[depth * 2];
			System.arraycopy(fGrpStack, 0, newGrpStack, 0, depth);
			fGrpStack = newGrpStack;
		}
		fOpStack[depth] = -1;
		fGrpStack[depth] = null;
	}

	//
	private int checkForAttributeWithPEReference(AttNode attNode, int scannerState) {
		int state = -1;
		int len;
		String rawText;
		EntityDecl pEntity;

		// System.out.println(" checkforATTPERReference- start scannerState: "
		// + scannerState);
		if (scannerState == Att_Scanner_State_Name) {
			contentString.skipPastNameAndPEReference(' ');
			nodeOffset = contentString.getCurrentOffset();
			len = nodeOffset - prevNodeOffset;

			rawText = contentString.getString(prevNodeOffset, len);
			attNode.name = rawText;

			// System.out.println("State_name : " + rawText);

			if (rawText.startsWith("%") && rawText.endsWith(";")) {
				String pe = rawText.substring(1, rawText.length() - 1);

				pEntity = entityPool.referPara(pe);
				if (pEntity != null) {
					// System.out.println(" name :" + rawText +" expandTo:" +
					// pEntity.expandedValue);
					state = whatIsTheNextAttributeScanningState(pEntity.expandedValue, scannerState);
					// System.out.println("checkForAttrwithPER - nextstate: "
					// + state);
				}
				else
					state = Att_Scanner_State_Type;
			}
			else
				state = Att_Scanner_State_Type;

		}
		else if (scannerState == Att_Scanner_State_Type) {
			if (contentString.lookingAtChar('%', true)) {
				rawText = getPEName();
				attNode.type = "%" + rawText;
				String peName = rawText.substring(0, rawText.length() - 1);
				// System.out.println("State_type : pe- " + peName);
				pEntity = entityPool.referPara(peName);
				if (pEntity != null) {
					state = whatIsTheNextAttributeScanningState(pEntity.expandedValue, scannerState);
				}
				else
					state = Att_Scanner_State_DefaultType;
			}
			else
				state = Att_Scanner_State_Type;
		}
		else if (scannerState == Att_Scanner_State_DefaultType) {
			if (contentString.lookingAtChar('%', true)) {
				rawText = getPEName();
				attNode.defaultType = rawText;
				// System.out.println("State_defaultType : " + rawText);
				pEntity = entityPool.referPara(rawText.substring(1, rawText.length() - 1));
				if (pEntity != null) {
					state = whatIsTheNextAttributeScanningState(pEntity.expandedValue, scannerState);
				}
				else
					state = Att_Scanner_State_DefaultValue;
			}
			else
				state = Att_Scanner_State_DefaultType;
		}
		else if (scannerState == Att_Scanner_State_DefaultValue) {
			if (contentString.lookingAtChar('%', true)) {
				rawText = getPEName();
				attNode.defaultValue = rawText;
				// System.out.println("State_defaultValue : " + rawText);

				pEntity = entityPool.referPara(rawText.substring(1, rawText.length() - 1));
				if (pEntity != null) {
					state = whatIsTheNextAttributeScanningState(pEntity.expandedValue, scannerState);
				}
				else
					state = Att_Scanner_State_DefaultValue;
			}
			else
				state = Att_Scanner_State_DefaultValue;
		}

		if (contentString.lookingAtSpace(true))
			contentString.skipPastSpaces();
		prevNodeOffset = contentString.getCurrentOffset();
		return state;
	}

	private String getPEName() {
		prevNodeOffset = contentString.getCurrentOffset();
		contentString.skipToChar(';', true);
		nodeOffset = contentString.getCurrentOffset();
		int len = nodeOffset - prevNodeOffset;
		return contentString.getString(prevNodeOffset, len);
	}

	private int whatIsTheNextAttributeScanningState(String attrContentString, int currentState) {
		StringParser sp = new StringParser(attrContentString.trim());


		int nextState = currentState;
		int nOffset = 0;

		/*
		 * System.out.println("WhatistheNext AttContentStringt : " +
		 * attrContentString); System.out.println("WhatistheNext
		 * AttContentStringL : " + attrContentString.length());
		 * System.out.println("WhatistheNext currentstate : " + currentState);
		 */

		while (true) {
			// System.out.println("WhatistheNext inside whil nextstate : " +
			// nextState);
			if (nextState == Att_Scanner_State_Name) { // the current
														// scanning state is
														// Attr Name, is the
														// next part Attr Type
														// ?
				if (isAttrName(sp)) {
					nextState = Att_Scanner_State_Type;
				}
			}
			else if (nextState == Att_Scanner_State_Type) { // the current
															// scanning state
															// is Attr Type,
															// is the next
															// part Default
															// Attr Type ?

				if (isAttrType(sp)) {
					nextState = Att_Scanner_State_DefaultType;
				}
				else
					System.out.println("WhatistheNext Attr Part - is not an Attr Type");

			}

			if (nextState == Att_Scanner_State_DefaultType) {

				int dType = isAttrDefaultType(sp);
				// System.out.println("WhatistheNext inside dType : " +
				// dType);
				if (dType == 1) // #REQUIRED or #IMPLIED
				{
					nextState = Att_Scanner_State_Name;
				}
				else {
					if (dType == 2) // #FIXED
					{
						// need to look at this again
						nextState = Att_Scanner_State_DefaultType;
					}

					if (scanDefaultAttValue(sp) != null) {
						nextState = Att_Scanner_State_Name;

					}
				}
			}

			sp.skipPastSpaces();

			if (nOffset == sp.getCurrentOffset())
				break;

			nOffset = sp.getCurrentOffset();

			if (nOffset >= attrContentString.length() || nOffset == -1)
				break;

		} // end while

		return nextState;
	}


	private boolean isAttrName(StringParser sp) {
		// System.out.println("isAttrName - sp:" + sp.fData);
		// System.out.println("isAttrName - currentOffset:" +
		// sp.getCurrentOffset());
		boolean isAttrName = false;
		int prev = sp.getCurrentOffset();
		sp.skipPastName(' ');
		if ((sp.getCurrentOffset() - prev) > 0)
			isAttrName = true;
		return isAttrName;

	}

	private boolean isAttrType(StringParser sp) {
		// System.out.println("isAttrType - sp:" + sp.fData);
		// System.out.println("isAttrType - currentOffset:" +
		// sp.getCurrentOffset());
		boolean isAttrType = false;
		if (sp.skippedString(cdata_string)) {
			isAttrType = true;
		}
		else if (sp.skippedString(id_string)) {
			if (!sp.skippedString(ref_string)) {
				isAttrType = true; // ID
			}
			else if (!sp.lookingAtChar('S', true)) {
				isAttrType = true; // IDREFS
			}
			else {
				isAttrType = true; // IDREF
			}
		}
		else if (sp.skippedString(entit_string)) {
			if (sp.lookingAtChar('Y', true)) {
				isAttrType = true; // ENTITY
			}
			else if (sp.skippedString(ies_string)) {
				isAttrType = true; // ENTITITES
			}
		}
		else if (sp.skippedString(nmtoken_string)) {
			if (sp.lookingAtChar('S', true)) {
				isAttrType = true; // NMTOKENS
			}
			else {
				isAttrType = true; // NMTOKEN
			}
		}
		else if (sp.skippedString(notation_string)) {
			if (!sp.lookingAtChar('(', true)) {
				// System.out.println(" missing ( in notation ");
			}
			Vector enumList = scanEnumeration(sp, true);
			if (enumList == null || enumList.size() == 0)
				isAttrType = false;
			else
				isAttrType = true;
		}
		else if (sp.lookingAtChar('(', true)) {
			// "ENUMERATION";
			Vector enumList = scanEnumeration(sp, false);
			if (enumList == null || enumList.size() == 0)
				isAttrType = false;
			else
				isAttrType = true;
		}

		return isAttrType;

	}

	/*
	 * return 0 - not default type 1 - #REQUIRED or #IMPLIED 2 - #FIXED
	 */

	private int isAttrDefaultType(StringParser sp) {
		// System.out.println("isAttrDefaultType - sp:" + sp.fData);
		int result = 0;
		if (sp.skippedString(required_string)) {
			result = 1;
		}
		else if (sp.skippedString(implied_string)) {
			result = 1;
		}
		else if (sp.skippedString(fixed_string)) {
			result = 2;
		}
		return result;
	}

	//
	// [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
	// [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
	//
	// Called after scanning '('
	//
	private Vector scanEnumeration(StringParser sp, boolean isNotationType) {
		// System.out.println(" scanEnum ...");
		Vector enumList = null;
		int len;

		if (sp.lookingAtSpace(true))
			sp.skipPastSpaces();

		int prevNodeOffset = sp.getCurrentOffset();
		int nodeOffset;

		String nodeName;

		while (true) {

			if (isNotationType)
				sp.skipPastNameAndPEReference(')');
			else
				sp.skipPastNmtokenAndPEReference(')');

			nodeOffset = sp.getCurrentOffset();

			if (nodeOffset == -1) {
				return enumList;
			}

			len = nodeOffset - prevNodeOffset;
			nodeName = sp.getString(prevNodeOffset, len);

			if (enumList == null)
				enumList = new Vector();

			enumList.addElement(nodeName);

			if (sp.lookingAtSpace(true))
				sp.skipPastSpaces();

			if (!sp.lookingAtChar('|', true)) {
				if (!sp.lookingAtChar(')', true)) {
					System.out.println("scanning enum values - error missing ')'");
					break;
				}
				break;
			}

			if (sp.lookingAtSpace(true))
				sp.skipPastSpaces();

			prevNodeOffset = sp.getCurrentOffset();
		}
		return enumList;
	}

	//
	// [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
	// | "'" ([^<&'] | Reference)* "'"
	//
	/**
	 * Scan the default value in an attribute declaration
	 * 
	 * @param elementType
	 *            handle to the element that owns the attribute
	 * @param attrName
	 *            handle in the string pool for the attribute name
	 * @return handle in the string pool for the default attribute value
	 * @exception java.lang.Exception
	 */
	public String scanDefaultAttValue(StringParser sp) {
		String value = null;
		// System.out.println("scan default ATT Value... sp:" + sp.fData);

		sp.skipPastSpaces();

		boolean single;
		if (!(single = sp.lookingAtChar('\'', true)) && !sp.lookingAtChar('\"', true)) {
			return value;
		}

		char qchar = single ? '\'' : '\"';
		int sOffset = sp.getCurrentOffset();
		sp.skipToChar(qchar, true);
		int len = sp.getCurrentOffset() - sOffset - 1;
		if (len == 0)
			value = "";
		else
			value = sp.getString(sOffset, len);

		return value;
	}

	void printAttList(Vector attrs) {
		Enumeration en = attrs.elements();
		while (en.hasMoreElements()) {
			AttNode an = (AttNode) en.nextElement();
			// System.out.println("attNode: " + an);
		}

	}

	//
	// [70] EntityDecl ::= GEDecl | PEDecl
	// [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
	// [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
	// [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
	// [74] PEDef ::= EntityValue | ExternalID
	// [75] ExternalID ::= 'SYSTEM' S SystemLiteral
	// | 'PUBLIC' S PubidLiteral S SystemLiteral
	// [76] NDataDecl ::= S 'NDATA' S Name
	// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
	// | "'" ([^%&'] | PEReference | Reference)* "'"
	//
	// Called after scanning 'ENTITY'
	//
	public EntityDecl scanEntityDecl() {
		prevNodeOffset = 1;
		nodeOffset = 1;
		int len;
		boolean isPEDecl = false;
		EntityDecl entityDecl = null;

		String name = null;
		String ndata = null;

		if (contentString.lookingAtSpace(true)) {
			contentString.skipPastSpaces();
			if (!contentString.lookingAtChar('%', true)) {
				isPEDecl = false; // <!ENTITY x "x">
			}
			else if (contentString.lookingAtSpace(true)) {
				isPEDecl = true; // <!ENTITY % x "x">
			}
			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipPastName(' ');
			nodeOffset = contentString.getCurrentOffset();
			len = nodeOffset - prevNodeOffset;
			if (len > 0) {
				name = contentString.getString(prevNodeOffset, len);
				prevNodeOffset = nodeOffset;
			}
		}

		if (name == null)
			return null;

		contentString.skipPastSpaces();
		prevNodeOffset = contentString.getCurrentOffset();

		boolean single;
		if ((single = contentString.lookingAtChar('\'', true)) || contentString.lookingAtChar('\"', true)) {
			String value = scanEntityValue(single);
			entityDecl = new EntityDecl(name, ownerDTD, value, isPEDecl);
		}
		else {
			// external entity
			ExternalID xID = scanExternalID();
			if (xID != null) {
				if (!isPEDecl) // general entity
				{
					boolean unparsed = false;
					contentString.skipPastSpaces();
					unparsed = contentString.skippedString(ndata_string);
					if (unparsed) {
						contentString.skipPastSpaces();
						prevNodeOffset = contentString.getCurrentOffset();
						contentString.skipPastName(' ');
						nodeOffset = contentString.getCurrentOffset();
						len = nodeOffset - prevNodeOffset;
						ndata = contentString.getString(prevNodeOffset, len);
					}
				}
				entityDecl = new EntityDecl(name, ownerDTD, xID, isPEDecl, ndata);
			}
		}
		return entityDecl;
	}


	//
	// [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S?
	// '>'
	// [75] ExternalID ::= 'SYSTEM' S SystemLiteral
	// | 'PUBLIC' S PubidLiteral S SystemLiteral
	// [83] PublicID ::= 'PUBLIC' S PubidLiteral
	//
	// Called after scanning 'NOTATION'
	//
	public NotationDecl scanNotationDecl() {
		prevNodeOffset = 1;
		nodeOffset = 1;
		int len;
		boolean isPEDecl = false;
		NotationDecl notationDecl = null;

		String name = null;

		if (contentString.lookingAtSpace(true)) {
			contentString.skipPastSpaces();
			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipPastName(' ');
			nodeOffset = contentString.getCurrentOffset();
			len = nodeOffset - prevNodeOffset;
			if (len > 0) {
				name = contentString.getString(prevNodeOffset, len);
				prevNodeOffset = nodeOffset;
			}
		}

		if (name == null)
			return null;

		contentString.skipPastSpaces();
		prevNodeOffset = contentString.getCurrentOffset();

		notationDecl = new NotationDecl(name, ownerDTD);

		ExternalID xID = scanExternalID();
		if (xID != null) {
			if (xID.getSystemLiteral() != null) {
				notationDecl.setSystemId(xID.getSystemLiteral());
			}
			if (xID.getPubIdLiteral() != null) {
				notationDecl.setPublicId(xID.getPubIdLiteral());
			}
		}

		return notationDecl;
	}


	private String scanEntityValue(boolean single) {
		char qchar = single ? '\'' : '\"';
		prevNodeOffset = contentString.getCurrentOffset();
		contentString.skipToChar(qchar, false);
		int len = contentString.getCurrentOffset() - prevNodeOffset;
		String value = contentString.getString(prevNodeOffset, len);
		return value;
	}

	//
	// [75] ExternalID ::= 'SYSTEM' S SystemLiteral
	// | 'PUBLIC' S PubidLiteral S SystemLiteral
	private ExternalID scanExternalID() {
		ExternalID xID = null;
		char qchar = '\"';
		if (contentString.skippedString(system_string)) {
			if (!contentString.lookingAtSpace(true)) {
				return null;
			}
			contentString.skipPastSpaces();

			if (contentString.lookingAtChar('\'', true))
				qchar = '\'';
			else if (contentString.lookingAtChar('\"', true))
				qchar = '\"';

			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipToChar(qchar, true);
			int len = contentString.getCurrentOffset() - prevNodeOffset - 1;
			String systemId = contentString.getString(prevNodeOffset, len);
			// System.out.println("systemid..." + systemId);
			xID = new ExternalID(systemId);
		}
		else if (contentString.skippedString(public_string)) {
			if (!contentString.lookingAtSpace(true)) {
				return null;
			}

			contentString.skipPastSpaces();
			if (contentString.lookingAtChar('\'', true))
				qchar = '\'';
			else if (contentString.lookingAtChar('\"', true))
				qchar = '\"';

			// publicLiteral
			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipToChar(qchar, true);
			int len = contentString.getCurrentOffset() - prevNodeOffset - 1;
			String publicId = contentString.getString(prevNodeOffset, len);

			// systemLiteral
			contentString.skipPastSpaces();
			if (contentString.lookingAtChar('\'', true))
				qchar = '\'';
			else if (contentString.lookingAtChar('\"', true))
				qchar = '\"';
			prevNodeOffset = contentString.getCurrentOffset();
			contentString.skipToChar(qchar, true);
			len = contentString.getCurrentOffset() - prevNodeOffset - 1;

			if (len > 0) {
				String systemId = contentString.getString(prevNodeOffset, len);
				xID = new ExternalID(publicId, systemId);
			}
			else {
				xID = new ExternalID(publicId, null);
			}
		}
		return xID;
	}

	//
	// [83] PublicID ::= 'PUBLIC' S PubidLiteral
	//

	// dmw 11/15 private method never read locally
	// TODO: change to private if used, otherwise should be removed
	String scanPublicID() {
		String pID = null;
		if (contentString.skippedString(public_string)) {
			if (!contentString.lookingAtSpace(true)) {
				return pID;
			}
			contentString.skipPastSpaces();
			prevNodeOffset = contentString.getCurrentOffset();

			contentString.skipToChar(' ', true);
			int len = contentString.getCurrentOffset() - prevNodeOffset;
			pID = contentString.getString(prevNodeOffset, len);
		}

		return pID;
	}

	//
	// Main
	//

	/** Main program entry point. */
	public static void main(String argv[]) {

		// is there anything to do?
		if (argv.length == 0) {
			System.exit(1);
		}

		// DTDScanner sc = new DTDScanner(argv[0]);
		DTDScanner sc = new DTDScanner("hello.dtd", " gif SYSTEM \"GIF File\" ");

		NotationDecl n = sc.scanNotationDecl();
		System.out.println("Noation Name: " + n.getNodeName());
		System.out.println("SystemId: " + n.getSystemId());


		// Attributes
		// Vector lists = sc.scanAttlistDecl();
		// sc.printAttList(lists);

		// System.out.println("CM: " + sc.scanContentModel());

	} // main(String[])

	/**
	 * Gets the errorString
	 * 
	 * @return Returns a String
	 */
	public String getErrorString() {
		return errorString;
	}

	/**
	 * Sets the errorString
	 * 
	 * @param errorString
	 *            The errorString to set
	 */
	public void setErrorString(String errorString) {
		this.errorString = errorString;
	}

}
