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

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

	/**
	 * @return com.ibm.sed.structuredDocument.IStructuredDocument
	 */
	IStructuredDocument getStructuredDocument() {
		return fStructuredDocument;
	}

	/**
	 * @return com.ibm.sse.model.css.model.ICSSModel
	 */
	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;
	}

	/**
	 * 
	 * @return com.ibm.sed.structuredDocument.ITextRegion
	 */
	//	ITextRegion getSignificantTargetRegion() {
	//		ITextRegion targetRegion = getTargetRegion();
	//		RegionIterator iterator = null;
	//		if (targetRegion == null) {
	//			if (0 < fCursorPos) {
	//				iterator = new RegionIterator(fStructuredDocument, fCursorPos - 1);
	//			}
	//		} else {
	//			iterator = getRegionIterator();
	//		}
	//		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)
	// {
	//					targetRegion = region;
	//					break;
	//				}
	//			}
	//		}
	//
	//		return targetRegion;
	//	}
	/**
	 *  
	 */
	ICSSNode getTargetNode() {
		return fTargetNode;
	}

	/**
	 *  
	 */
	private int getTargetPos() {
		return fTargetPos;
	}

	/**
	 * @return com.ibm.sed.structuredDocument.ITextRegion
	 */
	ITextRegion getTargetRegion() {
		return getRegionByOffset(getTargetPos());
	}

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

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

	/**
	 * 
	 * @return com.ibm.sed.structuredDocument.ITextRegion
	 */
	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());
	}
}