/*******************************************************************************
 * 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); //$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;
	}

	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\" "); //$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;
	}

}
