/*******************************************************************************
 * Copyright (c) 2004, 2007 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());
	}
}
