/*******************************************************************************
 * Copyright (c) 2004, 2005 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.text;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.wst.css.core.internal.Logger;
import org.eclipse.wst.css.core.internal.parser.CSSRegionUtil;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
import org.eclipse.wst.css.core.internal.util.CSSUtil;
import org.eclipse.wst.css.core.internal.util.RegionIterator;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredTextReParser;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.text.StructuredDocumentReParser;


/**
 * This class provides a centralized place to put "reparsing" logic. This is
 * the logic that reparses the text incrementally, as a user types in new
 * characters, or DOM nodes are inserted or deleted. Note: it is not a thread
 * safe class.
 */
public class CSSStructuredDocumentReParser extends StructuredDocumentReParser {

	class ReparseRange {
		ReparseRange() {
			reset();
		}

		ReparseRange(int start, int end) {
			fRangeStart = start;
			fRangeEnd = end;
		}

		void setStart(int start) {
			fRangeStart = start;
		}

		void setEnd(int end) {
			fRangeEnd = end;
		}

		int getStart() {
			return fRangeStart;
		}

		int getEnd() {
			return fRangeEnd;
		}

		boolean isValid() {
			return (0 < fRangeEnd - fRangeStart) ? true : false;
		}

		void reset() {
			fRangeStart = Integer.MAX_VALUE;
			fRangeEnd = 0;
		}

		void expand(ReparseRange range) {
			if (range == null || !range.isValid()) {
				return;
			}
			int start = range.getStart();
			if (start < fRangeStart) {
				fRangeStart = start;
			}
			int end = range.getEnd();
			if (fRangeEnd < end) {
				fRangeEnd = end;
			}
		}

		private int fRangeStart;
		private int fRangeEnd;
	}

	/**
	 * 
	 */
	public CSSStructuredDocumentReParser() {
		super();
	}

	/**
	 * 
	 */
	// public StructuredDocumentEvent
	// checkForCrossStructuredDocumentRegionBoundryCases2() {
	// StructuredDocumentEvent result = specialPositionUpdate(fStart, fStart +
	// fLengthToReplace - 1);
	// if (result == null) {
	// result = checkInsideBrace();
	// }
	// return result;
	// }
	protected StructuredDocumentEvent checkForCrossStructuredDocumentRegionSyntax() {
		int checkStart = fStart;
		int checkEnd = fStart + fLengthToReplace - 1;
		IStructuredDocumentRegion endRegion = fStructuredDocument.getRegionAtCharacterOffset(checkEnd);
		if (endRegion != null) {
			checkEnd = endRegion.getEndOffset();
		}

		ReparseRange range = new ReparseRange(checkStart, checkEnd);

		range.expand(getUpdateRangeForDelimiter(range.getStart(), range.getEnd()));
		range.expand(getUpdateRangeForUnknownRegion(range.getStart(), range.getEnd()));

		range.expand(getUpdateRangeForQuotes(range.getStart(), range.getEnd()));
		range.expand(getUpdateRangeForComments(range.getStart(), range.getEnd()));
		range.expand(getUpdateRangeForBraces(range.getStart(), range.getEnd()));

		StructuredDocumentEvent result;

		result = checkInsideBrace(range.getStart(), range.getEnd());

		if (result == null) {
			result = reparse(range.getStart(), range.getEnd());
		}

		return result;
	}

	private ReparseRange getUpdateRangeForUnknownRegion(int start, int end) {
		int newStart = start;
		RegionIterator iterator = new RegionIterator(fStructuredDocument, start - 1);
		if (iterator.hasPrev()) {
			iterator.prev(); // skip myself
		}
		while (iterator.hasPrev()) {
			ITextRegion region = iterator.prev();
			if (region != null && region.getType() == CSSRegionContexts.CSS_UNKNOWN) {
				newStart = iterator.getStructuredDocumentRegion().getStartOffset(region);
			}
			else {
				break;
			}
		}

		if (start != newStart) {
			return new ReparseRange(newStart, end);
		}

		return null;
	}

	private ReparseRange getUpdateRangeForDelimiter(int start, int end) {
		if (dirtyStart != null && dirtyStart.getStart() < start) {
			start = dirtyStart.getStart();
		}
		IStructuredDocumentRegion docRegion = fStructuredDocument.getRegionAtCharacterOffset(start);
		if (docRegion == null) {
			return null;
		}
		if (docRegion.getType() == CSSRegionContexts.CSS_DELIMITER) {
			IStructuredDocumentRegion prevRegion = docRegion.getPrevious();
			if (prevRegion != null) {
				return new ReparseRange(prevRegion.getStart(), end);
			}
		}

		return null;
	}

	private ReparseRange getUpdateRangeForQuotes(int start, int end) {
		ReparseRange range = new ReparseRange();

		range.expand(getUpdateRangeForPair(start, end, "\"", "\"")); //$NON-NLS-2$//$NON-NLS-1$
		range.expand(getUpdateRangeForPair(start, end, "\'", "\'")); //$NON-NLS-2$//$NON-NLS-1$

		return (range.isValid()) ? range : null;
	}

	private ReparseRange getUpdateRangeForComments(int start, int end) {
		ReparseRange range = new ReparseRange();

		range.expand(getUpdateRangeForPair(start, end, "/*", "*/")); //$NON-NLS-2$//$NON-NLS-1$
		range.expand(getUpdateRangeForPair(start, end, "<%", "%>")); //$NON-NLS-2$//$NON-NLS-1$

		return (range.isValid()) ? range : null;
	}

