package org.eclipse.cdt.internal.ui.text;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import java.io.IOException;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.ICharacterPairMatcher;

/**
 * Helper class for match pairs of characters.
 */
public class CPairMatcher implements ICharacterPairMatcher {

	protected char[] fPairs;
	protected IDocument fDocument;
	protected int fOffset;

	protected int fStartPos;
	protected int fEndPos;
	protected int fAnchor;

	protected CCodeReader fReader = new CCodeReader();

	public CPairMatcher(char[] pairs) {
		fPairs = pairs;
	}

	public IRegion match(IDocument document, int offset) {

		fOffset = offset;

		if (fOffset < 0)
			return null;

		fDocument = document;

		if (matchPairsAt() && fStartPos != fEndPos)
			return new Region(fStartPos, fEndPos - fStartPos + 1);

		return null;
	}

	public int getAnchor() {
		return fAnchor;
	}

	/*
		 * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear()
		 */
	public void clear() {
		if (fReader != null) {
			try {
				fReader.close();
			} catch (IOException x) {
				// ignore
			}
		}
	}

	public void dispose() {
		clear();
		fDocument = null;
		fReader = null;
	}
	protected boolean matchPairsAt() {

		int i;
		int pairIndex1= fPairs.length;
		int pairIndex2= fPairs.length;

		fStartPos= -1;
		fEndPos= -1;

		// get the chars preceding and following the start position
		try {

			char prevChar= fDocument.getChar(Math.max(fOffset - 1, 0));
// modified behavior for http://dev.eclipse.org/bugs/show_bug.cgi?id=16879			
//			char nextChar= fDocument.getChar(fOffset);

			// search for opening peer character next to the activation point
			for (i= 0; i < fPairs.length; i= i + 2) {
//				if (nextChar == fPairs[i]) {
//					fStartPos= fOffset;
//					pairIndex1= i;
//				} else 
				if (prevChar == fPairs[i]) {
					fStartPos= fOffset - 1;
					pairIndex1= i;
				}
			}
			
			// search for closing peer character next to the activation point
			for (i= 1; i < fPairs.length; i= i + 2) {
				if (prevChar == fPairs[i]) {
					fEndPos= fOffset - 1;
					pairIndex2= i;
				} 
//				else if (nextChar == fPairs[i]) {
//					fEndPos= fOffset;
//					pairIndex2= i;
//				}
			}

			if (fEndPos > -1) {
				fAnchor= RIGHT;
				fStartPos= searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
				if (fStartPos > -1)
					return true;
				else
					fEndPos= -1;
			}	else if (fStartPos > -1) {
				fAnchor= LEFT;
				fEndPos= searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument);
				if (fEndPos > -1)
					return true;
				else
					fStartPos= -1;
			}

		} catch (BadLocationException x) {
		} catch (IOException x) {
		}

		return false;
	}
	


//	protected boolean matchPairsAt() {
//
//		int i;
//		int pairIndex1 = fPairs.length;
//		int pairIndex2 = fPairs.length;
//
//		fStartPos = -1;
//		fEndPos = -1;
//
//		// get the chars preceding and following the start position
//		try {
//
//			/*
//			 A quick hack to get around the fact that we can't bracket
//			 match on the very first element of a document.  We make the
//			 character to match a null character which is unlikely to match.
//			*/
//			char prevChar = (fOffset > 0) ? fDocument.getChar(fOffset - 1) : '\0';
//			char nextChar = fDocument.getChar(fOffset);
//
//			// search for opening peer character next to the activation point
//			for (i = 0; i < fPairs.length; i = i + 2) {
//				if (nextChar == fPairs[i]) {
//					fStartPos = fOffset;
//					pairIndex1 = i;
//				} else if (prevChar == fPairs[i]) {
//					fStartPos = fOffset - 1;
//					pairIndex1 = i;
//				}
//			}
//
//			// search for closing peer character next to the activation point
//			for (i = 1; i < fPairs.length; i = i + 2) {
//				if (prevChar == fPairs[i]) {
//					fEndPos = fOffset - 1;
//					pairIndex2 = i;
//				} else if (nextChar == fPairs[i]) {
//					fEndPos = fOffset;
//					pairIndex2 = i;
//				}
//			}
//
//			if (fEndPos > -1) {
//				fAnchor = RIGHT;
//				fStartPos = searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
//				if (fStartPos > -1)
//					return true;
//				else
//					fEndPos = -1;
//			} else if (fStartPos > -1) {
//				fAnchor = LEFT;
//				fEndPos = searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument);
//				if (fEndPos > -1)
//					return true;
//				else
//					fStartPos = -1;
//			}
//
//		} catch (BadLocationException x) {
//		} catch (IOException x) {
//		}
//
//		return false;
//	}

	protected int searchForClosingPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {

		fReader.configureForwardReader(document, offset + 1, document.getLength(), true, true);

		int stack = 1;
		int c = fReader.read();
		while (c != CCodeReader.EOF) {
			if (c == openingPeer && c != closingPeer)
				stack++;
			else if (c == closingPeer)
				stack--;

			if (stack == 0)
				return fReader.getOffset();

			c = fReader.read();
		}

		return -1;
	}

	protected int searchForOpeningPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {

		fReader.configureBackwardReader(document, offset, true, true);

		int stack = 1;
		int c = fReader.read();
		while (c != CCodeReader.EOF) {
			if (c == closingPeer && c != openingPeer)
				stack++;
			else if (c == openingPeer)
				stack--;

			if (stack == 0)
				return fReader.getOffset();

			c = fReader.read();
		}

		return -1;
	}
}