/*****************************************************************************
 * 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.ui.internal.contentassist;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.css.core.internal.metamodel.CSSMetaModel;
import org.eclipse.wst.css.core.internal.metamodel.util.CSSMetaModelFinder;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
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.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

class CSSContentAssistContext {

	private int fReplaceBegin = -1;
	private String fTextToReplace = null;
	private String fTextToCompare = null;
	private int fTargetPos = -1;
	private ICSSNode fTargetNode = null;
	private int fCursorPos = -1;
	private IStructuredDocument fStructuredDocument = null;
	private int fDocumentOffset = 0;
	private char fQuote = 0;
	private ICSSModel fModel = null;

	/**
	 *  
	 */
	private CSSContentAssistContext() {
		super();
	}

	/**
	 *  
	 */
	CSSContentAssistContext(int documentPosition, ICSSNode node, int documentOffset, char quote) {
		super();
		fCursorPos = documentPosition;
		fDocumentOffset = documentOffset;
		fQuote = quote;
		initialize(node.getOwnerDocument());
	}

	/**
	 * @return int
	 */
	int getCursorPos() {
		return fCursorPos;
	}

	/**
	 * @return int
	 */
	int getDocumentOffset() {
		return fDocumentOffset;
	}

	IStructuredDocument getStructuredDocument() {
		return fStructuredDocument;
	}

	ICSSModel getModel() {
		return fModel;
	}

	private ICSSNode getNodeAt(int offset) {
		return (ICSSNode) ((fModel != null) ? fModel.getIndexedRegion(offset) : null);
	}

	/**
	 * 
	 * @return char
	 */
	char getQuoteOfStyleAttribute() {
		return fQuote;
	}

	ITextRegion getRegionByOffset(int offset) {
		ITextRegion region = null;
		if (fStructuredDocument != null) {
			IStructuredDocumentRegion flatNode = fStructuredDocument.getRegionAtCharacterOffset(offset);
			if (flatNode != null) {
				region = flatNode.getRegionAtCharacterOffset(offset);
			}
		}
		return region;
	}

	/**
	 *  
	 */
	//	String getRegionText() {
	//		ITextRegion targetRegion = getTargetRegion();
	//		if (targetRegion != null) {
	//			return targetRegion.getText();
	//		} else {
	//			return ""; //$NON-NLS-1$
	//		}
	//	}
	/**
	 *  
	 */
	int getReplaceBegin() {
		return fReplaceBegin;
	}

	ICSSNode getTargetNode() {
		return fTargetNode;
	}

	private int getTargetPos() {
		return fTargetPos;
	}

	ITextRegion getTargetRegion() {
		return getRegionByOffset(getTargetPos());
	}

	private IStructuredDocumentRegion getTargetDocumentRegion() {
		return getDocumentRegionByOffset(getTargetPos());
	}

	private IStructuredDocumentRegion getDocumentRegionByOffset(int offset) {
		return (fStructuredDocument != null) ? fStructuredDocument.getRegionAtCharacterOffset(offset) : null;
	}

	ITextRegion getTargetRegionPrevious() {
		ITextRegion previousRegion = null;
		ITextRegion targetRegion = getTargetRegion();
		RegionIterator iterator = null;
		if (targetRegion == null) {
			if (0 < fCursorPos) {
				iterator = new RegionIterator(fStructuredDocument, fCursorPos - 1);
			}
		} else {
			iterator = getRegionIterator();
			if (iterator.hasPrev()) {
				iterator.prev();
			} else {
				iterator = null;
			}
		}
		if (iterator != null) {
			while (iterator.hasPrev()) {
				ITextRegion region = iterator.prev();
				String type = region.getType();
				if (type != CSSRegionContexts.CSS_S && type != CSSRegionContexts.CSS_COMMENT && type != CSSRegionContexts.CSS_CDO && type != CSSRegionContexts.CSS_CDC) {
					previousRegion = region;
					break;
				}
			}
		}

		return previousRegion;
	}

	/**
	 * @return java.lang.String
	 */
	String getTextToCompare() {
		return fTextToCompare;
	}

	/**
	 *  
	 */
	String getTextToReplace() {
		return fTextToReplace;
	}

	/**
	 *  
	 */
	private void initialize(ICSSDocument doc) {
		if (doc == null) {
			return;
		}
		ICSSModel model = doc.getModel();
		fModel = model;
		fStructuredDocument = model.getStructuredDocument();

		initializeTargetPos();
		initializeTargetText();
		initializeTargetNode();
	}

	/**
	 *  
	 */
	private void initializeTargetNode() {
		if (fCursorPos == 0) {
			fTargetNode = fModel.getDocument();
			return;
		}

		// find edge of tree node
		ICSSNode cursorNode = getNodeAt(fCursorPos);
		if (cursorNode == null) { // end of document
			cursorNode = fModel.getDocument();
		}
		ICSSNode node = null;
		IStructuredDocumentRegion flatNode = fStructuredDocument.getRegionAtCharacterOffset(fCursorPos - 1);
		while (flatNode != null && (node = getNodeAt(flatNode.getStartOffset())) == cursorNode && ((IndexedRegion) node).getStartOffset() != flatNode.getStartOffset()) {
			flatNode = flatNode.getPrevious();
		}
		if (flatNode == null) { // top of document
			fTargetNode = (node == null) ? fModel.getDocument() : node;
			return;
		}
		//   v<--|
		//   AAAAAA
		// BBBBBBBBBB cursorNode:A , node:B -> target is A
		if (cursorNode != null) {
			for (ICSSNode parent = cursorNode.getParentNode(); parent != null; parent = parent.getParentNode()) {
				if (parent == cursorNode) {
					fTargetNode = cursorNode;
					return;
				}
			}
		}
		//     v<--|
		//   AAA
		// BBBBBBBBBB cursorNode:B , node:A -> depend on A's node type
		short nodeType = node.getNodeType();
		if (nodeType == ICSSNode.STYLEDECLITEM_NODE || nodeType == ICSSNode.CHARSETRULE_NODE || nodeType == ICSSNode.IMPORTRULE_NODE) {
			String type = CSSUtil.getStructuredDocumentRegionType(flatNode);
			if (type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
				fTargetNode = node.getParentNode();
			} else {
				fTargetNode = node;
			}
			//			fTargetNode = (bOverSemiColon) ? node.getParentNode() : node;
		} else if (CSSUtil.getStructuredDocumentRegionType(flatNode) == CSSRegionContexts.CSS_RBRACE) {
			fTargetNode = node.getParentNode();
		} else {
			fTargetNode = node;
		}

		return;
	}

	/**
	 *  
	 */
	private void initializeTargetPos() {
		if (fCursorPos == 0 || isSpecialDelimiterRegion(fCursorPos - 1)) {
			fTargetPos = fCursorPos;
		} else {
			fTargetPos = fCursorPos - 1;
		}
	}

	/**
	 *  
	 */
	private void initializeTargetText() {
		ITextRegion targetRegion = getTargetRegion();
		IStructuredDocumentRegion documentRegion = getTargetDocumentRegion();
		if (targetRegion == null) {
			fReplaceBegin = fCursorPos;
			fTextToReplace = ""; //$NON-NLS-1$
			fTextToCompare = ""; //$NON-NLS-1$
		} else {
			String regionText = documentRegion.getText(targetRegion);
			int regionStart = documentRegion.getStartOffset(targetRegion);
			if (regionStart == fCursorPos || regionText.trim().length() == 0 || regionStart + regionText.length() - 1 < fTargetPos) {
				// to insertion
				fReplaceBegin = fCursorPos;
				fTextToReplace = ""; //$NON-NLS-1$
				fTextToCompare = ""; //$NON-NLS-1$
			} else {
				// to replace
				fReplaceBegin = regionStart;
				fTextToReplace = regionText;
				fTextToCompare = regionText.substring(0, fCursorPos - fReplaceBegin);
			}
		}
	}

	/**
	 *  
	 */
	private boolean isSpecialDelimiterRegion(int pos) {
		ITextRegion region = getRegionByOffset(pos);
		String type = region.getType();
		return (type == CSSRegionContexts.CSS_LBRACE || type == CSSRegionContexts.CSS_RBRACE || type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_SEPARATOR || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR);
	}

	/**
	 *  
	 */
	boolean isTargetPosAfterOf(String regionType) {
		int start = ((IndexedRegion) fTargetNode).getStartOffset();
		if (start < 0 || ((IndexedRegion) fTargetNode).getEndOffset() <= 0) {
			return false;
		}

		RegionIterator iRegion = new RegionIterator(fStructuredDocument, start);
		while (iRegion.hasNext()) {
			ITextRegion region = iRegion.next();
			if (fTargetPos < iRegion.getStructuredDocumentRegion().getTextEndOffset(region)) {
				break;
			}
			if (region.getType() == regionType) {
				return true;
			}
		}

		return false;
	}

	/**
	 *  
	 */
	boolean isTargetPosBeforeOf(String regionType) {
		return !isTargetPosAfterOf(regionType);
	}

	/**
	 * @return boolean
	 * @param regionType
	 *            java.lang.String
	 */
	boolean targetFollows(String regionType) {
		RegionIterator iRegion;
		ITextRegion region = null;
		if (fStructuredDocument.getLength() <= fTargetPos) {
			iRegion = new RegionIterator(fStructuredDocument, fStructuredDocument.getLength() - 1);
		} else {
			iRegion = new RegionIterator(fStructuredDocument, fTargetPos);
			try {
				if (!Character.isWhitespace(fStructuredDocument.getChar(fTargetPos)) && iRegion.hasPrev()) {
					region = iRegion.prev();
				}
			} catch (BadLocationException e) {
				iRegion = new RegionIterator(fStructuredDocument, fStructuredDocument.getLength() - 1);
			}
		}
		while (iRegion.hasPrev()) {
			region = iRegion.prev();
			String type = region.getType();
			if (type == CSSRegionContexts.CSS_S || type == CSSRegionContexts.CSS_COMMENT) {
				continue;
			} else {
				break;
			}
		}
		if (region != null && region.getType() == regionType) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 *  
	 */
	boolean targetHas(String regionType) {
		int start = ((IndexedRegion) fTargetNode).getStartOffset();
		int end = ((IndexedRegion) fTargetNode).getEndOffset();
		if (start < 0 || end <= 0) {
			return false;
		}
		RegionIterator iRegion = new RegionIterator(fStructuredDocument, start);
		while (iRegion.hasNext()) {
			ITextRegion region = iRegion.next();
			if (end <= iRegion.getStructuredDocumentRegion().getStartOffset(region)) {
				break;
			}
			if (region.getType() == regionType) {
				return true;
			}
		}
		return false;
	}

	RegionIterator getRegionIterator() {
		return new RegionIterator(getStructuredDocument(), getTargetPos());
	}

	/**
	 *  
	 */
	CSSMetaModel getMetaModel() {
		CSSMetaModelFinder finder = CSSMetaModelFinder.getInstance();
		return finder.findMetaModelFor(getModel());
	}
}