/*******************************************************************************
 * 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.dtd.core.parser;

import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.wst.dtd.core.internal.text.DTDStructuredDocumentRegionFactory;
import org.eclipse.wst.dtd.core.tokenizer.DTDTokenizer;
import org.eclipse.wst.dtd.core.tokenizer.Token;
import org.eclipse.wst.sse.core.parser.RegionParser;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;


public class DTDRegionParser implements RegionParser {
	private Vector cachedRegions = null;
	private DTDTokenizer tokenizer = null;
	private IStructuredDocumentRegion cachedNode = null; // top of node chain

	public RegionParser newInstance() {
		return new DTDRegionParser();
	}

	private IStructuredDocumentRegion addNewNodes(IStructuredDocumentRegion lastNode, Vector regions) {
		IStructuredDocumentRegion leadingSpaceNode = null;
		IStructuredDocumentRegion contentNode = null;
		IStructuredDocumentRegion trailingSpaceNode = null;
		LinkedList nodeSeeds = new LinkedList();
		int nRegions = regions.size();
		int leadingSpaceEnd = -1;
		int trailingSpaceBegin = nRegions;

		// find leading space
		nodeSeeds.clear();
		for (int i = 0; i < nRegions; i++) {
			ITextRegion region = (ITextRegion) regions.get(i);
			String type = region.getType();
			if (isBlankRegion(type)) {
				leadingSpaceEnd = i;
				nodeSeeds.addLast(region);
			} else {
				break;
			}
		}
		if (!nodeSeeds.isEmpty()) {
			leadingSpaceNode = createNode(nodeSeeds);
			if (lastNode != null) {
				lastNode.setNext(leadingSpaceNode);
				leadingSpaceNode.setPrevious(lastNode);
			}
			lastNode = leadingSpaceNode;
		}

		// find trailing space
		if (leadingSpaceEnd < nRegions - 1) {
			nodeSeeds.clear();
			for (int i = nRegions - 1; 0 <= i; i--) {
				ITextRegion region = (ITextRegion) regions.get(i);
				String type = ((ITextRegion) regions.get(i)).getType();
				if (isBlankRegion(type)) {
					trailingSpaceBegin = i;
					nodeSeeds.addFirst(region);
				} else {
					break;
				}
			}
			if (!nodeSeeds.isEmpty()) {
				trailingSpaceNode = createNode(nodeSeeds);
			}

			nodeSeeds.clear();
			for (int i = leadingSpaceEnd + 1; i < trailingSpaceBegin; i++) {
				nodeSeeds.addLast(regions.get(i));
			}
			if (!nodeSeeds.isEmpty()) {
				contentNode = createNode(nodeSeeds);
				if (lastNode != null) {
					lastNode.setNext(contentNode);
					contentNode.setPrevious(lastNode);
				}
				lastNode = contentNode;
			}
			if (trailingSpaceNode != null) {
				lastNode.setNext(trailingSpaceNode);
				trailingSpaceNode.setPrevious(lastNode);
				lastNode = trailingSpaceNode;
			}
		}

		return lastNode;
	}

	private IStructuredDocumentRegion createNode(LinkedList regions) {
		if (regions.size() == 0) {
			return null;
		}

		IStructuredDocumentRegion node = DTDStructuredDocumentRegionFactory.createStructuredDocumentRegion(DTDStructuredDocumentRegionFactory.DTD_GENERIC);
		int start = ((ITextRegion) regions.getFirst()).getStart();
		int length = ((ITextRegion) regions.getLast()).getEnd() - start;
		node.setStart(start);
		node.setLength(length);
		for (ListIterator i = regions.listIterator(0); i.hasNext();) {
			ITextRegion region = (ITextRegion) i.next();
			node.addRegion(region);
			region.adjustStart(-start);
		}
		node.setEnded(true);

		return node;
	}

	private IStructuredDocumentRegion createNodeChain(List regions) {
		IStructuredDocumentRegion headNode = null;
		IStructuredDocumentRegion lastNode = null;
		Vector nodeSeeds = new Vector();

		for (Iterator e = regions.iterator(); e.hasNext();) {
			ITextRegion region = (ITextRegion) e.next();
			String type = region.getType();
			// If the following regions appear,
			// a previous node is closed in front of it.
			if (!nodeSeeds.isEmpty() && isBeginningRegion(type)) {
				lastNode = addNewNodes(lastNode, nodeSeeds);
				nodeSeeds.clear();
			}
			nodeSeeds.addElement(region);

			// The following regions close the current node.
			if (!nodeSeeds.isEmpty() && isEndingRegion(type)) {
				lastNode = addNewNodes(lastNode, nodeSeeds);
				nodeSeeds.clear();
			}

			if (headNode == null && lastNode != null) {
				headNode = findFirstNode(lastNode);
			}
		}

		// close current node forcibly.
		if (!nodeSeeds.isEmpty()) {
			lastNode = addNewNodes(lastNode, nodeSeeds);
			if (headNode == null && lastNode != null) {
				headNode = findFirstNode(lastNode);
			}
		}
		return headNode;
	}

	private IStructuredDocumentRegion findFirstNode(IStructuredDocumentRegion node) {
		IStructuredDocumentRegion firstNode = node;
		IStructuredDocumentRegion prevNode = null;
		while ((prevNode = firstNode.getPrevious()) != null) {
			firstNode = prevNode;
		}
		return firstNode;
	}

	public IStructuredDocumentRegion getDocumentRegions() {
		if (cachedNode != null) {
			return cachedNode;
		}

		List regions = getRegions();
		IStructuredDocumentRegion headNode = createNodeChain(regions);
		cachedNode = headNode;

		return headNode;
	}

	public List getRegions() {
		if (cachedRegions != null) {
			return cachedRegions;
		}

		Vector regions = new Vector();
		Token currentToken = null;
		do {
			try {
				currentToken = (Token) tokenizer.yylex();
				if (currentToken != null) {
					ITextRegion region = DTDRegionFactory.createRegion(currentToken.getType(), currentToken.getStartOffset(), currentToken.getLength());
					regions.add(region);
				}
			} catch (java.io.FileNotFoundException e) {
				System.out.println("File not found"); //$NON-NLS-1$
			} catch (java.io.IOException e) {
				System.out.println("Error opening file"); //$NON-NLS-1$
			}
		} while (currentToken != null);

		cachedRegions = regions;
		return regions;
	}

	public void reset(Reader reader) {
		if (tokenizer == null) {
			try {
				tokenizer = new DTDTokenizer(reader);
			} catch (ArrayIndexOutOfBoundsException e) {
				System.out.println("Usage : java DTDTokenizer <inputfile>"); //$NON-NLS-1$
			}
		} else {
			try {
				tokenizer.yyreset(reader);
			} catch (java.io.IOException e) {
				System.out.println("Error opening file"); //$NON-NLS-1$
			}
		}

		cachedNode = null;
		cachedRegions = null;
	}

	/**
	 * An additional offset for use with any position-dependant parsing rules
	 */
	public void reset(Reader reader, int offset) {
		reset(reader);
	}

	public void reset(String input) {
		reset(new StringReader(input));
	}

	public void reset(String input, int offset) {
		reset(input);
	}

	// never used
	 DTDTokenizer getTokenizer() {
		return tokenizer;
	}

	private boolean isBeginningRegion(String type) {
		return (type == DTDRegionTypes.START_TAG) || (type == DTDRegionTypes.ENTITY_PARM);
	}

	private boolean isBlankRegion(String type) {
		return (type == DTDRegionTypes.WHITESPACE);
	}

	private boolean isEndingRegion(String type) {
		return (type == DTDRegionTypes.END_TAG) || (type == DTDRegionTypes.ENTITY_PARM) || (type == DTDRegionTypes.COMMENT_END);
	}
}
