/*******************************************************************************
 * 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.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); //$NON-NLS-1$
		}
		else if (contentString.skippedString(any_string)) {
			cmNode = new CMBasicNode("ANY", CMNodeType.ANY); //$NON-NLS-1$
		}
		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)); //$NON-NLS-1$

		// 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("%")) //$NON-NLS-1$
				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("%")) { //$NON-NLS-1$
				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"; //$NON-NLS-1$
					}
					else {
						attNode.type = "IDREFS"; //$NON-NLS-1$
					}
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(entit_string)) {
					if (contentString.lookingAtChar('Y', true)) {
						attNode.type = "ENTITY"; //$NON-NLS-1$
					}
					else if (contentString.skippedString(ies_string)) {
						attNode.type = "ENTITIES"; //$NON-NLS-1$
					}
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.skippedString(nmtoken_string)) {
					if (contentString.lookingAtChar('S', true)) {
						attNode.type = "NMTOKENS"; //$NON-NLS-1$
					}
					else {
						attNode.type = "NMTOKEN"; //$NON-NLS-1$
					}
					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 "); //$NON-NLS-1$
					}
					attNode.type = "NOTATION"; //$NON-NLS-1$
					attNode.enumList = scanEnumeration(contentString, true);
					scannerState = Att_Scanner_State_DefaultType;
				}
				else if (contentString.lookingAtChar('(', true)) {
					attNode.type = "ENUMERATION"; //$NON-NLS-1$
					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."); //$NON-NLS-1$ //$NON-NLS-2$
						// 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"; //$NON-NLS-1$

					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(";")) { //$NON-NLS-1$ //$NON-NLS-2$
				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; //$NON-NLS-1$
				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"); //$NON-NLS-1$

			}

			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 ')'"); //$NON-NLS-1$
					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 = ""; //$NON-NLS-1$
		else
			value = sp.getString(sOffset, len);

		return value;
	}

	//
	// [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;
		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\" "); //$NON-NLS-1$ //$NON-NLS-2$

		NotationDecl n = sc.scanNotationDecl();
		System.out.println("Noation Name: " + n.getNodeName()); //$NON-NLS-1$
		System.out.println("SystemId: " + n.getSystemId()); //$NON-NLS-1$


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

}
