/*******************************************************************************
 * Copyright (c) 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.css.core.internal.parser;

import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.wst.css.core.internal.Logger;
import org.eclipse.wst.css.core.parser.CSSRegionContexts;
import org.eclipse.wst.sse.core.parser.RegionParser;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.sse.core.util.Debug;


public class CSSSourceParser implements RegionParser {
	public static final int MODE_STYLESHEET = 0;
	public static final int MODE_DECLARATION = 1;
	public static final int MODE_DECLARATION_VALUE = 2;

	private long fStartTime;
	private long fStopTime;
	private CSSTokenizer fTokenizer;

	public void setParserMode(int mode) {
		int initialState;
		int bufsize;
		switch (mode) {
			case MODE_STYLESHEET :
				initialState = CSSTokenizer.YYINITIAL;
				bufsize = CSSTokenizer.BUFFER_SIZE_NORMAL;
				break;
			case MODE_DECLARATION :
				initialState = CSSTokenizer.ST_DECLARATION;
				bufsize = CSSTokenizer.BUFFER_SIZE_NORMAL;
				break;
			case MODE_DECLARATION_VALUE :
				initialState = CSSTokenizer.ST_DECLARATION_PRE_VALUE;
				bufsize = CSSTokenizer.BUFFER_SIZE_SMALL;
				break;
			default :
				return;
		}
		if (0 < initialState) {
			CSSTokenizer tokenizer = getTokenizer();
			tokenizer.setInitialState(initialState);
			tokenizer.setInitialBufferSize(bufsize);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#getNodes()
	 */
	public IStructuredDocumentRegion getDocumentRegions() {
		IStructuredDocumentRegion headnode = null;
		if (headnode == null) {
			if (Debug.perfTest) {
				fStartTime = System.currentTimeMillis();
			}
			headnode = parseNodes();
			if (Debug.perfTest) {
				fStopTime = System.currentTimeMillis();
				System.out.println(" -- creating nodes of IStructuredDocument -- "); //$NON-NLS-1$
				System.out.println(" Time parse and init all regions: " + (fStopTime - fStartTime) + " (msecs)"); //$NON-NLS-2$//$NON-NLS-1$
				// System.out.println(" for " + fRegions.size() + "
				// Regions");//$NON-NLS-2$//$NON-NLS-1$
				System.out.println("      and " + _countNodes(headnode) + " Nodes"); //$NON-NLS-2$//$NON-NLS-1$
			}
		}
		return headnode;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#getRegions()
	 */
	public List getRegions() {
		IStructuredDocumentRegion headNode = null;
		if (!getTokenizer().isEOF()) {
			headNode = getDocumentRegions();
			// throw new IllegalStateException("parsing has not finished");
		}
		// for memory recovery, we assume if someone
		// requests all regions, we can reset our big
		// memory consuming objects
		// but the new "getRegions" method is then more expensive.
		// I don't think its used much, though.
		List localRegionsList = getRegions(headNode);
		primReset();
		return localRegionsList;
	}

	/**
	 * Method getRegions.
	 * 
	 * @param headNode
	 * @return List
	 */
	protected List getRegions(IStructuredDocumentRegion headNode) {
		List allRegions = new ArrayList();
		IStructuredDocumentRegion currentNode = headNode;
		while (currentNode != null) {
			ITextRegionList nodeRegions = currentNode.getRegions();
			for (int i = 0; i < nodeRegions.size(); i++) {
				allRegions.add(nodeRegions.get(i));
			}
			currentNode = currentNode.getNext();
		}
		return allRegions;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#reset(java.io.Reader)
	 */
	public void reset(Reader reader) {
		primReset();
		getTokenizer().reset(reader, 0);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#reset(java.io.Reader, int)
	 */
	public void reset(Reader reader, int offset) {
		reset(reader);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#reset(java.lang.String)
	 */
	public void reset(String input) {
		reset(new StringReader(input));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#reset(java.lang.String, int)
	 */
	public void reset(String input, int offset) {
		reset(input);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.parser.RegionParser#newInstance()
	 */
	public RegionParser newInstance() {
		return new CSSSourceParser();
	}

	private IStructuredDocumentRegion parseNodes() {
		// regions are initially reported as complete offsets within the
		// scanned input
		// they are adjusted here to be indexes from the currentNode's start
		// offset
		IStructuredDocumentRegion headNode = null;
		IStructuredDocumentRegion lastNode = null;
		ITextRegion region = null;
		IStructuredDocumentRegion currentNode = null;
		String type = null;
		String currentRegionType = null;

		while ((region = getNextRegion()) != null) {
			type = region.getType();
			if (mustBeStart(type, currentRegionType) && currentNode != null) {
				currentNode.setEnded(true);
			}

			if ((currentNode != null && currentNode.isEnded()) || currentNode == null) {
				if (currentNode != null && !currentNode.isEnded()) {
					currentNode.setEnded(true);
				}
				lastNode = currentNode;
				currentNode = createStructuredDocumentRegion(type);
				currentRegionType = type;
				if (lastNode != null) {
					lastNode.setNext(currentNode);
				}
				currentNode.setPrevious(lastNode);
				currentNode.setStart(region.getStart());
			}

			currentNode.addRegion(region);
			currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
			region.adjustStart(-currentNode.getStart());

			if (mustBeEnd(type)) {
				currentNode.setEnded(true);
			}

			if (headNode == null && currentNode != null) {
				headNode = currentNode;
			}
		}

		if (currentNode != null && !currentNode.isEnded()) {
			currentNode.setEnded(true);
		}

		primReset();
		return headNode;
	}

	private IStructuredDocumentRegion createStructuredDocumentRegion(String type) {
		return CSSStructuredDocumentRegionFactory.createRegion(type);
	}

	private boolean mustBeStart(String type, String docRegionType) {
		return ((type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_LBRACE || type == CSSRegionContexts.CSS_RBRACE || type == CSSRegionContexts.CSS_IMPORT || type == CSSRegionContexts.CSS_PAGE || type == CSSRegionContexts.CSS_MEDIA || type == CSSRegionContexts.CSS_FONT_FACE || type == CSSRegionContexts.CSS_CHARSET || type == CSSRegionContexts.CSS_ATKEYWORD || type == CSSRegionContexts.CSS_DECLARATION_PROPERTY || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER) || (docRegionType == CSSRegionContexts.CSS_DECLARATION_PROPERTY && type == CSSRegionContexts.CSS_S) || (!CSSRegionUtil.isSelectorBegginingType(docRegionType) && (type == CSSRegionContexts.CSS_SELECTOR_ELEMENT_NAME || type == CSSRegionContexts.CSS_SELECTOR_UNIVERSAL || type == CSSRegionContexts.CSS_SELECTOR_PSEUDO || type == CSSRegionContexts.CSS_SELECTOR_CLASS || type == CSSRegionContexts.CSS_SELECTOR_ID || type == CSSRegionContexts.CSS_SELECTOR_ATTRIBUTE_START)));
	}

	private boolean mustBeEnd(String type) {
		return (type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_LBRACE || type == CSSRegionContexts.CSS_RBRACE || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER);
	}

	private ITextRegion getNextRegion() {
		ITextRegion region = null;
		try {
			region = getTokenizer().getNextToken();
			// DMW: 2/12/03 Removed state
			// if (region != null) {
			// fRegions.add(region);
			// }
			return region;
		}
		catch (StackOverflowError e) {
			Logger.logException(getClass().getName() + ": input could not be parsed correctly at position " + getTokenizer().getOffset(), e); //$NON-NLS-1$
			throw e;
		}
		catch (Exception e) {
			Logger.logException(getClass().getName() + ": input could not be parsed correctly at position " + getTokenizer().getOffset() + " (" + e.getLocalizedMessage() + ")", e); //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
		}
		return null;
	}

	private void primReset() {

		getTokenizer().reset(new char[0]);
	}

	private CSSTokenizer getTokenizer() {
		if (fTokenizer == null) {
			fTokenizer = new CSSTokenizer();
		}
		return fTokenizer;
	}


	/**
	 * This is a simple utility to count nodes. Used only for debug
	 * statements.
	 */
	private int _countNodes(IStructuredDocumentRegion nodes) {
		int result = 0;
		IStructuredDocumentRegion countNode = nodes;
		while (countNode != null) {
			result++;
			countNode = countNode.getNext();
		}
		return result;
	}

}