/*****************************************************************************
 * 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) {
		this();
		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());
	}
}