	private ReparseRange getUpdateRangeForBraces(int start, int end) {
		ReparseRange range = new ReparseRange();

		range.expand(getUpdateRangeForPair(start, end, "[", "]")); //$NON-NLS-2$//$NON-NLS-1$
		range.expand(getUpdateRangeForPair(start, end, "(", ")")); //$NON-NLS-2$//$NON-NLS-1$
		range.expand(getUpdateRangeForPair(start, end, "{", "}")); //$NON-NLS-2$//$NON-NLS-1$

		return (range.isValid()) ? range : null;
	}

	private StructuredDocumentEvent checkInsideBrace(int start, int end) {
		StructuredDocumentEvent result = null;
		IStructuredDocumentRegion region = fStructuredDocument.getRegionAtCharacterOffset(start);
		if (region == null) {
			return null;
		}
		boolean bDeclaration = false;
		String type = region.getType();
		if (CSSRegionUtil.isDeclarationType(type) || type == CSSRegionContexts.CSS_LBRACE || type == CSSRegionContexts.CSS_RBRACE) {
			bDeclaration = true;
		}
		if (!bDeclaration) {
			IStructuredDocumentRegion prevRegion = CSSUtil.findPreviousSignificantNode(region);
			if (prevRegion != null) {
				type = prevRegion.getType();
				if (CSSRegionUtil.isDeclarationType(type) || type == CSSRegionContexts.CSS_LBRACE) {
					bDeclaration = true;
				}
			}
		}
		if (!bDeclaration) {
			IStructuredDocumentRegion nextRegion = CSSUtil.findNextSignificantNode(region);
			if (nextRegion != null) {
				type = nextRegion.getType();
				if (CSSRegionUtil.isDeclarationType(type) || type == CSSRegionContexts.CSS_RBRACE) {
					bDeclaration = true;
				}
			}
		}

		if (bDeclaration) {
			IStructuredDocumentRegion startRegion = findRuleStart(region);
			if (startRegion != null) {
				IStructuredDocumentRegion endRegion = fStructuredDocument.getRegionAtCharacterOffset(end);
				if (endRegion != null) {
					result = reparse(startRegion, endRegion);
				}
			}
		}
		return result;
	}

	private IStructuredDocumentRegion findRuleStart(IStructuredDocumentRegion startRegion) {
		IStructuredDocumentRegion region = startRegion;
		// find '{'
		while (region != null && region.getType() != CSSRegionContexts.CSS_LBRACE) {
			region = region.getPrevious();
		}
		// if (region == startRegion) {
		// return null;
		// }
		// else
		if (region != null) { // '{' is found
			region = region.getPrevious();
			if (isLeadingDeclarationType(region.getType())) {
				return region;
			}
		}
		return null;
	}

	private boolean isLeadingDeclarationType(String type) {
		return (type == CSSRegionContexts.CSS_PAGE || type == CSSRegionContexts.CSS_FONT_FACE || CSSRegionUtil.isSelectorType(type));
	}

	// public StructuredDocumentEvent
	// checkForCrossStructuredDocumentRegionBoundryCases() {
	// return specialPositionUpdate(fStart, fStart + fLengthToReplace - 1);
	// }
	/**
	 * 
	 */
	private ReparseRange getUpdateRangeForPair(int start, int end, String opener, String closer) {
		StringBuffer deletionBuf = new StringBuffer();
		StringBuffer insertionBuf = new StringBuffer();
		int quoteLen = Math.max(opener.length(), closer.length());
		if (1 < quoteLen) {
			/**
			 * ex) opener = "ABC", closer = "XYZ" model: ABCDEF.......UVWXYZ
			 * deletion: CDEF.......UVWX pre/post: AB / YZ
			 */
			int addStart = start - (quoteLen - 1);
			if (0 <= addStart) {
				String addStr = fStructuredDocument.get(addStart, quoteLen - 1);
				deletionBuf.append(addStr);
				insertionBuf.append(addStr);
			}
			deletionBuf.append(fDeletedText);
			insertionBuf.append(fChanges);
			if (end + (quoteLen - 1) < fStructuredDocument.getLength()) {
				String addStr = fStructuredDocument.get(end + 1, quoteLen - 1);
				deletionBuf.append(addStr);
				insertionBuf.append(addStr);
			}
		}
		else {
			deletionBuf.append(fDeletedText);
			insertionBuf.append(fChanges);
		}
		String deletion = deletionBuf.toString();
		String insertion = insertionBuf.toString();

		int rangeStart = start;
		int rangeEnd = end;

		if (0 <= deletion.indexOf(opener) || 0 <= deletion.indexOf(closer) || 0 <= insertion.indexOf(opener) || 0 <= insertion.indexOf(closer)) {
			int s, e;
			try {
				if (start <= fStructuredDocument.getLength()) {
					IRegion startRegion = getFindReplaceDocumentAdapter().find(start - 1, opener, false, false, false, false);
					if (startRegion != null) {
						s = startRegion.getOffset();
					}
					else {
						s = -1;
					}
				}
				else {
					s = -1;
				}
				if (end < fStructuredDocument.getLength() - 1) {
					IRegion endRegion = getFindReplaceDocumentAdapter().find(end + 1, closer, true, false, false, false);
					if (endRegion != null) {
						e = endRegion.getOffset();
					}
					else {
						e = -1;
					}
				}
				else {
					e = -1;
				}
			}
			catch (BadLocationException ex) {
				Logger.logException(ex);
				return null;
			}
			if (0 <= s) {
				rangeStart = Math.min(rangeStart, s);
			}
			if (0 <= e) {
				rangeEnd = Math.max(rangeEnd, e);
			}
		}

		if (rangeStart < start || end < rangeEnd) {
			return new ReparseRange(rangeStart, rangeEnd);
		}
		else {
			return null;
		}
	}

	public IStructuredTextReParser newInstance() {
		return new CSSStructuredDocumentReParser();
	}
}
